安卓音频播放失败主因是格式、属性或时机问题:需用显式声明type(如audio/mpeg),加controls和muted才能autoplay,play()须捕获promise拒绝,preload推荐metadata,厂商webview可能禁用volume。

安卓设备上音频播放失败,八成不是代码写错了,而是格式、属性或加载时机没对上。只写 <audio src="a.mp3"></audio> 在大部分安卓 WebView 或旧版 Chrome 中会静默失败——没报错,但点不动、duration 是 NaN、play() 被拒绝。
必须显式写 <source></source> + type 属性
安卓(尤其低版本 WebView 和部分定制 ROM)不解析文件后缀,只认 type 声明的 MIME 类型。省略 type 或写错(比如 audio/mp3),浏览器直接跳过该源。
-
MP3必须写type="audio/mpeg"(不是audio/mp3) -
OGG写type="audio/ogg",WAV写type="audio/wav" - 多个
<source></source>按 DOM 顺序尝试,把兼容性最稳的放最前(通常是 MP3)
controls 和 muted 别省略
安卓 Chrome 和多数 WebView 默认隐藏控件;且有声 autoplay 几乎必被拦截——即使写了,play() 也会抛 NotAllowedError。
- 必须加
controls,否则用户连播放按钮都看不到 - 若需自动播放,
autoplay和muted必须同时存在,缺一不可 - 不要写
muted="false":布尔属性设为 false 无效,JS 中改回有声得用audio.muted = false
JS 播放必须捕获 Promise 拒绝
安卓环境下,audio.play() 不是同步成功,而是返回 Promise,失败时不会抛异常,只 reject。
- 必须用
.catch()捕获:audio.play().catch(e => console.warn('play failed:', e.name)) - 常见错误:
NotAllowedError(未静音或无用户手势)、NotSupportedError(所有<source></source>都不支持)、AbortError(网络中断) - 监听
error事件可确认哪个源挂了:audio.addEventListener('error', () => console.log(audio.error?.code)),code === 4表示全部失败
preload 和 iOS/Android 差异要分开处理
preload="auto" 在安卓多数 WebView 中被忽略,iOS 则强制降级为 metadata。盲目依赖它会导致首播延迟或卡顿。
- 推荐设
preload="metadata":只加载时长、采样率等元信息,不下载音频体,平衡速度与流量 - 不要在
canplay后立刻设currentTime:安卓某些 WebView 中该事件触发太早,currentTime会被重置;iOS 则要求必须等canplay才能设 - 需要精确跳转时,优先监听
canplaythrough,但注意它会显著延迟首次播放
最易被忽略的一点:安卓某些厂商定制系统(如华为 EMUI、小米 MIUI)的 WebView 会主动禁用 audio 的 volume 属性调节,JS 设置 audio.volume = 0.5 可能完全无效——这种场景只能靠服务端混音或 Web Audio API 替代。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











