iOS: 从后台开始播放声音

iOS: Start playing sound from background

我需要在用户关闭应用程序时开始播放声音。我使用 applicationDidEnterBackground 方法。在这里:

func applicationDidEnterBackground(application: UIApplication) {
    let dispatchQueue =
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

    dispatch_async(dispatchQueue, {[weak self] in

        var audioSessionError: NSError?
        let audioSession = AVAudioSession.sharedInstance()
        NSNotificationCenter.defaultCenter().addObserver(self!,
            selector: "handleInterruption:",
            name: AVAudioSessionInterruptionNotification,
            object: nil)

        audioSession.setActive(true, error: nil)

        if audioSession.setCategory(AVAudioSessionCategoryPlayback,
            error: &audioSessionError){
                println("Successfully set the audio session")
        } else {
            println("Could not set the audio session")
        }

        let filePath = NSBundle.mainBundle().pathForResource("MySong",
            ofType:"mp3")

        let fileData = NSData(contentsOfFile: filePath!,
            options: .DataReadingMappedIfSafe,
            error: nil)

        var error:NSError?

        /* Start the audio player */
        self!.audioPlayer = AVAudioPlayer(data: fileData, error: &error)

        /* Did we get an instance of AVAudioPlayer? */
        if let theAudioPlayer = self!.audioPlayer{
            theAudioPlayer.delegate = self;
            if theAudioPlayer.prepareToPlay() &&
                theAudioPlayer.play(){
                    println("Successfully started playing")
            } else {
                println("Failed to play")
            }
        } else {
            /* Handle the failure of instantiating the audio player */
        }
        })

}
func handleInterruption(notification: NSNotification){
/* Audio Session is interrupted. The player will be paused here */

let interruptionTypeAsObject =
notification.userInfo![AVAudioSessionInterruptionTypeKey] as! NSNumber

let interruptionType = AVAudioSessionInterruptionType(rawValue:
  interruptionTypeAsObject.unsignedLongValue)

if let type = interruptionType{
  if type == .Ended{

    /* resume the audio if needed */

  }
}

}

func audioPlayerDidFinishPlaying(播放器: AVAudioPlayer!, 成功标记:Bool){

  println("Finished playing the song")

  /* The flag parameter tells us if the playback was successfully
  finished or not */
  if player == audioPlayer{
    audioPlayer = nil
  }
  }

它不起作用。调试后我看到 theAudioPlayer.play() returns false。例如,如果我 运行 此代码在 applicationDidFinishLaunching 中播放声音。我在 Info.plist 中添加了背景模式 App plays audio or streams audio/video using AirPlay 这里有什么问题?

在最基本的层面上,您的应用应满足三个先决条件才能在后台播放音频:

  • 必须正在播放音乐
  • 在目标功能中为音频设置“背景模式”。

  • 对于基本播放,初始化您的音频会话,并将您的音频会话类别设置为 AVAudioSessionCategoryPlayback。如果不这样做,您将获得默认行为。

您还应该配置您的应用以响应

  • 音频输出的变化
  • 音频会话中断(例如 phone 通话)
  • 远程控制事件(通过控制中心或锁屏)

查看 this Swift 示例。