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

时间:2015-09-13 09:29:15

标签: ios swift audio avfoundation avplayer

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

我在中断后(例如通话)恢复背景音频播放已经挣了好几个小时

会发生什么:

  1. 当应用程序转到后台(工作)时,音频会继续播放
  2. 当被通话中断时,开始通知中断 (作品)
  3. 通话结束时,获取中断通知 结束(工作)
  4. 继续播放音频(无效 - 听不见
  5. 真的很感激任何帮助!感谢

    备注:

    1. 该应用已注册背景音频,并且在中断前播放正常
    2. 我已经尝试过,没有时间延迟恢复播放 - 两种方式都没有工作
    3. 代码:

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

5 个答案:

答案 0 :(得分:4)

终于搞定了!

解决方案:通过将setCategory行更改为:

添加了mixable选项
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback,
                                            withOptions: .mixWithOthers )

答案 1 :(得分:1)

我写了这样的代码并成功恢复了通话结束后的音频。我建立在Xcode 6.4上并在我的iPhone 4S上运行应用程序。

{{1}}

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

对我来说,这增加了解决问题的延迟时间:

@objc func handleInterruption(_ notification: Notification) {
    // audio interuption - restart audio player for any type (began or ended) to make sure it keeps going
    guard let type = notification.userInfo?[AVAudioSessionInterruptionTypeKey] as? UInt,
        let interruption = AVAudioSession.InterruptionType(rawValue: type) else {
            NSLog("*** Incorrect notification format")
            return
    }

    if interruption == .began {
        NSLog("audio interruption: began")
    } else if interruption == .ended {
        NSLog("audio interruption: ended")
        if isRunning {
            // Sadly this lengthy delay hack is necessary, otherwise sounds won't play :(
            DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
                self.start() // sets up the audio session, connects nodes, starts the engine, plays the player, and sets isRunning to true
            }
        }
    }
}

延迟确实需要这么长。 2s不能解决问题。

答案 4 :(得分:-1)

西蒙,绝对在我的身上证实了这一点。我花了2天时间寻找它!如果您只使用:

AVAudioSession.sharedInstance()。setCategory(AVAudioSessionCategoryPlayback)然后无论你做什么,如果你改用你的播放器都不会恢​​复播放音频:

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

然后它就像完美一样,在应用程序处于后台时接到电话后会恢复。

谢谢!