标签必须嵌套在或内,否则浏览器报domexception且播放器空白;它仅作为候选源列表,按dom顺序加载首个type匹配、src返回200且可解码的资源。

<source></source> 标签不能单独存在,必须嵌套在 <audio></audio> 或 <video></video> 内部,否则浏览器直接报 DOMException: The element has no supported sources,播放器区域空白——这不是警告,是硬性结构要求。
为什么必须写在
它本身不渲染、不播放,只是“候选列表”。浏览器按 DOM 顺序逐个读取 <source></source>,遇到第一个 type 被识别 + src 返回 200 + 能实际解码的,就加载并停止;其余全部跳过。脱离父标签后,这个机制彻底失效。
常见错误包括:
-
<source src="a.mp3" type="audio/mpeg"></source>直接写在顶层 → 控制台无提示,但播放器控件都不出现 - 用
<div> 包裹多个 <code><source></source>再塞进<audio></audio>→ 父子关系错乱,等同于没写 - 把
<source></source>放在<audio></audio>开始标签之后、但被<p></p>或注释隔开 → 不是直接子元素,部分 Safari 版本会忽略 - 用 DevTools Network 面板确认每个资源的
Content-Type,MP3 必须是audio/mpeg,OGG 是audio/ogg,含 Opus 编码时部分浏览器要audio/opus - 本地开发用
file://协议时,type会被完全忽略 → 必须起本地 HTTP 服务(如npx serve) - AV1 编码 MP4 要写
type="video/mp4; codecs="av01.0.05M.08"",不能只写video/mp4 - 逐个把
src值粘贴到新标签页打开,看能否下载 - Network 面板过滤
media,检查状态码是否为 200 - 相对路径以当前 HTML 文件位置为基准,不是 JS/CSS 所在目录
- 确保服务器配置了正确的 MIME 类型映射,尤其自建 Nginx/Apache 时
- 第一位:H.264 MP4(覆盖 iOS、Android、旧桌面端)
- 第二位:VP9 WebM(Chrome/Firefox/Edge)
- 第三位:AV1 MP4(仅现代 Chrome/Firefox,Safari 16.4+ 开始有限支持)
- 绝对不要把 WebM 或 AV1 放第一位,哪怕你认为它更先进
type属性必须和响应头Content-Type严格一致
浏览器不看文件后缀,只比对 type 值与服务器返回的 Content-Type 响应头。差一个字符(比如 audio/mp3 vs audio/mpeg)就可能跳过该源。
实操要点:
src路径出错时浏览器静默失败
404、跨域、权限拒绝、大小写不匹配(song.MP3 ≠ song.mp3),都不会触发控制台报错,也不会显示 fallback 文字。你只会看到空控件或 loading 状态卡住。
排查方法:
iOS Safari 对首个source有硬性限制
它强制要求第一个可解码的 <source></source> 必须是 H.264 编码的 MP4(type="video/mp4; codecs="avc1.42e01e, mp4a.40.2""),否则可能静音、禁止自动播放,甚至抛 NotAllowedError。
所以顺序不能按“画质高”排,而要按“兼容性高”排:
真正容易被忽略的是:即使写了 media="(min-width: 1024px)",iOS Safari 仍会先检查第一个无 media 的 <source></source> 是否可用——media 在音视频中只是提示,不改变“首个可用即采用”的核心逻辑。











