uni.getbackgroundaudiomanager()是唯一支持锁屏播放的api,因其桥接原生音频会话:ios设avaudiosessioncategoryplayback,android申请wake_lock并绑定媒体会话,从而满足系统后台音频要求。

必须用 uni.getBackgroundAudioManager(),其他 API(比如 uni.createInnerAudioContext())在锁屏后必然中断,iOS 尤其严格——这不是兼容性问题,是系统级限制。
为什么 uni.getBackgroundAudioManager() 是唯一入口
这个 API 本质是桥接到原生的音频会话管理器:iOS 上它调用 AVAudioSession 设置 AVAudioSessionCategoryPlayback,Android 上则申请 WAKE_LOCK 并绑定媒体会话。只有走这条路,系统才认为你的 App “正在播放媒体”,从而允许锁屏后继续播、响应耳机按键、在控制中心显示封面和进度条。
常见错误现象:
-
play()调用后有声音,一锁屏就静音 - 锁屏界面空白,不显示标题/歌手/封面
- iOS 上完全没反应,连
onPlay都不触发
根本原因几乎全是:误用了前台音频上下文,或元数据缺失、权限未配、触发方式违规。
manifest.json 必须手动加后台模式声明
App 端(app-plus)和微信小程序(mp-weixin)都需要显式声明后台音频能力,否则系统直接拒绝授权。
在 manifest.json 的源码视图中,找到对应平台节点,添加:
{
"name": "app-plus",
"requiredBackgroundModes": ["audio"]
}
注意:
- 不能写在根节点,必须嵌套在
"app-plus"或"mp-weixin"下 - 字段名是
requiredBackgroundModes,不是backgroundModes或backgroundMode - iOS 打包后若仍无效,检查 Xcode 工程是否自动同步了该配置(云打包会自动处理,离线打包需手动确认
Info.plist中有UIBackgroundModes数组含audio)
元数据和触发时机两个硬门槛
iOS 对后台播放卡得极死:缺任意一项元数据,或没用户手势触发,play() 就是静默失败。
必须设置的字段(顺序无关,但缺一不可):
-
title:歌曲标题,锁屏控件第一行文字 -
singer:歌手名,第二行 -
src:必须是 HTTPS 可直链地址(/static/xxx.mp3在 App 端可能因路径解析失败而静音)
播放动作必须由用户操作触发:
- 不能在
onLoad、onShow或定时器里调用play() - 必须绑定在
<button></button>的@click、uni.showToast回调等明确交互事件中 - 微信小程序里,甚至要等
uni.getSystemInfoSync().platform返回后才可安全调用
H5 端不支持,必须条件编译隔离
uni.getBackgroundAudioManager() 在 H5 环境下无任何报错,但也不起作用——它被 uni-app 内部静默降级为普通 Audio 对象,切后台必停。
正确做法是用条件编译主动分流:
#ifdef APP-PLUS || MP-WEIXIN
const bgm = uni.getBackgroundAudioManager()
bgm.title = '夜曲'
bgm.singer = '周杰伦'
bgm.src = 'https://xxx.com/yequ.mp3'
bgm.play()
#endif
#ifdef H5
const audio = new Audio('/static/music/h5-bg.mp3')
audio.loop = true
audio.play().catch(() => {}) // H5 自动播大概率被拦截
#endif
容易被忽略的一点:微信小程序里,backgroundAudioManager 是单例,且事件监听必须在首次使用前绑定;重复绑定会导致 onTimeUpdate 多次触发,进度条跳变。全局只初始化一次,挂到 uni.$bgm 最稳妥。











