2015-09-13 18 views
7

Uczę się Swift jako mojego pierwszego języka programowania.Jak wznowić dźwięk w tle w Swift 2/AVPlayer?

Mam walczyli przez wiele godzin wznawiania odtwarzania dźwięku tła po przerwie (np rozmowy)

Co powinno się wydarzyć:

  1. dźwięku utrzymuje odtwarzanie gdy aplikacja przechodzi do tła (prace)
  2. Po przerwaniu połączenia otrzymasz powiadomienie o przerwaniu połączenia (działa)
  3. Gdy rozmowa się kończy, otrzymasz powiadomienie o przerwaniu końce (prac)
  4. wznowić odtwarzanie audio (NIE działa - słychać nic)

naprawdę wdzięczni za każdą pomoc! Dzięki

Uwagi:

  1. Aplikacja jest zarejestrowany na tle dźwięku i gra dobrze przed przerw
  2. próbowałem i bez zwłoki czasowej, aby wznowić odtwarzanie - ani pracować

Kod:

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

Czy metody są właściwie nazywa? szczególnie metoda resumeNow. –

+0

Tak - widzę dziennik pokazujący "próbę restartu" 3 sekundy po zakończeniu połączenia. –

Odpowiedz

4

Nareszcie!

Rozwiązanie: dodano opcję mieszający zmieniając setCategory linię być.

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

1

Napisałem taki kod i pomyślnie wznowiono dźwięk z połączenia zakończonego. Byłem zbudowany na Xcode 6.4 i uruchomiłem aplikację na moim 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

Próbowałem, ale nie wydaje się nic. Dźwięk nadal nie jest odtwarzany po wznowieniu. –

+0

Gdzie umieściłeś kod? –

+0

w obu: case. Zakończone i wznowioneNie tuż przed player.play() czy udało Ci się sprawić, że działa? –

-1

Simon, absolutnie potwierdzić je na mojej stronie . Spędzam 2 dni na szukaniu! Jeśli używasz tylko:

AVAudioSession.sharedInstance() setCategory (AVAudioSessionCategoryPlayback) wtedy nie ma znaczenia co robisz, odtwarzacz nie będzie wznowić odtwarzanie dźwięku jeśli używasz zamiast:..

AVAudioSession.sharedInstance() setCategory (AVAudioSessionCategoryOdtwarzanie, z opcjami: AVAudioSessionCategoryOptions.MixWithInne)

to działa jak idealne i zostanie wznowione po otrzymaniu połączenia telefonicznego, gdy aplikacja jest w tle.

Dzięki!

+0

Simon, nie jestem pewien, czy zauważyłeś, ale to nie działa rozwiązanie.Myślę, że rozwiązanie działa, ale przy użyciu: AVAudioSession.sharedInstance(). SetCategory (AVAudioSessionCategoryPlayback, withO ptions: AVAudioSessionCategoryOptions.MixWithOthers , a następnie twój odtwarzacz będzie mieszał się z innymi. Spróbuj jednocześnie oglądać aplikację muzyczną. Otrzymasz 2 dźwięki grające jednocześnie i miksujące. Działa po wznowieniu połączenia w tle, ale zakłóca odtwarzanie dźwięku. Czy ktoś ma jakiś pomysł? – awindsurfer

+0

Rzecz, której nam brakowało, to self.becomeFirstResponder(), gdy tylko została dodana, wszystko zaczęło działać dla mnie. – awindsurfer

+0

Dobrze wiedzieć, dzięki. Nie potrzebuję tego, ponieważ moja aplikacja to cicha aplikacja do medytacji i nie będą same miksować dźwięku, więc nie przetestowałem tej opcji. –

0

Dla mnie przeładować odtwarzacz Po przerwaniu końcowego rozwiązać problem:

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