アプリを作成し、ユーザーがゲームのプレイ中に音楽を聴き続けることを許可しようとしていますが、「プレイ」を押してゲーム内サウンドが発生すると、バックグラウンドミュージックが停止します。私は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
に設定されています。あなたが読むことができるように:
[...]このカテゴリを使用することは、アプリのオーディオがミックス不可であることを意味します。セッションをアクティブにすると、同じくミックスできない他のオーディオセッションが中断されます。混合を許可するには、代わりに
AVAudioSessionCategoryAmbient
カテゴリを使用します。
サウンドを再生する前に、カテゴリを変更する必要があります。そうするには :
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
サウンドを再生するたびにこれらの行を呼び出す必要はありません。一度だけやりたいかもしれません。
Swift 4バージョン:
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try? AVAudioSession.sharedInstance().setActive(true)
これは、私が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 2.0に使用しているものは次のとおりです。
let sess = AVAudioSession.sharedInstance()
if sess.otherAudioPlaying {
_ = try? sess.setCategory(AVAudioSessionCategoryAmbient, withOptions: .DuckOthers)
_ = try? sess.setActive(true, withOptions: [])
}
.DuckOthers
with []
バックグラウンドミュージックを下げずに、その上で再生したい場合。
lchampのソリューションは、Objective-Cに適応した私にとって完璧に機能しました。
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; [[AVAudioSession sharedInstance] setActive:YES error:nil];
**
**
私が演奏している音の名前は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 5.0
do{
try AVAudioSession.sharedInstance().setCategory(.ambient)
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
} catch {
NSLog(error.localizedDescription)
}
AVAudioSessionをAVAudioSessionCategoryOptions.duckOthersに設定するだけでは機能するとは思いませんでしたが、うまくいきました。ここに私のような新人を助けるための私の完全なコードがあります。
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")
}
}
私はまだsetActive( このブログ投稿を見ていました )を把握する必要がありますが、アプリを離れると音声がダッキングを停止するため、アプリで動作します。