锁屏歌词唯一合规方案是预处理歌词为时间轴数组,按播放时间匹配当前句填入title字段;前台用scroll-view实现滚动高亮,锁屏仅静态显示单句文本。

uni.getBackgroundAudioManager() 是锁屏歌词的唯一入口
锁屏界面显示动态歌词,不是靠前端 DOM 滚动或 scroll-view 实现的——那是前台页面逻辑,锁屏时整个 WebView 已被系统挂起。真正能影响锁屏控件内容的,只有 uni.getBackgroundAudioManager() 设置的元数据和系统级媒体会话(MediaSession)。
iOS 锁屏界面只认三个字段:title、singer、coverImgUrl;Android 则依赖原生 MediaSession 的 setMetadata() 和 setPlaybackState(),但 uni-app 未暴露直接控制接口,只能靠 JS 层有限同步。
常见错误现象:歌词滚动效果在页面内正常,一锁屏就只剩静态封面和标题;或锁屏后歌词完全不更新,进度条卡死。根本原因是误把前台歌词渲染逻辑当成了锁屏能力,忽略了系统对后台媒体信息的强约束。
为什么不能用 onTimeUpdate 去实时改锁屏歌词
onTimeUpdate 在后台触发频率极低(iOS 约 250–500ms 一次,Android 更不稳定),且锁屏界面**根本不支持动态文本更新**——它只展示你初始化时填的 title 和 singer,不接受运行时反复赋值。
想让锁屏“显示当前歌词”,唯一合规做法是:把整段歌词预处理成时间轴数组,再按当前播放时间匹配出最接近的一句,然后把它塞进 title 字段里(例如:bgm.title = '春风十里')。但这有严重限制:
- iOS 对
title长度敏感,超长会被截断或导致锁屏控件消失 - 频繁修改
title可能触发系统重绘抖动,部分 Android 机型直接忽略后续更新 - 没有“歌词行号”“高亮色”等样式控制,纯文本,无法实现逐字/逐行动画
实际可落地的锁屏歌词方案
与其强行“动态刷新锁屏歌词”,不如接受平台限制,做合理降级:
-
前台页面:用
scroll-view+onTimeUpdate实现精准滚动高亮(参考网易云格式,lyricTime匹配lyric[]中time字段) -
锁屏界面:只设一个「当前句」作为
title,例如bgm.title = '[01:23.45]山高水长';singer放歌手名;coverImgUrl必须是 HTTPS 可直链图 -
避免踩坑:不要在
onTimeUpdate里反复调用bgm.title = xxx,改为仅当跨行时更新(比如上一秒是第 3 行,当前秒进了第 4 行,才赋新值) -
H5 / 小程序端:
uni.getBackgroundAudioManager()在 H5 无锁屏概念,在微信小程序中虽支持title显示,但不支持动态更新,同样需降级为前台滚动
manifest.json 和权限配置必须到位
即使代码写对,没配 manifest,title 修改也不会出现在锁屏界面:
- iOS:确保
app-plus.distribute.ios.UIBackgroundModes是["audio"](字符串数组,不是字符串) - Android:
app-plus.background.mode设为"audio",且app-plus.modules.Audio为{} - 所有平台:改完必须重新云打包,本地调试和热更新无效
- src 地址必须是 HTTPS(iOS 强制,Android 部分版本也校验),不能是
/static/xxx.mp3
最容易被忽略的是:锁屏歌词不是“功能开关”,而是系统媒体会话的副产品;它依赖音频通道激活、权限声明、元数据填充、用户手势触发这四者同时成立。少一个,title 就不会出现在锁屏界面上。











