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
相关产品推荐
相关产品推荐

