标签必须放在 或 内部,因为它不是独立标签,仅作为其直接子元素提供备选资源,脱离后会被浏览器完全忽略且静默失效。

为什么 <source></source> 标签必须放在 <audio></audio> 或 <video></video> 内部
<source></source> 不是独立可用的标签,它本身不渲染任何内容,只提供备选资源路径和类型提示。浏览器按顺序检查 <source></source> 元素,一旦找到能解码的格式就停止加载后续项。如果把它写在 <audio></audio> 外面,或嵌套在 <div> 里,会被完全忽略——连错误都不会报。
<p>常见错误现象:<code><source src="a.mp3"></source> 单独写在页面中,音频根本不会播放;控制台也看不到报错,只是静默失效。
- 必须作为
<audio></audio>或<video></video>的直接子元素 - 顺序很重要:把兼容性最广的格式(如 MP4/H.264 + AAC)放前面,把较新但支持有限的(如 WebM/AV1)放后面
- 每个
<source></source>必须带src和type,否则浏览器无法预判是否支持
type 属性写错会导致浏览器跳过整个 <source></source>
浏览器不会尝试去“猜”文件类型,它只信任 type 值。比如 type="audio/mpeg" 是对的,但写成 type="mp3" 或 type="audio/mp3" 就无效——后者甚至不是标准 MIME 类型。
典型错误场景:用 FFmpeg 导出一个 .webm 文件,却写 type="video/webm; codecs=vp8",而实际编码是 VP9,结果 Chrome 可能跳过它,转而加载下一个 <source></source>(如果有的话),或者直接 fallback 到 poster 或文字提示。
- 常用正确写法:
type="video/mp4; codecs="avc1.42E01E, mp4a.40.2"、type="video/webm; codecs="vp8, vorbis"、type="audio/ogg; codecs="vorbis" - 查真实编码方式:用
ffprobe file.webm看输出里的codec_name和codec_type - 省略
codecs参数虽可运行,但失去精确匹配能力,尤其在多编码共存时容易误判
用 media 属性做响应式音视频源切换
media 属性让 <source></source> 支持媒体查询,适合在不同屏幕尺寸下加载不同分辨率或码率的视频。但它只影响是否“被考虑”,不改变播放行为本身——也就是说,即使 media="(max-width: 768px)" 匹配了,浏览器仍会照常检查该 <source></source> 的 type 和可解码性。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
容易踩的坑:有人以为写了 media="(prefers-reduced-motion: reduce)" 就能自动切到静态 poster,其实不行。这个属性只决定当前 <source></source> 是否参与候选,不能替代 JavaScript 控制逻辑。
- 有效用例:为移动端提供 480p MP4,桌面端提供 1080p MP4,都用同一
<video></video>容器 -
media不支持 JS 动态修改,改了也不会触发重选;如需运行时切换,得用 JS 替换src或重新设置innerHTML - 注意优先级:
media匹配失败时,该<source></source>直接被跳过,哪怕它的type完全正确
当所有 <source></source> 都失败时,fallback 内容怎么写才可靠
很多人以为在 <video></video> 里写段文字就是 fallback,但其实只有浏览器完全不识别 <video></video> 标签(比如 IE8)才会显示内部文本。现代浏览器只要认识这个标签,哪怕所有 <source></source> 都 404 或格式不支持,也会渲染一个空白控件——此时 fallback 文字根本不会出现。
真正可靠的 fallback 要靠 JS 检测:canPlayType() 返回空字符串,或 onerror 触发后手动插入提示。
- 纯 HTML fallback 仅适用于极端老旧环境,不要依赖它处理格式不支持问题
- 服务端返回 404 的
src不会触发<video></video>的onerror,要监听<source></source>的onerror(但兼容性差),更稳妥的是用fetch()预检资源状态 - 如果所有源都不可用,建议用 JS 显示一个带下载链接的
<div>,而不是指望 HTML 内容自动浮现 实际项目里,最常被忽略的是 <code>codecs字符串的引号和空格细节,以及把<source></source>当作普通容器来用。这些地方一错,整个多格式适配就形同虚设。










