uni-app 中必须用 uni.getBackgroundAudioManager() 实现后台播放,因 new Audio() 在 App 端受系统限制,切后台即停、iOS 尤其严格;该 API 需设置 title、epname 等字段才支持锁屏控制,且 src 必须为 HTTPS 直链地址。

uni-app 无法直接用 Audio 对象实现后台持续播放,必须用 uni.getBackgroundAudioManager(),否则切到后台就停、锁屏就断、iOS 尤其严格。
为什么 new Audio() 在 uni-app 里不适用于背景播放
因为 new Audio() 是 Web 标准 API,在 App 端(尤其是 iOS)被系统限制:一旦页面失焦或 App 进入后台,音频自动暂停,且无法恢复。uni-app 的 H5 端虽能跑,但和「背景音频」需求本质冲突。
- App 端(iOS/Android):
new Audio()没有后台生命周期权限 - 小程序端:部分平台(如微信)会静音或拦截非用户主动触发的播放
- 真正跨端可用的唯一方案是
uni.getBackgroundAudioManager()—— 它是 uni-app 封装的原生音频管理器,对接系统后台音频服务
uni.getBackgroundAudioManager() 基本用法与必设字段
这个 API 返回一个全局单例对象,所有操作都基于它。**不调用 title 和 epname 就无法在 iOS 锁屏界面显示控制条**,Android 也建议填全。
const bgAudio = uni.getBackgroundAudioManager(); bgAudio.title = '晴天'; // 必填,否则 iOS 不显示锁屏控件 bgAudio.epname = '范特西'; // 推荐填,专辑名 bgAudio.singer = '周杰伦'; // 推荐填,歌手名 bgAudio.src = 'https://example.com/qingtian.mp3'; // 必须是 HTTPS(iOS 强制,Android 部分版本也要求) bgAudio.coverImgUrl = 'https://example.com/qingtian.jpg'; // 可选,锁屏封面
-
src必须是可直链访问的音频地址,不能是本地static/路径(App 端不支持 file:// 协议后台播放) - H5 端不支持该 API,需降级处理:用
new Audio()+ 页面可见性监听 - 首次播放必须由用户手势触发(如
buttonclick),否则 iOS 直接拒绝
常见错误:播放没反应、状态不更新、iOS 锁屏无控件
问题往往出在「时机」和「字段完整性」上,不是代码写错,而是漏了关键约束。
- 调用
bgAudio.play()前未设置title或src→ iOS 静默失败,无报错 - 在
onLoad里直接play()→ 触发非用户手势,iOS 拒绝(需绑定到button @click) - 音频地址跨域或非 HTTPS → Android 可能播,iOS 100% 失败,控制台无明确错误
- 未监听
bgAudio.onPlay/onError→ 不知道是否真播了,误以为卡住 - 重复调用
uni.getBackgroundAudioManager()没问题,它始终返回同一实例,但别反复赋值src后立刻play(),加个pause()再play()更稳
简单播放器逻辑示例(含状态同步)
只需几个核心状态 + 事件绑定,就能支撑基础播放/暂停/切换:
export default {
data() {
return {
isPlaying: false,
currentTime: 0,
duration: 0
}
},
onLoad() {
const bgAudio = uni.getBackgroundAudioManager();
bgAudio.onPlay(() => {
this.isPlaying = true;
});
bgAudio.onPause(() => {
this.isPlaying = false;
});
bgAudio.onTimeUpdate(() => {
this.currentTime = bgAudio.currentTime;
this.duration = bgAudio.duration;
});
bgAudio.onError((err) => {
console.error('背景音频错误:', err.errMsg);
});
},
methods: {
togglePlay() {
const bgAudio = uni.getBackgroundAudioManager();
if (this.isPlaying) {
bgAudio.pause();
} else {
// 确保 src 已设置、title 已填,再 play
if (bgAudio.src) bgAudio.play();
}
},
setAudio(src, title, singer) {
const bgAudio = uni.getBackgroundAudioManager();
bgAudio.src = src;
bgAudio.title = title;
bgAudio.singer = singer;
// 注意:这里不立即 play,等用户点击
}
}
}
真实项目里容易忽略的是「状态不同步」:比如用户从锁屏点暂停,onPause 会触发,但如果你没监听,UI 还显示“正在播放”。所有控制都必须以 bgAudio 的事件为准,不能只信自己的变量。



















