浏览器在标签页失焦、锁屏或最小化时主动暂停有声音频是统一策略,非bug;无法绕过,Media Session API仅维持系统控件与解码线程,需先用户手势触发播放再注册;iframe隔离可避免页面跳转中断音频。

浏览器在标签页失焦、系统锁屏或页面最小化时主动暂停有声音频,不是 bug,是所有主流浏览器(Chrome、Firefox、Safari、Edge)统一执行的策略。所谓“自动停止”,本质是策略性挂起,play() 调用会直接被拒绝,错误信息通常是 "DOMException: play() failed because the document is not visible" 或 "play() failed because the user didn't interact with the document first"。
audio 标签切到后台就停,怎么绕过?
根本绕不过——浏览器不让你绕。Media Session API 不是“让音频继续播”,而是“让系统知道它在播”,从而维持解码线程、显示锁屏控件、响应媒体键。它必须配合已开始播放的 audio 实例使用,且只在页面处于 document.visibilityState === 'visible' 时注册 handler 才有效。
- 必须先调用
audio.play()成功(用户点击后),再设置navigator.mediaSession.metadata - 必须注册
setActionHandler('play')、'pause'等,否则系统控件点不动 - 切到后台后,
setActionHandler不再触发,但状态仍可读、UI 仍可显示 - Android 部分机型能借此维持音频输出;iOS 锁屏后仍会中断,仅保留控件可见性
页面跳转时音乐断掉,怎么保持连续?
这不是后台问题,是 DOM 销毁问题。整页刷新或导航到新 HTML 会导致 audio 元素被回收,播放必然中断。唯一轻量可靠的方案是用 隔离内容层。
- 主页面(如
index.html)固定包含和播放控件,不参与跳转 - 所有内容页(如
scene1.html、scene2.html)通过加载到主页面内 - 跳转逻辑由主页面 JS 控制:
iframe.src = "scene2.html",不触发 reload -
iframe内无法直接访问父页面的audio,需用postMessage发送播放/暂停指令
为什么加了 loop、autoplay、preload="auto" 还是停?
这些属性和后台持续播放无关。loop 只在当前播放实例未被中断时生效;autoplay 在现代浏览器中基本失效(除非 muted);preload 控制的是加载时机,不是生命周期。
-
preload="metadata"是最实用的取值:快速获取时长、避免首次点击卡顿 -
preload="auto"在移动网络下常退化为metadata,不可依赖 -
loop对 iOS Safari 无效:后台暂停后,即使恢复前台也不会自动续播 - 不要在
setTimeout或异步回调里调用play(),浏览器会判定为“非用户直接触发”
真正容易被忽略的点是:Service Worker 无法播放音频,也不能唤醒页面恢复播放; 必须存在于活跃的 document 上下文中,且首次播放必须由用户手势同步触发——哪怕只是点一下按钮,之后再用键盘空格控制,也比试图“全自动”可靠得多。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











