html5 标签需满足格式(mp4/h.264+aac优先)、mime类型、服务器支持及尺寸可见等条件才能正常播放;controls失效多因css隐藏或尺寸塌陷;自动播放须用户手势触发且静音;状态监听应使用原生事件而非轮询。

html5 <video></video> 标签怎么写才真正能播
不是加了 <video></video> 就能播——浏览器对格式、编码、服务器响应头都有硬性要求。最常见现象是页面显示黑屏、控制栏灰掉、控制台报 MediaError {code: 4}(MEDIA_ERR_SRC_NOT_SUPPORTED)。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 视频源必须用
mp4(H.264 + AAC 编码),webm(VP9 + Opus)作为备选,不要只放avi或mov - 用
<source></source>显式声明多个格式,让浏览器自主选择:<video controls> <source src="video.mp4" type="video/mp4"> <source src="video.webm" type="video/webm"> </video> - 确保 Web 服务器返回正确的 MIME 类型:mp4 对应
video/mp4,不是application/octet-stream;本地双击打开 HTML 文件时,file://协议下部分浏览器会拒绝加载视频(需起本地服务)
为什么加了 controls 还没反应
控制栏不出现,大概率是播放器被 CSS 隐藏或尺寸塌陷了。HTML5 播放器默认宽高为 300×150 像素,如果父容器设了 overflow: hidden 或 display: flex 但没给 <video></video> 设 flex-shrink: 0,它就可能被压缩成一条线。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 先检查 computed styles,确认
<video></video>元素有可见宽高(至少width: 300px) - 移除所有影响尺寸的 CSS(比如
max-width: 100%但父容器宽度为 0)再测试 -
controls是布尔属性,写成controls="false"不生效,必须写成controls或完全不写(禁用) - 移动端 safari 要求用户手势触发播放,不能自动
play(),否则静音也不行——这是策略限制,不是 bug
play() 报错 “NotAllowedError: play() failed because the user didn’t interact with the document first”
这是现代浏览器(chrome ≥66、Safari、firefox)的强制策略:自动播放仅允许在静音状态下触发,且首次播放必须由用户点击/触摸等交互启动。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 别在
DOMContentLoaded或load事件里直接调video.play() - 把播放逻辑绑定到按钮点击上:
button.addEventListener('click', () => { video.muted = true; video.play().catch(e => console.warn('play failed:', e)); }); - 如需预加载,用
preload="metadata"(只加载头信息),避免preload="auto"在移动网络下浪费流量 - 服务端开启 http/2 和 Accept-Ranges 支持,能让拖拽和 seek 更快响应
自定义 ui 时,怎么监听播放状态变化
原生控件一关,就得自己处理播放/暂停/进度/音量等逻辑。靠轮询或定时器是错的——应该用事件监听。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 关键事件:
play、pause、timeupdate(每 200–250ms 触发一次)、loadedmetadata(元数据加载完成)、canplay(可开始播放)、ended - 不要用
setInterval去读video.currentTime,timeupdate更精准且省资源 - 拖动进度条时,先
video.pause(),再video.currentTime = x,再video.play()(如果需要继续播) - 注意
volume属性范围是 0–1,不是 0–100;移动端通常禁止 js 设置音量,只能调用系统音量键
实际接入时最容易被忽略的,是视频文件本身是否真的能在目标设备解码——哪怕格式是 mp4,H.265(HEVC)在多数 android 和旧版 ios 上依然不支持。测之前,先用 Safari 和 Chrome for Android 真机跑一遍。