必须提供MP3、OPUS、WAV三种格式并按此顺序声明,且均需显式指定type属性、正确编码及服务器MIME类型,否则Safari等浏览器将静音或报错。

没有一种音频格式能通吃所有浏览器,必须提供至少两种 <source></source> 并按特定顺序声明,否则 Safari(尤其 iOS)和部分企业内网环境大概率静音或报错。
MP3 不是万能解,但仍是必选项
MP3(audio/mpeg)兼容性最广,Chrome、Firefox、Edge、Safari 全支持,但它在 Safari 上对 VBR 编码偶有解码失败;在某些 Linux 发行版或严格隐私模式下的 Firefox 中,MP3 解码器可能被禁用。所以不能只靠它。
- 必须显式写
type="audio/mpeg",不能只靠文件后缀 - 服务器响应头中
Content-Type必须为audio/mpeg,否则 Safari 会跳过该源 - 避免使用 VBR 编码(可用
ffmpeg -i in.mp3 -c:a libmp3lame -q:a 2 out.mp3转为 CBR)
OPUS 比 OGG 更值得放第二位
很多资料仍推荐 MP3 + OGG 组合,但实测中 audio/opus 在 Chrome/Firefox 上体积比 MP3 小 30%~50%,解码更快,且不会像 OGG 那样被 Safari 完全忽略(Safari 对 audio/ogg 的识别极不稳定,即使 type 正确也常跳过)。
-
<source src="a.opus" type="audio/opus"></source>必须放在 MP3 之后、WAV 之前 - Opus 文件需封装在 WebM 容器中,但 type 属性仍写
audio/opus,不是audio/webm - 旧版 Safari(≤16)不支持 Opus,所以它不能放第一位,也不能替代 MP3
WAV 是兜底项,但不能乱放最后
WAV(audio/wav)虽兼容性好(所有浏览器都支持 PCM 编码的 16-bit little-endian 格式),但文件体积大、加载慢,仅适合短提示音(如 1 秒“滴”声)。把它放在最后,是为了防止前面所有源因路径错误、MIME 不匹配或编码不支持而被跳过时,还能 fallback 到一个确定能播的格式。
立即学习“前端免费学习笔记(深入)”;
- 必须用 PCM 编码,避免 float 或 big-endian —— iOS Safari 会直接拒绝解码
- 采样率优先选 44.1kHz 或 16kHz;32kHz 及非常规值在 Android WebView 中易出问题
- 别把
.wav放在.ogg前面:OGG 在 Firefox/Chrome 能播,但 Safari 会跳过它继续往下找;如果 WAV 在前,Safari 可能加载完大文件才发现不能播,浪费带宽和时间
type 属性漏写等于白配
浏览器不会根据文件后缀推断类型,canPlayType() 判断依赖 type 字符串。漏写 type,Chrome 可能碰运气试播,Safari 则直接跳过该 <source></source>,哪怕 URL 和文件完全正确。
-
<source src="a.mp3"></source>→ Safari 当作不支持,静默跳过 -
<source src="a.mp3" type="audio/mpeg"></source>→ Safari 进入 canPlayType 流程,大概率命中 - MP4 容器(.m4a)必须用
type="audio/mp4",且内部音频轨必须是 AAC 编码(用ffprobe a.m4a确认codec_name为aac)
最容易被忽略的是:多格式 fallback 不是“多写几个就稳了”,而是顺序、type、编码、服务器 MIME 四者必须咬合。任何一个环节脱节,Safari 就静音,Firefox 就报 DOMException: The element has no supported sources,而控制台里连个 warning 都没有。



















