锁屏控制中心总时长显示0:00或NaN,根本原因是MPNowPlayingInfoCenter(iOS)或MediaSession(Android)接收的duration未正确设置:uni.createInnerAudioContext()不主动上报时长,且元数据加载异步,常在onCanplay前就调用setNowPlaying;iOS要求MPMediaItemPropertyPlaybackDuration为NSNumber类型、毫秒整数,Android需传秒级浮点数且须配合title/artist等字段,无效值会被静默丢弃。

锁屏控制中心显示的总时长为什么总是 0:00 或 NaN?
根本原因是 MPNowPlayingInfoCenter(iOS)或 MediaSession(Android)接收的 duration 值未正确设置或单位错误。uni-app 的 uni.createInnerAudioContext() 默认不主动上报 duration,且音频元数据加载异步,容易在未就绪时就调用 setNowPlaying()。
- 常见错误现象:
MPNowPlayingInfoCenter显示 “0:00 / 0:00” 或 “–:– / –:–”,iOS 控制中心无法拖动进度条 - 必须等
onCanplay触发后才能获取准确的context.duration,不能依赖onLoad或初始化时刻的值 - Android 端需确保
mediaSession.setDuration()传入的是秒级浮点数(如245.3),传字符串或NaN会导致静默失败 - iOS 端要求
MPNowPlayingInfoCenter.nowPlayingInfo中的MPMediaItemPropertyPlaybackDuration必须是 NSNumber 类型,uni-app 插件层若未做类型转换,会 fallback 为 0
uni-app 如何正确设置锁屏播放总时长?
关键不是“调一次 setNowPlaying”,而是监听元数据就绪、校验数值有效性、并动态更新。原生层(iOS/Android)对 duration 的校验非常严格,无效值会被直接丢弃。
- 在
onCanplay回调中读取context.duration,确认其为有限正数:isFinite(context.duration) && context.duration > 0 - 调用
uni.setNowPlaying({ duration: Math.round(context.duration * 1000) })—— 注意:iOS 原生要求毫秒整数,Android 部分版本接受秒但推荐统一用毫秒 - 如果音频源支持 CORS 且是 MP3/M4A,可在
load后主动触发context.play()再暂停,强制触发元数据解析(某些 CDN 会延迟返回 duration) - 避免在
onError或onStop后残留旧 duration;建议每次播放新资源前清空:uni.setNowPlaying({ duration: 0 })
为什么改了 duration 还是不显示?检查这三个地方
多数问题不出在 JS 层,而在平台配置或生命周期时机。尤其要注意 iOS 真机调试时 Xcode 的后台音频能力是否开启。
- 检查
manifest.json → ios → capability → audio是否设为true,否则MPNowPlayingInfoCenter完全不可写 - 确认 H5 模式下没误用该 API(
uni.setNowPlaying仅在 App 平台有效,H5 调用无副作用但也不生效) - 真机测试时,若首次安装未手动开启「后台音频」权限,系统会拒绝写入 nowPlayingInfo —— 此时 Xcode 控制台会输出
NowPlayingInfoCenter is not available错误,但 uni-app 不抛 JS 异常
Android 上 MediaSession duration 更新延迟怎么办?
Android 原生 MediaSession 对 duration 更新有缓存机制,单纯调用 setNowPlaying 不一定立即刷新控制中心。需要配合状态同步信号。
- 必须在调用
uni.setNowPlaying()后,紧接着触发一次播放状态更新:uni.setNowPlaying({ playbackRate: context.playbackRate })(哪怕 rate 不变) - 部分 Android 12+ 设备要求
setNowPlaying中至少包含title、artist、duration三项才渲染时间轴 - 避免高频调用(如每秒设一次 duration),Android 会节流;只在
onCanplay和切换音源时设置即可
实际修复时最容易被忽略的,是认为“只要 duration 有值就行”。iOS 和 Android 对数值类型、单位、调用时机、配套字段的要求完全不同,且错误不会报 JS 异常 —— 它只是沉默地不显示。真机连 Xcode 或 adb logcat 看原生日志,比反复改 JS 更有效。


















