video 的 media 属性无效,仅 picture 的 source 支持;浏览器按 type、Content-Type、首帧解码能力顺序匹配 source;type 字符串须与 ffprobe 输出及服务器响应头严格一致,否则 iOS 等可能静音或报错。

video里的写media属性根本没用
它不会触发任何条件加载,Chrome、Firefox、Safari、Edge 全部忽略。这不是兼容性问题,是 HTML 标准明确规定的:media 属性只对 <picture> 中的 <source> 生效,对 <video> 或 <audio> 内的 <source> 完全无效。
真正起作用的是type + 顺序 + 实际解码能力
浏览器只做三件事:依次检查每个 <source> 的 type 是否被支持、HTTP 响应头 Content-Type 是否与 type 逐字符一致、能否成功解码首帧。一旦某一项失败,就跳过,继续下一个;一旦成功,立刻加载并停止后续尝试。
-
type="video/mp4; codecs="avc1.42E01E, mp4a.40.2""必须和ffprobe输出完全一致——空格、逗号、引号错一个,iOS Safari 就静音 - 首个
<source>必须是 H.264 Baseline + AAC-LC 编码的 MP4,否则 iOS 可能报NotAllowedError或直接不播放 - 不能把
<source>和<video src="">混用,两者互斥;<source>必须是<video>的直接子元素 - 本地用
file://协议测试时,type匹配常失效,行为不可靠,务必用本地 HTTP 服务(如python3 -m http.server)验证
想按设备/屏幕适配?得靠 JS 或服务端
靠 HTML 原生 <source media=""> 在 <video> 里做不到。可行路径只有两个:
- 服务端根据
User-Agent或Accept请求头,返回不同顺序的<source>(比如给 iOS 返回 MP4 在前的 HTML) - 前端 JS 调用
video.canPlayType("video/mp4; codecs=...")或MediaSource.isTypeSupported(),动态插入匹配的<source>——但注意:动态插入可能绕过原生格式探测逻辑,稳定性不如静态写死 - 别依赖
srcset或sizes:它们只在<picture>里有效,<video>的<source>不支持这些属性
最容易被忽略的实操细节
不是 media 写得不准,而是 type 字符串和实际文件编码、服务器响应头、浏览器解码器之间那几处严丝合缝的对齐被漏掉了。一个 404 的 src、一个大小写错误的 MIME 类型(比如 audio/mp3 而非 audio/mpeg)、一个漏掉的 codecs 描述、甚至 FFmpeg 导出时没加 -profile:v baseline,都会让整个 fallback 链条在第一个环节就静默断裂——Network 面板只看到一次请求,控制台却无提示,播放器区域空白。



















