type属性必须带codecs参数才能真正过滤解码器,仅写type="video/mp4"等同于没写,浏览器无法判断内部编码是否支持,会发起请求后才发现解码失败;真正起作用的是type="video/mp4; codecs="avc1.42e01e, mp4a.40.2""等完整声明,使浏览器在请求前完成mime类型与编解码器双层校验,不匹配的source直接被跳过。

type属性必须带codecs参数才能真正过滤解码器
只写 type="video/mp4" 等同于没写——浏览器无法据此判断是否支持内部编码,会照常发起请求,等下载完才发现解码失败,Network 面板里能看到 200,但视频黑屏无报错,error 事件也不触发(静默跳过)。
真正起作用的是带 codecs 的完整声明,它让浏览器在发起网络请求前就完成“MIME 类型 + 编解码器”双层校验。不匹配的 <source></source> 直接被跳过,连请求都不会发。
-
type="video/mp4; codecs="avc1.42E01E, mp4a.40.2":H.264 Baseline Profile + AAC-LC,iOS Safari 唯一认的起点 -
type="video/webm; codecs="vp9, opus":大小写敏感,vp09或VP9都不行;Safari 16.4+ 才开始识别 -
type="video/mp4; codecs="av01.0.05M.08":AV1 MP4,Chrome/Firefox 支持良好,Safari 16+ 起步,旧版直接忽略整条<source></source> - 别写
codecs="h264"或codecs="aac":标准写法是avc1.xxxx和mp4a.40.2,FFmpeg 输出可用ffprobe -v quiet -show_entries stream=codec_name,profile -of csv video.mp4核实
iOS Safari强制首个source必须是H.264+AAC且type精确匹配
把 <source src="vid.webm" type="video/webm"></source> 放第一位?真机上大概率白屏、静音、自动播放被禁,甚至抛 NotAllowedError。WebKit 不 fallback,它直接判定整个 <video></video> 不可用,后续所有 <source></source> 都不会加载。
必须满足三项硬性条件:
- 位置第一:
<source></source>必须是<video></video>内的第一个子元素 - 编码合规:H.264 Baseline 或 Main Profile(推荐
-profile:v baseline -level 3.0),AAC-LC 音频(-c:a aac -b:a 128k) - type逐字符一致:服务器返回的
Content-Type响应头必须和type属性值完全相同,包括空格、逗号、引号位置。例如返回video/mp4; codecs="avc1.42E01E, mp4a.40.2",但你写成type="video/mp4; codecs="avc1.42E01E,mp4a.40.2""(少空格),Safari 就当它不匹配
canPlayType()比盲写source更可靠
靠手写一堆 <source></source> 猜浏览器支持什么,不如用 JS 主动探测。浏览器对 canPlayType() 的返回值有明确定义:"probably" 表示高度可能支持,"maybe" 表示不确定,空字符串表示不支持。
示例用法:
const video = document.createElement('video');
console.log(video.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')); // "probably"
console.log(video.canPlayType('video/webm; codecs="vp9, opus"')); // Safari 16.4+ 返回 "probably",旧版返回 ""
console.log(video.canPlayType('video/mp4; codecs="av01.0.05M.08"')); // Chrome 返回 "probably",Safari
<p>注意点:</p>
- 不能只传 MIME 类型,如
canPlayType('video/webm')总是返回"maybe",无实际判断力 - 返回
"maybe"时仍可能加载失败,仅说明浏览器不反对尝试,不代表能解码成功 - 探测结果受当前设备能力影响,比如 macOS 上 Safari 对 AV1 的支持晚于 iOS
服务端Content-Type不匹配会导致source被静默跳过
哪怕 type 写得完全正确,只要服务器返回的 Content-Type 响应头不一致,浏览器(尤其是 Safari)就会直接忽略该 <source></source>,Network 面板里根本看不到请求发出。
常见翻车场景:
- .webm 文件被 Nginx 配置为
text/plain→ Safari 跳过,即使type="video/webm"正确 - 本地开发用
file://协议 → 所有type匹配逻辑失效,浏览器退化为按文件后缀瞎猜 - CDN 缓存了错误的响应头 → 某些边缘节点返回
application/octet-stream,导致全量用户 fallback 失效
验证方式:打开 DevTools → Network → 点击对应资源 → 查看 Response Headers 中的 Content-Type,必须与 type 属性值严格一致(含空格与引号)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











