浏览器按顺序匹配source:先检查type是否识别,再确认HTTP 200响应,最后验证视频帧能否解码;三者全满足即选用,后续跳过。

浏览器解析时到底按什么顺序匹配
浏览器不“权衡”格式优劣,只做线性尝试:从第一个<source>开始,逐个检查 type 是否被识别 → 资源 HTTP 状态是否为 200 → 视频帧能否真正解码。三者全满足,立刻选用,后续全部跳过。
常见误判是看到 Network 面板只发一个请求,就以为“没走 fallback”,其实只是第一个 <source> 卡在解码环节——比如 MP4 文件用了 High Profile H.264,Safari 会静默失败,但不会触发下一个请求。
- 用 DevTools 的 Media 面板确认解码器是否初始化成功,不能只看 Network
-
type值必须与服务器返回的Content-Type响应头逐字符一致,audio/mpeg写成audio/mp3就直接跳过 - 本地用
file://协议打开时,所有<source>的type匹配逻辑静默失效,必须走 HTTP(S)
为什么 iOS Safari 强制要求第一个是 H.264 MP4
iOS Safari(及所有 WebKit WebView)不是“偏好”H.264,而是硬性规则:首个可播放的 <source> 必须是 type="video/mp4" 且内部编码为 H.264(AVC1),否则可能静音、禁止自动播放,甚至抛 NotAllowedError。
这不是兼容性妥协,是平台级限制。哪怕你把 WebM 放第一位、MP4 放第二位,Safari 也不会 fallback 到第二项——它认为整个 <video> 不合法。
立即学习“前端免费学习笔记(深入)”;
- 正确顺序:
<source src="vid-h264.mp4" type="video/mp4">(必须首位) - VP9 WebM 可跟在后面:
<source src="vid-vp9.webm" type="video/webm; codecs="vp9""> - AV1 MP4 必须放最后,且仅写
type="video/mp4; codecs="av1"",旧版 Safari 直接忽略
media 属性在 <video> 中根本不起作用
media 属性在 <video> 或 <audio> 的 <source> 里,目前所有主流浏览器(Chrome/Firefox/Safari/Edge)都忽略它。写了也不报错,但不会触发任何条件判断或懒加载。
常见翻车场景:写 <source src="hd.mp4" type="video/mp4" media="(min-width: 1024px)">,结果手机端照样加载 HD 源,或者干脆黑屏——因为该 <source> 被过滤后,后面没配移动友好的 MP4,整个视频就 fallback 到兜底文字。
- 唯一可靠使用
media的上下文是<picture>,配合srcset和sizes - 想做响应式视频?必须用 JS:监听
window.matchMedia(),动态改<video>.src并调用.load() - 防抖很重要:resize 事件高频触发,建议 250ms 内只执行最后一次
.load()
type 属性写不准等于没写
type 不是可选装饰,它是浏览器跳过无效格式的唯一依据。漏写、写宽泛、写错,都会导致额外请求或白屏。
例如 type="video/mp4" 看似没问题,但如果文件实际是 AV1 编码,旧版 Safari 会加载失败;而写成 type="video/mp4; codecs="av01.0.05M.08"",就能让支持 AV1 的浏览器精准识别,不支持的则跳过。
- H.264 MP4 推荐写法:
type="video/mp4; codecs="avc1.42E01E, mp4a.40.2"" - VP9 WebM 必须带 codecs:
type="video/webm; codecs="vp9, opus"" - 别信文件后缀:一个
.mp4文件可能是 AV1,type="video/mp4"就会失效 - 用
curl -I https://xxx.mp4确认响应头Content-Type: video/mp4,否则type匹配失败
type 匹配、HTTP 返回 200、视频帧真能解码——缺一不可。Network 面板里看到请求成功,不代表就能播。



















