ios - 为什么 AVPlayer 在后台时不继续播放下一首歌曲?

标签 ios swift avplayer ios9.3

我一直在使用 AVPlayer 从远程源流式传输音乐。我得到 URL,使用一个来创建一个 AVPlayerItem,然后我将其与我的 AVPlayer 实例相关联。我向与播放器相关联的项目添加了一个观察者,以在项目完成播放时进行观察 (AVPlayerItemDidPlayToEndTimeNotification)。当观察者在项目结束时通知我时,我然后创建一个新的 AVPlayerItem 并重新做一遍。这在 iOS 9.2 的前台和后台运行良好。

问题:因为我已经更新到 iOS 9.3,所以这在后台不起作用。相关代码如下:

var portionToBurffer = Double()
var player = AVPlayer()


func prepareAudioPlayer(songNSURL: NSURL, portionOfSongToBuffer: Double){

   self.portionToBuffer = portionOfSongToBuffer

   //create AVPlayerItem
   let createdItem = AVPlayerItem(URL: songNSURL)

   //Associate createdItem with AVPlayer
   player = AVPlayer(playerItem: createdItem)

   //Add item end observer
   NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerItemDidReachEnd:", name: AVPlayerItemDidPlayToEndTimeNotification, object: player.currentItem)

   //Use KVO to see how much is loaded
   player.currentItem?.addObserver(self, forKeyPath: "loadedTimeRanges", options: .New, context: nil)

}


override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == "loadedTimeRanges" {
    if let loadedRangeAsNSValueArray = player.currentItem?.loadedTimeRanges {
        let loadedRangeAsCMTimeRange = loadedRangeAsNSValueArray[0].CMTimeRangeValue
        let endPointLoaded = CMTimeRangeGetEnd(loadedRangeAsCMTimeRange)
        let secondsLoaded = CMTimeGetSeconds(endPointLoaded)
        print("the endPointLoaded is \(secondsLoaded) and the duration is \(CMTimeGetSeconds((player.currentItem?.duration)!))")


        if secondsLoaded >= portionToBuffer  {
            player.currentItem?.removeObserver(self, forKeyPath: "loadedTimeRanges")
            player.play()
        }
    }
}
}



 func playerItemDidReachEnd(notification: NSNotification){
     recievedItemEndNotification()
 }





func recievedItemEndNotification() {
   //register background task
   bgTasker.registerBackgroundTask()

   if session.playlistSongIndex == session.playlistSongTitles.count-1 {
       session.playlistSongIndex = 0
   } else {
       session.playlistSongIndex += 1
   }

     prepareAudioPlayer(songURL: session.songURLs[session.playlistSongIndex], portionOfSongToBuffer: 30.00)

  }

我设置了断点以查看 player.play() 在后台被调用。当我打印 player.rate 时,它显示为 0.0。我检查了 AVPlayerItem 的属性 playbackLikelyToKeepUp,它是 true。我还确认新 URL 已成功用于创建新 AVPlayerItem 并在应用程序处于后台时与 AVPlayer 相关联。我已经打开音频和 airplay 后台功能,甚至打开了一个有限长度的后台任务(在上面的代码中为 bgTasker.registerBackgroundTask)。不知道发生了什么。

我找到了 THIS但我不确定它是否有帮助。任何建议都很好,谢谢

最佳答案

When the observer notifies me at the item end, I then create a new AVPlayerItem and do it all over again

但问题是同时播放停止,规则是后台播放只有在你在前台播放并继续在后台播放时才允许。

我建议使用 AVQueuePlayer 而不是 AVPlayer。这将允许您在当前项目仍在播放时将下一个项目加入队列——因此,我们可能希望,这将被视为继续播放。

关于ios - 为什么 AVPlayer 在后台时不继续播放下一首歌曲?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36348332/

相关文章:

swift - 如何以编程方式更改搜索栏宽度? ( swift )

ios - 未调用 Alamofire 完成处理程序

cocoa - NSTextField GotFocus 事件 Cocoa Swift

ios - AVPlayer 和 AVAudioPlayer 不播放 URL 中的音频

ios - Objective-C 中 NSString 的 pretty-print XML

ios - 检测 iOS 10.3 应用评级对话框显示的机制?

ios - 将 UITableView 行从一个 tableviewController 发送到另一个

iphone - UITextView 文本颜色自动变得与背景颜色相同

ios - 两个 AVPlayer 视频不同步(Swift)

ios - AVPlayer 不播放,图层不显示