audio标签应省略src,用多个带type属性的source标签实现格式fallback,优先级从上到下;切换src需调用load()并监听canplaythrough;ios/微信首次播放须用户手势触发;preload推荐metadata或auto,避免none。

audio 标签里用多个 <source></source> 实现多格式 fallback
浏览器对音频格式的支持不一致,MP3 在 Safari/Chrome 里通吃,但 Firefox 和旧版 Edge 更倾向 OGG;WAV 虽通用但体积大。只写一个 src 属性,遇到不支持的格式就会静默失败——用户看到控件却播不出声,还查不到错在哪。
正确做法是省略 src,改用嵌套的 <source></source> 标签按优先级罗列:
- 把兼容性最广的格式(如 MP3)放在最上面,浏览器从上到下匹配第一个能解码的
- 每个
<source></source>必须带type属性,例如type="audio/mpeg"或type="audio/ogg",不能只靠文件后缀判断 - 标签内保留一段提示文字,比如“您的浏览器不支持音频播放”,它只在所有
<source></source>都失效时显示
<audio controls><source src="song.mp3" type="audio/mpeg"><source src="song.ogg" type="audio/ogg"><source src="song.wav" type="audio/wav"> 您的浏览器不支持音频播放。 </source></source></source></audio>
为什么改 src 属性不能直接切换格式
直接给 <audio></audio> 元素赋新 src 值(比如 audio.src = "new.mp3"),大多数浏览器不会自动重新加载资源——它可能继续播旧的、卡住、或静音。这不是 bug,而是规范行为:改 src 只更新属性值,不触发加载流程。
必须显式调用 load() 方法,才能让浏览器丢弃当前缓冲、重新解析并加载新源:
- 切换前先
audio.pause(),避免状态残留 - 再赋值
audio.src,然后立刻audio.load() - 如果想自动播放,得等
canplaythrough事件(不是loadeddata),它表示缓冲足够、可连续播放
const audio = document.getElementById('player');
function switchTo(src) {
audio.pause();
audio.src = src;
audio.load();
audio.addEventListener('canplaythrough', () => audio.play(), { once: true });
}
iOS 和微信里切音频必须由用户手势触发
哪怕你写了 audio.play() 并监听了 canplaythrough,在 iOS Safari 或微信内置浏览器中,首次调用 play() 仍会失败,报错类似 NotAllowedError: play() failed because the user didn't interact with the document first。这是硬性策略,绕不过去。
可行解法只有两个:
- 所有切换操作绑定在用户点击(
click、touchend)回调里,且首次播放必须在该回调同步执行(不能套setTimeout或异步 Promise) - 如果页面有“静音背景音”需求,可提前在页面初始化时用一次
audio.muted = true; audio.play()建立播放上下文,之后再切源、取消静音就能正常播
preload 设成 "none" 能省流量但影响体验
默认 preload="auto" 会让浏览器预加载整个音频,对大文件(比如 30MB 的无损 FLAC)很不友好;设成 "metadata" 只取时长、采样率等信息,加载快、开销小,适合列表页预览;而 "none" 完全不预加载,用户点播放才开始拉流——看似省事,但首播延迟明显,尤其弱网下容易卡在 loading 状态。
实际项目中建议:
- 列表页缩略播放(如 15 秒试听)用
preload="metadata" - 详情页主播放器用
preload="auto",并配合服务端启用 HTTP Range 请求支持断点续传 - 千万别在
<source></source>上单独设preload——它只认<audio></audio>根标签的属性
load() 都会清空之前绑定的所有事件(timeupdate、ended 等),所以动态切换音频时,要么每次都重新 addEventListener,要么用事件委托兜底。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











