You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:12:42