必须显式声明正确的type属性并配置服务器MIME类型,否则Safari等浏览器直接跳过音频源;MP3+OGG不够覆盖Safari和政企内网,需补充AAC(m4a)和WAV;autoplay需用户手势触发且静音才生效;错误捕获比事件监听更可靠。

只写 <audio src="a.mp3">,在 Safari、Firefox 或 iOS 上大概率静音或根本不动——这不是代码写错了,是浏览器根本没尝试解码。
为什么必须写type且不能省略
浏览器不靠文件后缀判断格式,而是严格比对 type 值与响应头 Content-Type。省略 type 时,Safari 直接跳过该 <source>,Firefox 可能发一次 404 再放弃。
-
type="audio/mp3"是错的,必须用type="audio/mpeg" -
type="audio/ogg"要求文件确实是 Vorbis 编码(不是 Opus),可用ffprobe a.ogg验证输出含Audio: vorbis - 服务器没配 MIME 类型,
<source>就是摆设:Nginx 需在types块加audio/mpeg mp3;,Apache 加AddType audio/mpeg .mp3 - 本地双击 HTML 文件走
file://协议,Chrome/Firefox 会直接拒绝加载音频,必须起本地服务(如python3 -m http.server)
MP3 + OGG 够不够?Safari 和企业内网怎么破
MP3 + OGG 覆盖桌面主流,但漏掉两个硬场景:Safari 对 audio/ogg 支持极不稳定;某些金融、政企内网禁用 MP3 解码器。
- Safari(尤其 iOS)更认
audio/wav(PCM 编码),短提示音用 WAV 兜底反而更稳,但别放第一位——文件大、加载慢 - OPUS(
audio/opus)在 Chrome/Firefox 已稳定支持,体积比 MP3 小 30%~50%,适合网络受限环境 - 顺序决定成败:
<source src="a.m4a" type="audio/mp4">(AAC 编码)应放最前给 Safari,再 MP3,再 OGG,WAV 放最后 - 用
ffprobe a.m4a确认codec_name=aac,否则 Safari 仍会跳过
autoplay 失效不是 bug,是浏览器在等你“动手”
写了 autoplay muted 还没声音?不是 JS 写错了,是浏览器没收到用户手势授权。iOS Safari 尤其严格:元素必须在视口内、未被 display: none 或 opacity: 0 遮挡。
立即学习“前端免费学习笔记(深入)”;
- 删掉
autoplay,改用按钮点击触发:button.addEventListener('click', () => audio.play().catch(e => {})) - 不要在
DOMContentLoaded、mounted或canplay里调play(),100% 被拒 - 静音自动播需同时满足:HTML 有
muted属性、JS 未执行audio.muted = false、audio.volume保持为 0 - 控制台报
The play() request was interrupted或NotAllowedError,就是没过手势关
监听错误比猜格式更重要
别依赖 canplay 判断是否就绪——它只表示元数据加载完,音频体可能还没到。真正能告诉你“到底能不能响”的,是错误捕获链。
- 用
audio.play().catch(e => { console.error(e.name) })捕获三类关键错误:NotAllowedError(手势缺失)、NotSupportedError(所有<source>格式均不支持)、AbortError(网络中断) - 监听
error事件:audio.addEventListener('error', () => console.log(audio.error?.code)),code === 4表示全部<source>都失败 -
networkState和readyState要一起看:networkState === 0(NETWORK_EMPTY)说明一个源都没开始加载,大概率是路径或 MIME 错了
最容易被忽略的是:所有兼容性方案都建立在“资源层正确”的前提上。路径错、MIME 错、编码错,再完美的 <source> 顺序和 JS 补丁也白搭。每次调试,先打开 Network 面板盯住那个音频请求的响应头和状态码——这是唯一真实可信的信号。



















