2015-09-13 8 views
7

Ich lerne Swift als meine erste Programmiersprache.Wie kann ich Hintergrundmusik in Swift 2/AVPlayer fortsetzen?

Ich habe viele Stunden Lebenslauf Hintergrund Audio-Wiedergabe nach einer Unterbrechung (zB Call) kämpfte

Was soll passieren:

  1. Audio spielen hält, wenn App Hintergrund geht (Werke)
  2. Wenn durch einen Anruf unterbrochen, erhalten Sie die Benachrichtigung für die Unterbrechung begann (funktioniert)
  3. Wenn Anruf beendet, erhält die Benachrichtigung für die Unterbrechung Ende (Werke)
  4. Fortsetzen der Audio-Wiedergabe (funktioniert NICHT - nichts hören)

wirklich zu schätzen jede Hilfe! Dank

Hinweise:

  1. Die App für Hintergrund-Audio registriert ist, und spielt fein vor der Unterbrechung
  2. Ich habe versucht, mit und ohne Zeitverzögerung Wiedergabe fortzufahren - weder arbeiten

Code:

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

Hat werden die Methoden richtig genannt? vor allem die resumeNow-Methode. –

+0

Ja - Ich sehe das Protokoll 3 Sekunden nach Beendigung des Anrufs "Versuch eines Neustarts". –

Antwort

4

Endlich geschafft!

Lösung: hinzugefügt, um die mischbare Option durch die setCategory Linie zu ändern sein.

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

1

Ich schrieb einen Code wie folgt und nahm erfolgreich das Audio vom Telefonanruf beendet auf. Ich wurde auf Xcode 6.4 gebaut und führte die App auf meinem 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

Versuchte es, aber scheint nichts zu tun. Audio wird weiterhin nicht abgespielt. –

+0

Wo hast du den Code abgelegt? –

+0

in beiden: Fall .Ented und in resumeNow kurz bevor player.play() haben Sie es geschafft, es funktioniert zu bekommen? –

-1

Simon, absolut bestätigen es auf meinem Ende . Ich verbringe 2 Tage damit, es zu suchen! Wenn Sie nur:

AVAudioSession.sharedInstance() setCategory (AVAudioSessionCategoryPlayback), dann spielt es keine Rolle, was Sie tun, um Ihre Spieler Abspielen von Audio nicht wieder aufnehmen, wenn Sie statt:..

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

dann funktioniert es wie perfekt und wird nach dem Empfangen des Anrufs fortgesetzt, während die App im Hintergrund ist.

Danke!

+0

Simon, nicht sicher, ob Sie bemerkt haben, aber das ist nicht die funktionierende Lösung.Ich dachte, die Lösung funktionierte, aber wenn Sie verwenden: 0 AVAudioSession.SharedInstance(). SetCategory (AVAudioSessionCategoryPlayback, withO Ptionen: AVAudioSessionCategoryOptions.MixWithOthers dann wird Ihr Player mit anderen mischen. Versuchen Sie auch Musik-App in der gleichen Zeit zu starren. Sie werden 2 Sounds gleichzeitig spielen und mischen. Es funktioniert nach dem Anruf im Hintergrund weiter, aber es vermasselt die gesamte Wiedergabe Ihres Sounds. Irgendeine Idee bitte? – awindsurfer

+0

Das Ding, das wir vermissten, war self.becomeFirstResponder() sobald das hinzugefügt wurde, fing die ganze Sache an, für mich zu arbeiten. – awindsurfer

+0

Gut zu wissen, danke. Ich brauche es nicht, weil meine App eine stille Meditations-App ist und sie Audio nicht selbst mischen werden, also habe ich diese Option nicht getestet. –

0

Für mich Spieler nach Ende Unterbrechung nachladen beheben das 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() 
    } 
    }