浏览器只加载第一个可解码的source,非选最优而是按顺序尝试首个成功项;若首源type匹配且http 200即停止后续请求,ios safari更强制要求首源为h.264 mp4。

必须用 <source></source> 显式声明格式,且顺序不能错——浏览器只试第一个能解码的,不是挑最好的。
为什么写了多个 <source></source> 却只加载第一个?
这不是 bug,是规范行为:只要第一个 <source></source> 的 type 被识别,且服务器返回 HTTP 200,浏览器就停止尝试后续项。它不关心你后面有没有更小、更清晰或更新的格式。
- 常见误判:用
curl -I看到 MP4 返回 200 就以为没问题;但实际文件可能缺关键帧、profile 不对(比如 iOS Safari 拒绝 High Profile H.264),导致静默失败、界面卡在 loading 状态 - 检查 DevTools Network 面板:如果只看到一个视频请求,说明第一个已被接受;若没请求后续项,重点查第一个响应头里的
Content-Type是否匹配你写的type - 别信文件后缀:
clip.mp4可能是 AV1 编码,type="video/mp4"会失效,得写type="video/mp4; codecs="av01.0.05M.08""(注意 Safari 16+ 才支持)
type 值怎么写才真正起作用?
type 不是可选项,写错等于没写。浏览器靠它跳过不支持的格式,避免无效请求和 404。
-
video/mp4; codecs="avc1.42e01e, mp4a.40.2":H.264 Baseline + AAC-LC,iOS Safari 和几乎所有设备都认 -
video/webm; codecs="vp9, opus":Chrome/Firefox/Edge 原生支持,Safari 16.4+ 开始支持 VP9 -
video/mp4; codecs="av01.0.05M.08":AV1 编码 MP4,仅现代 Chrome/Firefox 支持,旧版 Safari 直接忽略该<source></source> - 绝对不要写
type="video/mp4"这种宽泛值——它无法帮浏览器提前过滤,可能触发额外请求,甚至让 Safari 误判为不可播
iOS Safari 对第一个 <source></source> 有硬限制
iOS Safari(包括所有 WebKit WebView)强制要求:第一个可播放的 <source></source> 必须是 H.264 编码的 MP4,否则可能静音、禁止自动播放,甚至抛 NotAllowedError。
- 哪怕你把 WebM 放第一位、MP4 放第二位,Safari 也会跳过 WebM(不支持),但因第一个候选失效,可能拒绝播放整个
<video></video> - 解决方案:MP4(H.264)必须排第一;WebM 次之;AV1 或其他新格式放最后,仅作现代浏览器锦上添花
- 别用
media属性试图“隐藏”首源——它只控制是否参与候选,不改变顺序逻辑,反而可能导致小屏设备失效
最容易被忽略的是:type 声明和实际编码必须完全一致,且服务器返回的 Content-Type 响应头也得匹配。三者差一点,iOS 就可能黑屏,而控制台不报错。










