【问题标题】:Rearrange MediaPlayer Music Queue [iOS]重新排列 MediaPlayer 音乐队列 [iOS]
【发布时间】:2019-01-13 22:54:22
【问题描述】:

我真的很难弄清楚一些事情,我已经在整个互联网上寻找了答案,但我找不到答案。如您所知,Spotify 和 Apple Music 等音乐应用程序本身可以让用户重新排列下一个队列,即使用户正在听一首歌。我一直无法弄清楚如何做同样的事情。我希望能够完全重新排列队列,包括在下一个队列中添加、删除和移动歌曲。我尝试了各种方法,例如

musicPlayer.setQueue([queue])

但这需要我调用musicPlayer.prepareToPlay() afterwords 来更新队列,这将结束当前歌曲并启动新队列。

我也试过

musicPlayer.perform(queueTransaction: { (currentQueue) in
    let oldItems = currentQueue.items

    var currentItem: MPMediaItem? = nil
    for (i, item) in oldItems.enumerated() {
        if i == musicPlayer.indexOfNowPlayingItem {
            currentItem = item
            continue
        }

        currentQueue.remove(item)
    }

    currentQueue.insert(queue, after: currentItem)
}, completionHandler: { (newQueue, error) in
    if let error = error {
        print("there was an error updating the queue", error)
        return
    }

    print("===  NEW QUEUE  ===")  //insert does not work
    for item in newQueue.items {
        print("  -", item.title ?? "[No Title]")
    }
})

但是您可能从这个问题中知道: MPMusicPlayerControllerMutableQueue insert an Apple Music song not working

队列的在项目后插入功能似乎不起作用(我还尝试将项目设置为 nil,这有时会删除当前项目并将队列设置为空)。我也知道musicPlayer.prepend([queue]),它将在当前播放项目之后添加新队列,但我还必须从内存中删除前一个队列,这样下一个队列最终不会超过 300 首歌曲。我也尝试在队列事务中使用prepend 函数,但有时歌曲会在中间停止,音乐播放器会将nowPlayingItem 设置为零。我真的希望有人知道这个问题的答案,因为我已经遇到这个问题超过 4 天了,我似乎无法找到一个 100% 有效的解决方案。

【问题讨论】:

    标签: ios swift mpmusicplayercontroller


    【解决方案1】:

    MPMusicPlayerController(及其相关子类)使得无缝管理这样的队列变得非常困难。如果我没记错的话,您甚至无法将重复的 MPMediaItem 对象添加到队列中,从控制中心点击正在播放的媒体实际上会启动音乐应用程序而不是您自己的应用程序。从本质上讲,您的应用只能充当音乐播放体验的外壳,而音乐应用正在完成所有繁重的工作。

    根据您的要求,您可能还有其他选择,尽管有一些妥协。 AVFoundation 框架提供 AVPlayerAVQueuePlayer,它们可以更轻松地管理队列并提供更高级的播放选项。但是,您只能播放下载的、无 DRM 的内容(即来自 Apple Music 的歌曲将无法播放)。

    设置播放器:

    let audioPlayer = AVQueuePlayer()
    
    // Play next song in queue.
    NotificationCenter.default.addObserver(self, selector: #selector(didPlayToEndTime), name: .AVPlayerItemDidPlayToEndTime, object: nil)
    
    // Recover from failed playback.
    NotificationCenter.default.addObserver(self, selector: #selector(failedToPlayToEndTime(_:)), name: .AVPlayerItemFailedToPlayToEndTime, object: nil)
    
    // Resume music after interruptions.
    NotificationCenter.default.addObserver(self, selector: #selector(handleAudioSessionInterruption(_:)), name: .AVAudioSessionInterruption, object: AVAudioSession.sharedInstance())
    

    在队列中插入新项目:

    let media = MPMediaQuery.songs()
    let mediaItem: MPMediaItem = media.items.first!
    
    // MPMediaItem objects stored in iCloud or from Apple Music
    // will not have a URL, therefore, they cannot be played.
    guard let assetURL: URL = mediaItem.assetURL else { return }
    
    let playerItem = AVPlayerItem(url: assetURL)
    playerItem.seek(to: kCMTimeZero)
    audioPlayer.insert(playerItem, after: nil)
    

    在我的音乐播放器应用程序中,我保留了一个 Array 的媒体以使重新排序、插入和删除媒体变得非常简单,以及一个用于跟踪当前播放曲目的索引。然后我一次将媒体传递到AVQueuePlayer 一个或两个,这样我就不必弄乱它的 API 来插入/删除媒体。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-24
      • 2021-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-02
      • 2021-02-21
      • 2023-03-23
      相关资源
      最近更新 更多