应使用<source>多格式回退而非单src,因单src绕过浏览器格式协商导致黑屏或MEDIA_ERR_SRC_NOT_SUPPORTED;推荐H.264 MP4+VP9 WebM组合,autoplay必须muted且配合playsinline,poster需验证路径与加载状态。

直接用 <video src="xxx.mp4"> 或 <audio src="xxx.mp3"> 埋点,90% 的兼容性问题和加载失败都出在这里——不是写法错,而是绕过了浏览器的格式协商与错误兜底机制。
为什么单 src 的 <video> 经常黑屏或报 MEDIA_ERR_SRC_NOT_SUPPORTED
根本原因是浏览器在遇到单 src 时,只尝试加载一个文件,一旦该文件编码不被支持(比如 H.265/HEVC 在 iOS Safari 上直接拒解码)、服务端返回了错误的 Content-Type(如 text/plain 而非 video/mp4),就会静默失败,控制台只报模糊的 MEDIA_ERR_SRC_NOT_SUPPORTED。
- 本地双击打开 HTML(
file://协议)时,Chrome / Edge 会直接拒绝加载媒体,必须起 HTTP 服务(如python3 -m http.server) -
.mov、.avi、.mkv等格式现代浏览器基本不认,仅靠 MP4 也不够:iOS 不吃 H.265,Chrome 对 VP9 支持更好,但 WebM 文件体积又大 - 错误示例:
<video src="demo.mov" controls></video>—— 看似能写,实则大概率白屏
必须用 <source> 多格式回退,且顺序有讲究
浏览器按 <source> 出现顺序依次尝试,直到找到第一个能解码的。所以要把兼容性最广、解码开销最低的格式放前面。
- 推荐组合:
<source src="vid.mp4" type="video/mp4">(H.264 + AAC,全平台稳) +<source src="vid.webm" type="video/webm">(VP9 + Opus,Chrome/Firefox 更省带宽) - MP4 必须用 H.264 编码,不能只看后缀;可用
ffprobe vid.mp4检查:Stream #0:0: Video: h264 (High) - WebM 不是“补充”,是必要兜底:某些安卓 WebView 对 MP4 的 H.265 fallback 完全不触发,但能播 VP9
- 不要加
.ogg或.ogv:Firefox 已弃用 Theora,现代项目无实际价值
autoplay + muted 是唯一可靠自动播放路径
Chrome、Safari、Edge 全部强制要求:无用户手势(click/touchstart/scroll)前提下,有声 autoplay 必被拦截,调用 play() 会 reject Promise 并抛 DOMException: play() failed because the user didn't interact with the document first。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
<video autoplay muted playsinline preload="metadata"><source src="bg.mp4"></video> -
muted是硬门槛,缺一不可;playsinline防 iOS 强制全屏,否则视频一播就跳离页面流 - 若必须有声,只能等首次交互后 JS 调用:
button.addEventListener('click', () => video.play().catch(e => console.warn(e))) - 别信
preload="auto":移动端 Safari 直接忽略,Android WebView 表现不一,首帧延迟反而更高
poster 图片失效的三个隐藏原因
poster 不是 CSS 背景图,它是一张独立资源,行为更接近 <img>,失效往往悄无声息。
- 路径 404:控制台不报错,只留白;建议用绝对路径或检查 Network 面板确认 status 200
- iOS Safari 下,若视频本身加载失败(比如 MP4 返回 404 或编码不支持),
poster可能闪一下就消失——得监听error事件手动 fallback 到<img> - 尺寸不匹配不会自适应缩放:如果
poster是 1280×720,但<video width="640" height="360">,它会按原始比例裁剪显示,边缘被切掉
真正难的不是写对标签,而是让每个 <source> 都可验证、每个 poster 都可命中、每次 autoplay 都有 fallback 路径——这些细节堆起来,才是用户感知到的“流畅”。



















