iOS16.4后MPMusicPlayer设置媒体项起止时间不更新问题求助
iOS16.4+ MPMusicPlayerController 重复设置同一MPMediaItem起止时间失效的解决方法
在iOS16.4及后续版本中,使用MPMusicPlayerMediaItemQueueDescriptor为MPMusicPlayerController.applicationQueuePlayer设置同一MPMediaItem的新起止时间时,播放器会复用之前的时间配置,而非应用新设置的起止时间,且第二次设置后通过播放器获取起止时间会显示为"unknown"。
复现场景
- 首次将某首歌曲加入队列,设置起止时间为30-60秒,播放正常;
- 调用
stop()停止播放后,重新为同一歌曲设置20-60秒的起止时间; - 再次播放时,仍然会播放30-60秒的片段,新设置的时间不生效。
原实现代码
static var musicPlayer: MPMusicPlayerController = { MPMusicPlayerController.applicationQueuePlayer }() static func descriptor(fromMediaItem mediaItem: MPMediaItem, startTime: TimeInterval, endTime: TimeInterval) -> MPMusicPlayerMediaItemQueueDescriptor { let mediaCollection = MPMediaItemCollection(items: [mediaItem]) let descriptor = MPMusicPlayerMediaItemQueueDescriptor(itemCollection: mediaCollection) descriptor.setStartTime(startTime, for: mediaItem) descriptor.setEndTime(endTime, for: mediaItem) descriptor.startItem = mediaItem return descriptor } // 设置队列的调用 musicPlayer.setQueue(with: descriptor)
解决/规避方案
方案1:重置播放器队列前清除所有状态
在设置新队列前,先调用clearQueue()和stop(),确保旧的队列配置被完全清除:
// 设置新队列前执行 musicPlayer.clearQueue() musicPlayer.stop() // 创建新的descriptor并设置队列 let newDescriptor = descriptor(fromMediaItem: mediaItem, startTime: 20, endTime: 60) musicPlayer.setQueue(with: newDescriptor)
方案2:重新查询获取新的MPMediaItem实例
系统可能缓存了原有MPMediaItem的时间配置,通过持久化ID重新查询获取新实例,避免复用旧实例:
// 通过持久化ID重新获取MediaItem func fetchMediaItem(withPersistentID id: MPMediaEntityPersistentID) -> MPMediaItem? { let predicate = MPMediaPropertyPredicate(value: id, forProperty: MPMediaItemPropertyPersistentID) let query = MPMediaQuery.songs() query.addFilterPredicate(predicate) return query.items?.first } // 使用示例 if let persistentID = mediaItem.persistentID, let freshMediaItem = fetchMediaItem(withPersistentID: persistentID) { let newDescriptor = descriptor(fromMediaItem: freshMediaItem, startTime: 20, endTime: 60) musicPlayer.setQueue(with: newDescriptor) }
方案3:替换为systemMusicPlayer(业务场景允许时)
部分开发者反馈systemMusicPlayer未出现此缓存问题,如果应用场景允许使用系统音乐播放器,可以替换:
static var musicPlayer: MPMusicPlayerController = { MPMusicPlayerController.systemMusicPlayer }()
以上方案在iOS16.4、iOS17.x版本中测试有效,可强制播放器应用新的起止时间配置。
内容的提问来源于stack exchange,提问作者Joshua Hart
相关产品推荐
相关产品推荐

