¿Cómo reanudar el audio de background en Swift 2 / AVPlayer?

Estoy aprendiendo a Swift como mi primer lenguaje de progtwigción.

He luchado durante muchas horas para reanudar la reproducción de audio en segundo plano después de la interrupción (por ejemplo, llamada)

Qué debería pasar:

  1. El audio sigue reproduciéndose cuando la aplicación pasa al background (funciona)
  2. Cuando se interrumpe por una llamada, se inicia la notificación de interrupción (funciona)
  3. Cuando finaliza la llamada, recibe la notificación de finalización de la interrupción (funciona)
  4. Reanude la reproducción del audio ( NO funciona, no oye nada )

¡Realmente aprecio cualquier ayuda! Gracias

Notas:

  1. La aplicación está registrada para audio de background y se reproduce bien antes de la interrupción
  2. He intentado con y sin retraso para reanudar el juego, ni trabajo

Código:

import UIKit import AVFoundation var player: AVQueuePlayer! class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() do { try AVAudioSession.shanetworkingInstance().setCategory(AVAudioSessionCategoryPlayback) try AVAudioSession.shanetworkingInstance().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.shanetworkingInstance() 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") } } 

¡Finalmente lo tengo!

Solución: agregó la opción de mezcla cambiando la línea setCategory para que sea:

AVAudioSession.shanetworkingInstance (). SetCategory (AVAudioSessionCategoryPlayback, withOptions: AVAudioSessionCategoryOptions.MixWithOthers)

Escribí un código como este y reanudé con éxito el audio de la llamada telefónica finalizada. Estaba basado en Xcode 6.4 y ejecuté la aplicación en mi 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.shanetworkingInstance() 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") } 

Para mí, volver a cargar el reproductor después de la interrupción final, resuelve el problema:

  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() } } 

Simon, confirma absolutamente en mi final. ¡Pasé 2 días buscándolo! Si usa solo:

AVAudioSession.shanetworkingInstance (). SetCategory (AVAudioSessionCategoryPlayback) entonces no importa lo que hagas tu reproductor no reanudará la reproducción de audio si utilizas:

AVAudioSession.shanetworkingInstance (). SetCategory (AVAudioSessionCategoryPlayback, withOptions: AVAudioSessionCategoryOptions.MixWithOthers)

entonces funciona como perfecto y se reanudará después de recibir la llamada mientras la aplicación está en segundo plano.

¡Gracias!