必须写controls属性(仅controls或controls=""),且用<source>按MP3→OGG→WAV/OPUS顺序提供多格式并声明准确type;autoplay需配合muted,且iOS需用户首次触摸后才生效。

直接上 <audio> 标签加一个 src,在 Chrome 里能响,不代表在 Safari 或 Firefox 里能播——浏览器对音频的解码能力、自动播放策略、MIME 类型校验,全都不一样。
必须写 controls,且不能写成 controls="false"
不写 controls,页面上就看不到任何播放控件,用户无法手动触发播放;写了但写成 controls="false",浏览器会把它当真值处理,依然显示控件。正确写法只有两种:controls(推荐)或 controls=""。
- 移动端 iOS Safari 对控件渲染更敏感,缺
controls时即使 JS 调用play()成功,用户也无从感知状态 - 某些 Android WebView 会忽略空字符串
controls="",只认无值写法 - 若要用自定义 UI,仍建议保留
controls属性并用 CSS 隐藏,避免部分旧版 Safari 因缺失该属性拒绝初始化音频上下文
<source> 多格式顺序不能乱:MP3 → OGG → WAV/OPUS
浏览器按 DOM 顺序逐个尝试 <source>,遇到第一个 canPlayType() 返回非 "" 的就停。所以要把兼容性最广的放最前:
-
<source src="a.mp3" type="audio/mpeg">:所有现代浏览器都支持,但 Safari 对 VBR 编码 MP3 偶有解码失败 -
<source src="a.ogg" type="audio/ogg">:Firefox/Chrome 稳定,Safari 完全跳过(不报错也不加载) -
<source src="a.wav" type="audio/wav">:Safari/iOS 兜底效果好,但文件体积大,仅适合短提示音 -
<source src="a.opus" type="audio/opus">:Chrome/Firefox 支持,体积比 MP3 小 30%~50%,但 Safari 不支持,必须放在 WAV 后面
别信 canPlayType() 返回 "probably" 就代表一定能播——它只是推测,实测中常有“推测能播、实际静音”情况。
立即学习“前端免费学习笔记(深入)”;
autoplay + muted 是唯一能绕过现代浏览器拦截的组合
Chrome ≥70、Firefox ≥66、Safari ≥12.1 默认禁止有声自动播放。autoplay 单独写等于白写,必须搭配 muted 才可能成功:
-
<audio autoplay muted src="a.mp3">:有效,静音状态下可自动启播 -
<audio autoplay muted="false" src="a.mp3">:无效,muted是布尔属性,“=false”不取消静音,反而让浏览器误判为需要静音 - JS 中解除静音要写
audio.muted = false,不能只改audio.volume = 1,否则 Safari 仍卡在静音态 - iOS Safari 连
muted自动播都要用户首次触摸后才生效,所以首次play()必须包在click或touchstart回调里
preload 设成 metadata 最稳妥,别信 auto
preload="auto" 在多数移动端被浏览器强制降级为 metadata,尤其在 iOS Safari 和部分 Android WebView 中根本不会预加载音频体。设成 metadata 反而更可控:
- 只下载头信息(时长、采样率),首帧延迟低,流量开销小
- 避免
preload="none"导致用户点击后等待太久,又避免preload="auto"在弱网下拉取整文件失败 - 不要在
load或canplay事件里直接调play()—— iOS 不认这种“非用户手势触发”的上下文,必须等真实点击之后再调
真正容易被忽略的是:哪怕所有格式都写了、属性都设对了,如果服务器返回的 Content-Type 是 text/plain 或空,Chrome 和 Firefox 也会静默跳过该 <source>。上线前务必用 Network 面板确认每个音频响应头里的 Content-Type 是否匹配其扩展名。



















