为什么AVPlayer在后台不能继续播放下一首歌? [英] Why is AVPlayer not continuing to next song while in background?

查看:144
本文介绍了为什么AVPlayer在后台不能继续播放下一首歌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用AVPlayer从远程源播放音乐。我获取URL,使用一个来创建一个AVPlayerItem,然后我将其与我的AVPlayer实例关联。我将一个观察者添加到我与玩家关联的项目中,以观察项目何时完成播放( AVPlayerItemDidPlayToEndTimeNotification )。当观察者在项目结束时通知我时,我然后创建一个新的AVPlayerItem并重新执行它。这在iOS 9.2的前台和后台运行良好。

I have been streaming music from remote source using AVPlayer. I get URLs, use one to create an AVPlayerItem, which i then associate with my instance of AVPlayer. I add an observer to the item that I associate with the player to observe when the item finishes playing ( AVPlayerItemDidPlayToEndTimeNotification ). When the observer notifies me at the item end, I then create a new AVPlayerItem and do it all over again. This works well in the foreground AND in the background on iOS 9.2.

问题:由于我已更新到iOS 9.3,因此无法在后台运行。以下是相关代码:

Problem: Since I have updated to iOS 9.3 this does not work in the background. Here is the relevant code:

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关联。我已经打开了音频和播放背景功能,我甚至打开了一个有限长度的后台任务(在上面的代码中为 bgTasker.registerBackgroundTask )。不知道发生了什么。

I have set breakpoints to see that player.play() IS being called when in the background. When i print player.rate it reads 0.0. I have checked the property playbackLikelyToKeepUp of the AVPlayerItem and it is true. I have confirmed also that the new URL is successfully used to create the new AVPlayerItem and associated with the AVPlayer when the app is in the background. I have turned audio and airplay background capabilities on and I have even opened up a finite length background task (in code above as bgTasker.registerBackgroundTask). No idea what is going on.

我发现这个但我不确定它有帮助。任何建议都会很棒,谢谢

I found THIS but i'm not sure it helps. Any advice would be great, thanks

推荐答案


当观察者在项目结束时通知我时,我然后创建一个新的AVPlayerItem并重新执行

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

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

But the problem is that meanwhile play stops, and the rule is that background playing is permitted only so long as you were playing in the foreground and continue to play in the background.

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

I would suggest using AVQueuePlayer instead of AVPlayer. This will allow you to enqueue the next item while the current item is still playing — and thus, we may hope, this will count as continuing to play.

这篇关于为什么AVPlayer在后台不能继续播放下一首歌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆