audio标签需显式设controls属性(空字符串有效,controls="false"会误触发显示),多格式source须按mp3→opus→wav顺序静态声明,自动播放需同时满足muted、用户手势和preload="metadata"三条件。

只写一个 src 属性,或只提供 MP3 格式,基本等于放弃 Safari(尤其 iOS)、旧版 Firefox 和部分企业内网环境的播放能力。
audio 标签必须显式设置 controls 才能显示控件
不写 controls,浏览器就默认隐藏所有播放界面,哪怕音频在后台响了你也看不到按钮。空字符串 controls="" 有效,但 controls="false" 是个典型陷阱——浏览器会把它当真值处理,依然显示控件。
常见错误现象:
- 页面没出现播放器,检查控制台无报错,但 DOM 里漏写了
controls - 写了
controls="false",结果控件意外出现,且无法通过 JS 关闭(因为属性已存在)
多格式 <source></source> 必须按兼容性顺序静态声明
浏览器从上到下尝试每个 <source></source>,遇到第一个 canPlayType() 返回非 "" 的就停。JS 动态判断再插入毫无必要,反而增加失败概率。
推荐顺序与理由:
-
<source src="sound.mp3" type="audio/mpeg"></source>:MP3 兼容最广,但注意 Safari 对 VBR 编码偶有解码失败 -
<source src="sound.opus" type="audio/opus"></source>:Chrome/Firefox 已原生支持,体积比 MP3 小 30%~50%,适合网络受限场景 -
<source src="sound.wav" type="audio/wav"></source>:Safari(尤其 iOS)对 WAV 支持稳定,适合短提示音;但文件大、加载慢,仅作兜底
别把 ogg 放最后——Firefox/Chrome 能播,但 Safari 完全跳过,放最后等于白写。
自动播放必须满足 muted + 用户手势 + preload=metadata 三条件
Chrome ≥70、Firefox ≥66、Safari ≥12.1 全面限制有声自动播放。静音自动播不是“加了 muted 就行”,还有隐藏约束:
-
muted是布尔属性,写即生效;设muted="false"无效,JS 中要恢复声音得用audio.muted = false -
preload="auto"在 iOS Safari 上被忽略,强制降级为metadata,所以直接写preload="metadata"更可控 - 所有
play()调用必须包裹在用户点击/触摸事件回调里,load或canplay回调中触发必失败
本地开发时用 file:// 协议,Chrome 会直接拒绝 play() 并抛 DOMException: play() failed because the user didn't interact with the document first,必须起本地服务器(如 python3 -m http.server)。
JS 播放必须捕获错误并监听 error 事件
audio.play() 返回 Promise,不 catch 就会静默失败。不同错误码对应不同问题:
-
NotAllowedError:自动播放被拒(未满足 muted/手势条件) -
NotSupportedError:当前所有<source></source>的type均不被支持 -
AbortError:网络中断或资源加载被取消 -
audio.error?.code === 4:所有<source></source>都加载失败(常因路径错、MIME 类型不匹配或服务器未返回 200)
别依赖 canplay 判断是否可播——它只等元数据加载完,音频体可能还在传输中;canplaythrough 更准,但会显著延迟首次播放时机,对提示音类场景不友好。
真正容易被忽略的是 MIME 类型和服务器响应头:Network 面板里确认请求返回 200,且 Content-Type 是 audio/mpeg、audio/ogg 等合法类型;用 Nginx/Apache 时若未配置对应 MIME 映射,即使文件存在也会 404 或播不出。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











