Ncrust v1.1.4 更新日志
注意:无缝播放和多语言还在实验阶段
🐛 问题修复
无缝播放元数据与音频不同步
- 修复 gapless 模式下 UI 显示下一首歌曲信息但音频仍播放上一首的问题
- 根本原因:
playFromQueue在 URL fetch 完成前就更新了currentSong,导致 UI 超前于音频 - 修复:ViewModel 维护
currentSongId,UI 通过LaunchedEffect(vmCurrentSongId)同步更新,确保元数据与音频原子切换
预加载协程被反复取消导致卡顿
- 修复切歌时预加载协程被
preloadJob?.cancel()错误取消的问题 - 原代码每 250ms 触发一次
needsPreload重置 → 无限循环取消/重启预加载 → 歌曲 URL 永远取不完 - 修复:移除
resetPreloadFlag()循环触发机制,改为由playSong()和onSongTransitioned自然清零
预加载 URL 无缓存,手动切歌重复请求
- gapless 已预取的 URL 在手动切歌时被丢弃,重新发起网络请求(耗时 1-3 秒)
- 修复:新增
preloadCache(5 分钟 TTL),playSong快速路径优先使用缓存 URL
切歌时解码器资源冲突
- 旧解码器未完全释放时新解码器已启动,导致播放卡顿
- 修复:在
PlaybackService中使用player.addMediaItem()将预加载 URL 提前加入 ExoPlayer 队列,实现真正的无缝切换
🔧 改进
预加载时机提前
- 从"歌曲剩余 20 秒"改为"歌曲开始播放时立即预加载下一首"
- 整曲时长作为 buffer,网络请求充足时间完成
预加载去重机制
- 新增
currentlyPreloadingSongId字段,同一首歌不重复预加载 - 双重去重:已缓存或正在处理中直接 return,不 cancel 也不重启
📦 技术细节
PlayerViewModel.kt:新增PreloadCacheEntry、preloadCache、currentlyPreloadingSongId;preloadNextSong去重逻辑;playSong缓存优先PlaybackService.kt:新增preload_nextIntent 处理;onMediaItemTransition(AUTO)回调;队列管理优化MainActivity.kt:移除resetPreloadFlag()循环;新增LaunchedEffect(vmCurrentSongId)同步元数据