uni.createinneraudiocontext()是唯一可靠方案,因其封装原生音频上下文可绕过ios微信/app后台静音限制;其他方式在对应平台必然中断。

uni-app 实现后台持续播放音乐,唯一可靠路径是 uni.createInnerAudioContext() + 正确的平台配置,其他方式(如 <audio></audio> 标签、uni.getBackgroundAudioManager())在 iOS 微信和 App 真机后台必然中断或静音。
为什么 uni.createInnerAudioContext() 是唯一选择
它封装了原生音频上下文,在 iOS 微信、App 端能绕过部分自动静音限制;而 <audio></audio> 标签在这些平台切后台即停,uni.getBackgroundAudioManager() 仅适用于微信小程序(非 uni-app App),且 H5 端不支持。H5 本身无“后台”概念,切页即停,别指望它保持播放状态。
- iOS 微信:只有
uni.createInnerAudioContext()配合用户首次手势触发,才可能维持后台播放 - App 端:必须在
manifest.json中启用Audio模块,否则系统直接杀进程 - H5 端:浏览器禁止自动播放,必须由用户点击等交互后才能调用
play()
manifest.json 必须配对的后台权限
没配这个,代码写得再对也白搭。App 端后台播放依赖系统级声明,缺一不可:
- Android:需添加
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>到app-plus.distribute.android.permissions - iOS:必须在
app-plus.modules下开启Audio,并在app-plus.distribute.ios.UIBackgroundModes中填入["audio"] - 路径示例(
manifest.json片段):{"app-plus": {"modules": {"Audio": {}}, "distribute": {"android": {"permissions": ["<uses-permission android:name='\"android.permission.WAKE_LOCK\"'></uses-permission>"]}, "ios": {"UIBackgroundModes": ["audio"]}}}}
循环播放不能只设 loop = true
iOS 系统不支持真正无缝循环,设 loop = true 后仍会出现 100–300ms 间隙,用户能明显感知卡顿。必须手动监听 ended 事件并重置播放位置:
- 错误写法:
audio.loop = true→ 期望自动续播,实际有 Gap - 正确写法:
audio.onEnded(() => { audio.seek(0); audio.play(); }) - 注意:
seek(0)在部分 Android 机型上可能失败,建议加try/catch并 fallback 到重新赋值src - 不要在
onLoad就调play(),H5 会报DOMException: play() failed;应绑定到按钮点击或onShow后延时 100ms 再触发
锁屏控制与封面显示仅限 App 原生渲染
微信小程序和 H5 完全不支持锁屏界面信息,只有 App 端(且需使用原生渲染)可通过 plus.audio.setLockScreenControl() 设置标题、歌手、封面:
- 必须包裹在
#ifdef APP-PLUS中,否则编译报错 - 封面图片路径必须是本地绝对路径(如
/static/cover.jpg),网络地址无效 - 设置时机应在
audio.play()成功后,否则部分 iOS 机型无法同步显示 - 该 API 不返回 Promise,也不抛错,失败时静默忽略——务必真机测试确认是否生效
最容易被忽略的是:iOS 后台音频保活极度依赖“首个有效音频播放”的时机。如果用户首次进入页面时未触发播放(比如延迟加载、条件判断跳过),后续再怎么调 play() 都可能被系统拒绝。所以,首次交互触发必须真实、及时、不可绕过。











