使用 AVFoundation 播放 IOS 音乐库内容

Play IOS Music Library Content Using AVFoundation

我正在尝试编写一个 IOS 应用程序来播放我的 iPhone 音乐库内容,显示艺术作品以及 "announcing" 标题、艺术家等

我使用 Apple 的 Media Player 框架让它工作得很好。我可以显示播放列表名称和 queue 所选播放列表中的歌曲。 我使用 "MPMusicPlayerControllerNowPlayingItemDidChange" 观察者通知来暂停播放、检索元数据并通过 AVSpeechSynthesizer 进行通知。 在我 运行 陷入可怕的 "Media Player framwork doesn't respond to observer notifications in background" 问题之前,我是一个快乐的露营者。

所以,我开始研究 AVFoundation 框架。我找到了一个示例,它在后台通过 URL 播放本地歌曲文件。 我在尝试通过 AVFoundation 检索音乐库内容时失败得很惨。 我也未能将通过 Media Player 框架检索到的内容提供给 AVFoundation 播放器。 (注意:从 MPMediaItem 检索到的 URL 是伪造的“ipod-library://item/item.m4a?id=############### ##########”格式。使用此 "URL" 创建 AVPlayerItem 无效。)

有没有人设法做到这一点?我正在为自己的使用而开发。我无意在 Apple 的 App Store 中发布该应用程序,因此我愿意使用隐藏的 API 或 un-Apple 批准的方法。

一个 Swift 代码示例会很棒。 (Objective-C没那么多)

从用户的库中获取 MPMediaItem 后,获取其 assetURL。从生成的 URL 创建 AVPlayer 确实有效。

我的示例应用程序之一的实际代码:

func oneSong () -> (URL?, String?) {
    let query = MPMediaQuery.songs()
    // always need to filter out songs that aren't present
    let isPresent = MPMediaPropertyPredicate(value:false,
        forProperty:MPMediaItemPropertyIsCloudItem,
        comparisonType:.equalTo)
    query.addFilterPredicate(isPresent)
    let item = query.items?[0]
    return (item?.assetURL, item?.title)
}
@IBAction func doPlayOneSongAVPlayer (_ sender: Any) {
    let (url, title) = self.oneSong()
    if let url = url, let title = title {
        self.avplayer = AVPlayer(url:url)
        self.avplayer.play()
        MPNowPlayingInfoCenter.default().nowPlayingInfo = [
            MPMediaItemPropertyTitle : title
        ]
    }
}