如何在Swift 2 / AVPlayer中恢复背景audio?

我正在学习Swift作为我的第一个编程语言。

我努力了好几个小时才能恢复中断后的后台audio播放 (如通话)

应该发生什么:

  1. audio继续播放时,应用程序去背景(作品)
  2. 当被打电话中断时,得到中断通知开始(工作)
  3. 当通话结束时,获取中断通知(工作)
  4. 继续播放audio( 不工作 – 听不到

真的很感谢任何帮助! 谢谢

笔记:

  1. 该应用程序已注册后台audio,播放罚款之前中断
  2. 我尝试过,没有时间延迟来重新开始游戏,但都没有成功

码:

import UIKit import AVFoundation var player: AVQueuePlayer! class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() do { try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback) try AVAudioSession.sharedInstance().setActive(true, withOptions: .NotifyOthersOnDeactivation) } catch { } let songNames = ["music"] let songs = songNames.map { AVPlayerItem(URL: NSBundle.mainBundle().URLForResource($0, withExtension: "mp3")!) } player = AVQueuePlayer(items: songs) let theSession = AVAudioSession.sharedInstance() NSNotificationCenter.defaultCenter().addObserver(self, selector:"playInterrupt:", name:AVAudioSessionInterruptionNotification, object: theSession) player.play() } func playInterrupt(notification: NSNotification) { if notification.name == AVAudioSessionInterruptionNotification && notification.userInfo != nil { var info = notification.userInfo! var intValue: UInt = 0 (info[AVAudioSessionInterruptionTypeKey] as! NSValue).getValue(&intValue) if let type = AVAudioSessionInterruptionType(rawValue: intValue) { switch type { case .Began: print("aaaaarrrrgggg you stole me") player.pause() case .Ended: let timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: "resumeNow:", userInfo: nil, repeats: false) } } } } func resumeNow(timer : NSTimer) { player.play() print("attempted restart") } } 

终于明白了!

解决scheme:通过将setCategory行更改为添加可混合选项:

AVAudioSession.sharedInstance()。setCategory(AVAudioSessionCategoryPlayback,withOptions:AVAudioSessionCategoryOptions.MixWithOthers)

我写了这样的代码,并成功地恢复了电话的audio结束。 我是build立在Xcode 6.4上,并在我的iPhone 4S上运行应用程序。

 var player: AVQueuePlayer! = nil override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } override func viewDidAppear(animated: Bool) { super.viewDidAppear(true) var song = AVPlayerItem(URL: NSBundle.mainBundle().URLForResource("AlmostAYearAgo", withExtension: "mp3")!) player = AVQueuePlayer(items: [song]) let theSession = AVAudioSession.sharedInstance() NSNotificationCenter.defaultCenter().addObserver(self, selector: "playInterrupt:", name: AVAudioSessionInterruptionNotification, object: theSession) player.play() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func playInterrupt(notification: NSNotification) { if notification.name == AVAudioSessionInterruptionNotification && notification.userInfo != nil { var info = notification.userInfo! var intValue: UInt = 0 (info[AVAudioSessionInterruptionTypeKey] as! NSValue).getValue(&intValue) if let type = AVAudioSessionInterruptionType(rawValue: intValue) { switch type { case .Began: print("aaaaarrrrgggg you stole me") player.pause() case .Ended: let timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: "resumeNow:", userInfo: nil, repeats: false) } } } } func resumeNow(timer : NSTimer) { player.play() print("attempted restart") } 

结束中断后重新加载播放器解决问题:

  func interruptionNotification(_ notification: Notification) { guard let type = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt, let interruption = AVAudioSessionInterruptionType(rawValue: type) else { return } if interruption == .ended && playerWasPlayingBeforeInterruption { player.replaceCurrentItem(with: AVPlayerItem(url: radioStation.url)) play() } } 

西蒙,绝对确认我的结局。 我花了两天的时间寻找它! 如果你只使用:

AVAudioSession.sharedInstance()。setCategory(AVAudioSessionCategoryPlayback)然后不重要你做什么你的播放器将不会恢复播放audio,如果你使用:

AVAudioSession.sharedInstance()。setCategory(AVAudioSessionCategoryPlayback,withOptions:AVAudioSessionCategoryOptions.MixWithOthers)

那么它就像完美的工作,并会在应用程序在后台接到电话后恢复。

谢谢!