我怎么能让背景音乐继续播放,而我的应用程序仍然在使用Swift播放它的声音

我创build了一个应用程序,我试图让用户在玩我的游戏的同时继续听音乐,但每当他们点击“播放”,游戏就会停止播放背景音乐。 我正在使用Swift在iOS上开发。 这是一段启动游戏声音的代码。

func playSpawnedDot() { var alertSound: NSURL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("spawnDot", ofType: "mp3")!)! var error:NSError? audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error) audioPlayer.prepareToPlay() if volumeBool { audioPlayer.play() } } 

您需要设置AVAudioSession类别,使用以下值之一: https : //developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html (AVAudioSession类参考)。

默认值设置为AVAudioSessionCategorySoloAmbient 。 你可以阅读:

[…]使用这个类别意味着你的应用程序的audio是不可混合的 – 激活你的会话将中断任何其他audio会话也是不可混合的。 要允许混合,请改用AVAudioSessionCategoryAmbient类别。

在播放声音之前,您必须更改类别。 要做到这一点:

 AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil) AVAudioSession.sharedInstance().setActive(true, error: nil) 

每次播放声音时不需要调用这些行。 你可能只想做一次。

以下是我用于Swift 2.0的内容:

 let sess = AVAudioSession.sharedInstance() if sess.otherAudioPlaying { _ = try? sess.setCategory(AVAudioSessionCategoryAmbient, withOptions: .DuckOthers) _ = try? sess.setActive(true, withOptions: []) } 

请注意,如果您不想降低背景音乐,可以使用[]replace.DuckOthers

这就是我在Swift 3.0中的做法

 var songPlayer : AVAudioPlayer? func SetUpSound() { if let path = Bundle.main.path(forResource: "TestSound", ofType: "wav") { let filePath = NSURL(fileURLWithPath:path) songPlayer = try! AVAudioPlayer.init(contentsOf: filePath as URL) songPlayer?.numberOfLoops = -1 //logic for infinite loop songPlayer?.prepareToPlay() songPlayer?.play() } let audioSession = AVAudioSession.sharedInstance() try!audioSession.setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.duckOthers) //Causes audio from other sessions to be ducked (reduced in volume) while audio from this session plays } 

你可以在这里看到更多的AVAudioSessionCategoryOptions: https : //developer.apple.com/reference/avfoundation/avaudiosessioncategoryoptions

Swift 4版本:

 try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient) try? AVAudioSession.sharedInstance().setActive(true) 

lchamp的解决scheme对我来说是完美的,适用于Objective-C:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil];

**

更新了Swift 3.0

**

我正在播放的声音名称是shatter.wav

 func shatterSound() { if let soundURL = Bundle.main.url(forResource: "shatter", withExtension: "wav") { var mySound: SystemSoundID = 0 AudioServicesCreateSystemSoundID(soundURL as CFURL, &mySound) AudioServicesPlaySystemSound(mySound); } } 

然后,你想要播放声音的地方

 shatterSound() 

如果你想播放一个警报声音:

 public func playSound(withFileName fileName: String) { if let soundUrl = Bundle.main.url(forResource: fileName, withExtension: "wav") { do { try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, with:[.duckOthers]) try AVAudioSession.sharedInstance().setActive(true) var soundId: SystemSoundID = 0 AudioServicesCreateSystemSoundID(soundUrl as CFURL, &soundId) AudioServicesAddSystemSoundCompletion(soundId, nil, nil, { (soundId, clientData) -> Void in AudioServicesDisposeSystemSoundID(soundId) do { // This is to unduck others, make other playing sounds go back up in volume try AVAudioSession.sharedInstance().setActive(false) } catch { DDLogWarn("Failed to set AVAudioSession to inactive. error=\(error)") } }, nil) AudioServicesPlaySystemSound(soundId) } catch { DDLogWarn("Failed to create audio player. soundUrl=\(soundUrl) error=\(error)") } } else { DDLogWarn("Sound file not found in app bundle. fileName=\(fileName)") } } 

如果你想播放音乐:

导入AVFoundation

 var audioPlayer:AVAudioPlayer? public func playSound(withFileName fileName: String) { if let soundUrl = Bundle.main.url(forResource: fileName, withExtension: "wav") { do { try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, with:[.duckOthers]) try AVAudioSession.sharedInstance().setActive(true) let player = try AVAudioPlayer(contentsOf: soundUrl) player.delegate = self player.prepareToPlay() DDLogInfo("Playing sound. soundUrl=\(soundUrl)") player.play() // ensure the player does not get deleted while playing the sound self.audioPlayer = player } catch { DDLogWarn("Failed to create audio player. soundUrl=\(soundUrl) error=\(error)") } } else { DDLogWarn("Sound file not found in app bundle. fileName=\(fileName)") } } func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { self.audioPlayer?.stop() do { // This is to unduck others, make other playing sounds go back up in volume try AVAudioSession.sharedInstance().setActive(false) } catch { DDLogWarn("Failed to set AVAudioSession inactive. error=\(error)") } } 

对于Swift(Objective-C也是这样)

你可以使用这个链接获得最好的答案,如果你没有时间看10分钟,最好的行动是,你只需要在你的AppDelegate中的代码copy didFinishLaunchingWithOptions中的代码,然后select你的project's target然后去Capabilities和最后Background modes检查Audio, AirPlay and Picture in Picture

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. let session = AVAudioSession.sharedInstance() do { try session.setCategory(AVAudioSessionCategoryPlayback) } catch { } }