ios 如何在我的应用程序在使用 Swift 时仍然播放其声音的同时允许背景音乐继续播放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29024320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I allow background music to continue playing while my app still plays its sounds while using Swift
提问by Nathan Harper
I created an app and I am attempting to allow the user to continue to listen to their music while playing my game, but whenever they hit "play" and the ingame sounds occur it will stop the background music. I am developing on iOS using Swift. Here is a piece of the code that initiates the ingame sounds.
我创建了一个应用程序,我试图让用户在玩我的游戏时继续听他们的音乐,但是每当他们点击“播放”并且游戏中的声音出现时,它就会停止背景音乐。我正在使用 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()
}
}
回答by lchamp
You need to set the AVAudioSession
category, with one of the following value: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html(AVAudioSession Class Reference).
您需要AVAudioSession
使用以下值之一设置类别:https: //developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html(AVAudioSession 类参考)。
The default value is set to AVAudioSessionCategorySoloAmbient
. As you can read :
默认值设置为AVAudioSessionCategorySoloAmbient
。你可以读到:
[...] using this category implies that your app's audio is nonmixable—activating your session will interrupt any other audio sessions which are also nonmixable. To allow mixing, use the
AVAudioSessionCategoryAmbient
category instead.
[...] 使用此类别意味着您的应用程序的音频是不可混合的——激活您的会话将中断任何其他同样不可混合的音频会话。要允许混合,请改用
AVAudioSessionCategoryAmbient
类别。
You have to change the category, before you play your sound. To do so :
在播放声音之前,您必须更改类别。这样做:
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
You don't need to call those line each time you play the sound. You might want to do it only once.
每次播放声音时都不需要调用这些线路。你可能只想做一次。
回答by Milan Nosá?
Swift 4version:
斯威夫特 4版本:
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try? AVAudioSession.sharedInstance().setActive(true)
回答by Setera
This is how I do it in Swift 3.0
这就是我在 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
}
You can see more of AVAudioSessionCategoryOptions here: https://developer.apple.com/reference/avfoundation/avaudiosessioncategoryoptions
您可以在此处查看更多 AVAudioSessionCategoryOptions:https: //developer.apple.com/reference/avfoundation/avaudiosessioncategoryoptions
回答by sameer
Here's what I am using for Swift 2.0:
这是我用于 Swift 2.0 的内容:
let sess = AVAudioSession.sharedInstance()
if sess.otherAudioPlaying {
_ = try? sess.setCategory(AVAudioSessionCategoryAmbient, withOptions: .DuckOthers)
_ = try? sess.setActive(true, withOptions: [])
}
Please note that you can replace .DuckOthers
with []
if you don't want to lower background music and instead play on top to it.
请注意,如果您不想降低背景音乐而是在上面播放.DuckOthers
,[]
则可以替换为。
回答by itnAAnti
lchamp's solution worked perfectly for me, adapted for Objective-C:
lchamp 的解决方案非常适合我,适用于 Objective-C:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
回答by Timmy Sorensen
**
**
Updated for Swift 3.0
为 Swift 3.0 更新
**
**
The name of the sound I am playing is shatter.wav
我正在播放的声音的名称是 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);
}
}
Then where ever you want to play the sound call
然后你想在哪里播放声音电话
shatterSound()
回答by Matt
Since they can't seem to make up their minds from version to version. Here it is in Swift 5.0
因为他们似乎无法从一个版本到另一个版本下定决心。这是 Swift 5.0
do{
try AVAudioSession.sharedInstance().setCategory(.ambient)
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
} catch {
NSLog(error.localizedDescription)
}
回答by Amr
If you want to play an alert sound:
如果您想播放提示音:
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)")
}
}
And if you want to play music:
如果你想播放音乐:
import AVFoundation
导入 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)")
}
}
回答by shor67
For Swift (Objective-C like this too)
对于 Swift(Objective-C 也是这样)
you can use thislink for best answer and if you don't have any time for watching 10 minutes the best action is that you just copy
below code in your AppDelegate
in didFinishLaunchingWithOptions
and then select your project's target
then go to Capabilities
and at last in Background modes
check on Audio, AirPlay and Picture in Picture
你可以使用这个链接,最好的答案,如果你没有任何时间收看10分钟,最好的行动就是你刚才copy
下面的代码在你AppDelegate
的didFinishLaunchingWithOptions
,然后选择你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 {
}
}
回答by Joshua Dance
I didn't think that just setting the AVAudioSession to AVAudioSessionCategoryOptions.duckOthers would work, but it did. Here is my full code to help the rookies like myself.
我不认为只是将 AVAudioSession 设置为 AVAudioSessionCategoryOptions.duckOthers 会起作用,但确实如此。这是我的完整代码,可以帮助像我这样的菜鸟。
Swift 4 - Full Example:
Swift 4 - 完整示例:
var audioPlayer = AVAudioPlayer()
func playSound(sound: String){
let path = Bundle.main.path(forResource: sound, ofType: nil)!
let url = URL(fileURLWithPath: path)
let audioSession = AVAudioSession.sharedInstance()
try!audioSession.setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.duckOthers)
do {
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer.play()
} catch {
print("couldn't load the file")
}
}
I still need to figure out setActive (I was looking at this blog post) but the audio stops ducking when I leave the app, so it works for my app.
我仍然需要弄清楚 setActive (我正在看这篇博客文章)但是当我离开应用程序时音频停止闪避,所以它适用于我的应用程序。