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

MPMediaItem在AVAudioPlayer中播放偶现解包可选值nil错误的技术问询

解决MPMediaItem转AVAudioPlayer时偶发的nil解包崩溃问题

这个问题我之前踩过坑!核心原因是不是所有MPMediaItem都能拿到有效的AssetURL——比如云端的Apple Music歌曲、受DRM保护的曲目,或者媒体库中仅存元数据但没有本地文件的条目,调用value(forProperty: MPMediaItemPropertyAssetURL)都会返回nil,你用as!强制解包自然就会偶发崩溃了。

修复步骤和代码示例

首先把强制解包换成安全的可选绑定,先确认URL存在再初始化播放器:

let myitem = mySongs[0]
// 用guard let安全校验URL是否存在,避免nil崩溃
guard let myURL = myitem.value(forProperty: MPMediaItemPropertyAssetURL) as? URL else {
    // 这里处理URL为空的情况:提示用户歌曲无法播放,或者跳过该条目
    print("当前歌曲无法获取播放地址,可能是云端歌曲或受DRM保护")
    return
}

do {
    avAudioPlayer = try AVAudioPlayer(contentsOf: myURL)
    avAudioPlayer.delegate = self
    avAudioPlayer.prepareToPlay() // 别忘了提前准备播放,优化启动速度
} catch {
    // 捕获播放器初始化错误,比如文件损坏等情况
    print("播放器初始化失败:\(error.localizedDescription)")
}

额外优化建议

  • 提前过滤可播放歌曲:在把歌曲存入mySongs数组前,先筛选出有有效AssetURL的条目,减少后续异常处理:
    // 示例:构建媒体查询时过滤本地可播放歌曲
    let songQuery = MPMediaQuery.songs()
    // 先排除云端歌曲
    let nonCloudPredicate = MPMediaPropertyPredicate(value: true, forProperty: MPMediaItemPropertyIsCloudItem, comparisonType: .notEqualTo)
    songQuery.addFilterPredicate(nonCloudPredicate)
    // 再筛选有AssetURL的条目
    let playableSongs = songQuery.items?.filter { $0.value(forProperty: MPMediaItemPropertyAssetURL) != nil } ?? []
    
  • 处理DRM内容:如果是Apple Music订阅的受保护歌曲,即使拿到URL也无法用AVAudioPlayer播放,这种情况可以考虑用AVPlayer替代,它支持播放受DRM保护的流媒体内容。

内容的提问来源于stack exchange,提问作者Jordan Heath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:51:27