audio标签不响主因是未用<source>多源fallback且type错误;autoplay需muted才静音播放,有声播放须用户手势触发;本地file://协议、MIME配置错误、iOS视口外元素等均导致失败。

audio 标签不响,90% 是没写多源 fallback
只写 <audio src="a.mp3" controls></audio> 就想跨终端播放,基本等于靠浏览器掷骰子。Firefox 会跳过 MP3,iOS Safari 对 OGG 静默失败,Android WebView 可能连请求都不发。必须用 <source> 显式声明多个格式,并配对正确的 type:
-
<source src="a.mp3" type="audio/mpeg">—— 兼容性最广,放第一位 -
<source src="a.ogg" type="audio/ogg">—— Firefox/Chrome 稳,Safari 完全不支持,放第二位 -
<source src="a.opus" type="audio/opus">—— Chrome/Firefox 支持,体积比 MP3 小 30%~50%,适合网络受限场景
注意:type="audio/mp3" 是错的,type="audio/wav" 虽能播但体积大、加载慢,仅适合几秒提示音;WAV 在 Safari 上反而比 OGG 更稳,但别放第一位。
autoplay 失效不是 bug,是浏览器强制拦截
写了 autoplay 却没声音?不是代码漏了 muted,而是现代浏览器(Chrome ≥66、Firefox ≥66、Safari ≥11、Edge ≥79)默认阻止“有声自动播放”。它不会报错,只在控制台输出 DOMException: play() failed because the user didn't interact with the document first。
- 要静音自动播:必须同时写
autoplay muted,且确保 JS 没后续改audio.muted = false或audio.volume = 1 - 要带声自动播:放弃
autoplay,改用用户手势触发 —— 比如按钮点击后调audio.play().catch(e => console.warn("play blocked:", e)) - iOS Safari 更严:元素必须在视口内、未被
display: none或opacity: 0遮挡,否则即使点过也静音
本地开发时 audio 加载失败,大概率是 file:// 协议惹的祸
双击 HTML 文件打开,或用 VS Code Live Server 以外的方式本地预览,Chrome/Firefox 会直接屏蔽音频加载,连 play() 都抛 NotAllowedError。这不是兼容问题,是协议限制。
立即学习“前端免费学习笔记(深入)”;
- 必须用本地 HTTP 服务:Python 用户运行
python3 -m http.server 8000,Node 用户用http-server - 检查 Network 面板:确认音频请求返回 200,且响应头
Content-Type是audio/mpeg、audio/ogg等合法类型 - 服务器没配 MIME 类型?Apache 加
AddType audio/mpeg .mp3,Nginx 在types块加audio/mpeg mp3;
JS 控制播放时,时间点和状态判断容易错
直接在 DOMContentLoaded 里调 audio.play() 必然失败;用 audio.paused === false 判断是否正在播放,会在播放结束时误判(因为 ended 为 true 时 paused 也是 true)。
-
currentTime必须等loadedmetadata事件后才能设,否则会被忽略 - 正确判断“是否真在播放”:
!audio.paused && !audio.ended -
timeupdate触发太密(约 200–250ms 一次),别在里面直接更新 DOM,应节流或用requestAnimationFrame - 监听
error事件看哪个source失败:audio.addEventListener('error', () => console.log(audio.error?.code)),code === 4表示所有 source 均不可用
真正卡住人的从来不是“怎么写”,而是“什么时候能写”——用户没点,play() 就是废操作;服务器 MIME 错一位,整个 <source> 就白写;iOS 视口外的元素,点了也静音。这些点不手动验证一遍,光靠查文档永远调不通。



















