浏览器按<source>出现顺序依次尝试,遇第一个能解码且HTTP 200的即停止;必须显式声明精确type,兼容性排序应为mp4(H.264)→webm(VP9)→mp4(AV1),iOS Safari强制首源为H.264 MP4。

HTML <source> 标签的格式优先级怎么定
浏览器按 <source> 出现顺序依次尝试,遇到第一个能解码+播放成功的就停,后面全跳过。不是“选最优”,而是“选第一个可用”。
常见错误:把 webm 放最前,但用户用 Safari(不支持 webm),结果直接 fallback 到 <video> 的 src 或黑屏——因为没配 type,浏览器连试都不试。
- 必须为每个
<source>显式写type,比如type="video/mp4"、type="video/webm; codecs="vp9"" -
type值要精确:Safari 16+ 才支持av1,写type="video/mp4; codecs="av1""在旧版 Safari 会被忽略 - 顺序按兼容性降序排:
mp4(H.264)放最前保底,webm(VP9)次之,mp4(AV1)放最后
为什么加了 <source> 还是只加载第一个
不是 bug,是规范行为。只要第一个 <source> 的 type 被浏览器识别且资源 HTTP 状态为 200,就不会继续往下请求其他 <source>。
典型场景:你用 curl -I 检查发现 mp4 返回 200,但实际文件损坏或编码不合法(如无关键帧),浏览器可能静默失败并 fallback 到下一个——但多数情况它会卡在 loading 状态,看起来像“只加载第一个”。
立即学习“前端免费学习笔记(深入)”;
- 用浏览器 DevTools 的 Network 面板确认:只看到一个视频请求?那说明前一个
<source>被接受了 - 检查响应头是否有
Content-Type匹配你写的type属性,不匹配等于没写type - 不要依赖文件后缀判断格式,
xxx.mp4文件实际可能是 AV1 编码,type="video/mp4"仍会失败
<source> 的 media 属性真能按屏幕尺寸切视频吗
不能。media 只控制是否“参与候选”,不触发下载或切换。它类似 CSS 媒体查询,仅决定这个 <source> 当前是否被考虑——但最终播哪个,还是看顺序 + type + 可解码性。
比如你写 <source media="(min-width: 768px)" type="video/mp4">,在手机上这个 <source> 直接被忽略,不请求、不解析;但桌面端它变成候选,仍要按位置顺序参与竞争。
-
media不是懒加载开关,也不影响带宽自适应 - 真正做分辨率适配得靠 JavaScript +
MediaSource或 HLS/DASH,<source>本身无此能力 - 误用
media还可能导致小屏设备 fallback 到低质量mp4,因为高分辨率<source>被 media 规则过滤掉了
移动端 iOS Safari 对 <source> 的硬限制
iOS Safari(包括所有 WebKit 内核 WebView)强制要求:第一个可播放的 <source> 必须是 H.264 编码的 MP4,否则静音、不自动播放、甚至报 NotAllowedError。
这不是 bug,是 Apple 的策略:为省电和解码一致性,绕过所有协商逻辑,直奔最稳路径。哪怕你写了 webm 在前,它也无视 type,直接跳到第一个 mp4。
- 测试时务必用真机,模拟器不反映真实限制
- 避免在
<video>上设autoplay+muted以外的属性,iOS 会拒绝播放 - 如果必须用 VP9/AV1,只能放弃
<source>,改用 JS 动态src赋值,并监听canplay后再play()
最麻烦的点往往不在语法,而在不同浏览器对“可播放”的定义差异——iOS 认为不可播的,Chrome 可能播得飞起。别信文档,每个 <source> 都得真机跑一遍。











