iOS:如何在后台播放声音

3

当用户关闭应用时,我需要开始播放声音。我使用 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(player: AVAudioPlayer!, successfully flag: 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()返回false。如果我例如在applicationDidFinishLaunching中运行此代码,它会播放声音。我在Info.plist中添加了后台模式App plays audio or streams audio/video using AirPlay。这里出了什么问题?


你需要一个 UIBackgroundTaskIdentifier。 - Woodstock
好的,请举个例子。 - Nikita Zernov
请看我的更新答案,附有Swift示例。 - Woodstock
@Woodstock 这段代码来自那里。 - Nikita Zernov
1个回答

3

在非常基本的层面上,您的应用程序要在后台播放音频需要满足以下三个先决条件:

  • 音乐必须正在播放
  • 为音频设置“后台模式”以实现目标功能。

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

您还应该配置您的应用程序以响应以下内容

  • 音频输出的更改
  • 音频会话中断(例如电话呼叫)
  • 远程控制事件(通过控制中心或锁定屏幕)

请查看this Swift示例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接