Jetpack Media3中MediaController与TextToSpeechPlayer时间轴不同步问题
Jetpack Media3 TTS播放器与MediaController时间轴不同步问题修复
核心问题根源
Media3的MediaController完全依赖Player通过Listener机制同步时间轴状态。你遇到的"初始39条最终剩1条"的问题,本质是自定义TextToSpeechPlayer在时间轴构建、状态通知或委托切换环节,没有严格遵循Media3的Player接口规范。
分步修复方案
1. 确保时间轴构建符合Media3要求
自定义Player返回的时间轴必须是不可变的ImmutableTimeline,且每个MediaItem必须携带唯一mediaId——这是MediaController识别条目唯一性的核心依据。如果你的TTS内容是39个文本片段,构建时间轴时要为每个片段生成独立的MediaItem:
// 示例:构建包含39个TTS条目的时间轴 val ttsMediaItems = List(39) { idx -> MediaItem.Builder() .setMediaId("tts_segment_$idx") // 必须唯一,不能重复 .setUri("tts://content_$idx") // 自定义URI标识TTS片段 .build() } val ttsTimeline = ImmutableTimeline( ttsMediaItems, windowCount = ttsMediaItems.size, shuffleModeEnabled = false, repeatMode = Player.REPEAT_MODE_OFF ) // 确保Player的getTimeline()始终返回这个完整的时间轴
2. 主动触发时间轴更新通知
当自定义Player的时间轴发生变化(包括初始化设置),必须立即调用notifyListeners通知所有注册的Listener(包括MediaController):
private var currentTimeline: Timeline = EmptyTimeline() fun setTtsMediaItems(items: List<MediaItem>) { currentTimeline = ImmutableTimeline(items) // 必须指定正确的变更原因,MediaController会根据原因处理更新 notifyListeners { onTimelineChanged(currentTimeline, Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED) } }
注意:切换委托播放器时,也要在切换完成后触发一次时间轴通知,确保MediaController感知到新的Player时间轴。
3. 规范委托播放器切换流程
切换在线MP3播放器和离线TTS播放器时,必须避免状态冲突:
- 切换前暂停当前播放器,调用
pause(); - 切换后立即将新Player的时间轴同步,不要调用
MediaController.setMediaItems()覆盖原列表(应该由自定义Player内部处理时间轴); - 如果新Player需要
prepare(),确保在切换后调用,并触发对应的状态通知。
4. 验证Player核心方法的正确性
MediaController依赖Player的以下方法同步状态,必须确保这些方法返回正确值:
getTimeline():每次调用都返回完整的39条目的时间轴,不能在某些场景下返回仅含1条的时间轴;getCurrentMediaItemIndex():正确返回当前播放的条目索引,避免MediaController误判播放位置;getMediaItemCount():返回39,而不是1。
5. 排查MediaController的Listener生命周期
确保MediaController.addListener()在Activity/Fragment的onStart()或onResume()中注册,removeListener()在onStop()或onPause()中执行,避免Listener被意外移除导致时间轴更新无法接收。
快速调试技巧
- 在
TextToSpeechPlayer.getTimeline()方法中添加日志,记录每次调用返回的条目数量,确认是否在某些场景下返回了仅1条的时间轴; - 在
MediaController.onTimelineChanged()回调中打印时间轴条目数,跟踪从39变为1的触发时机,定位是Player主动推送了错误时间轴,还是MediaController自身过滤了条目。
内容的提问来源于stack exchange,提问作者adam_beers
相关产品推荐
相关产品推荐

