我怎么能让背景音乐继续播放,而我的应用程序仍然在使用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 { } }