2015-09-13 14 views
7

Sto imparando Swift come il mio primo linguaggio di programmazione.Come riprendere l'audio di sottofondo in Swift 2/AVPlayer?

ho lottato per molte ore per curriculum sfondo riproduzione audio dopo un'interruzione (ad esempio chiamata)

Cosa dovrebbe accadere:

  1. Audio continua a suonare quando applicazione va a sfondo (opere)
  2. Quando interrotto da una chiamata, ottenere la notifica di interruzione iniziata (opere)
  3. Quando chiamata termina, ottenere la notifica di interruzione estremità (opere)
  4. riprendere la riproduzione dell'audio (non funziona - sentire niente)

davvero apprezzare alcun aiuto! Grazie

Note:

  1. L'applicazione è registrata per audio di sottofondo e svolge bene prima dell'interruzione
  2. Ho provato con e senza il tempo di ritardo per riprendere la riproduzione - né lavorare

Codice:

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") 
    } 
} 
+0

Vuol metodi sono chiamati in modo corretto? in particolare il metodo resumeNow. –

+0

Sì - Vedo il registro che mostra "tentativo riavviato" 3 secondi dopo che la chiamata è terminata. –

risposta

4

Finalmente capito!

Soluzione: ha aggiunto l'opzione miscelabili cambiando la riga setCategory essere:.

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

1

Ho scritto un codice come questo e ho ripreso con successo l'audio della telefonata terminata. Sono stato costruito su Xcode 6.4 e ho eseguito l'app sul mio 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") 
} 
+0

Provato, ma non sembra fare nulla. L'audio continua a non essere riprodotto. –

+0

Dove hai messo il codice? –

+0

in entrambi: case. Fine e in riassunto, appena prima di player.play() sei riuscito a farlo funzionare? –

-1

Simon, assolutamente confermarlo sulla mia estremità . Trascorro 2 giorni a cercarlo! Se si utilizza solo:

AVAudioSession.sharedInstance() setCategory (AVAudioSessionCategoryPlayback) allora non importa quello che fai il tuo giocatore non riprenderà la riproduzione audio se si utilizza invece:..

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

quindi funziona come perfetto e riprenderà dopo aver ricevuto una chiamata mentre l'app è in background.

Grazie!

+0

Simon, non sono sicuro se l'hai notato ma questa non è la soluzione funzionante. Pensavo che la soluzione funzionasse ma quando usi: AVAudioSession.sharedInstance(). SetCategory (AVAudioSessionCategoryPlayback, withO ptions: AVAudioSessionCategoryOptions.MixWithOthers quindi il tuo lettore si mescolerà con gli altri. Prova anche l'app di musica staring allo stesso tempo. Riceverai 2 suoni contemporaneamente e mixando. Funziona per riprendere dopo la chiamata mentre è in background ma rovina l'intera riproduzione del suono. Qualche idea per favore? – awindsurfer

+0

La cosa che ci mancava era self.becomeFirstResponder() una volta aggiunta l'intera cosa ha iniziato a funzionare per me. – awindsurfer

+0

Buono a sapersi, grazie. Non ne ho bisogno perché la mia app è un'app di meditazione silenziosa e non mischiano loro stessi l'audio, quindi non hanno testato questa opzione. –

0

Per me ricaricare il giocatore dopo l'interruzione fine di risolvere il 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() 
    } 
    } 
Problemi correlati