J'ai créé une application et j'essaie de permettre à l'utilisateur de continuer à écouter sa musique tout en jouant à mon jeu, mais chaque fois qu'il clique sur "play" et que les sons du jeu se produisent, la musique de fond est arrêtée. Je développe sur iOS en utilisant Swift. Voici une partie du code qui initie les sons ingame.
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()
}
}
Vous devez définir la catégorie AVAudioSession
avec l'une des valeurs suivantes: https://developer.Apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html (Référence de la classe AVAudioSession).
La valeur par défaut est définie sur AVAudioSessionCategorySoloAmbient
. Comme vous pouvez le lire:
[...] l’utilisation de cette catégorie implique que le son de votre application est non mélangeable; l’activation de votre session interrompt toute session audio également non mélangeable. Pour permettre le mélange, utilisez plutôt la catégorie
AVAudioSessionCategoryAmbient
.
Vous devez changer de catégorie avant de jouer votre son. Faire cela :
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
Vous n'avez pas besoin d'appeler cette ligne à chaque fois que vous jouez le son. Vous voudrez peut-être ne le faire qu'une fois.
Swift 4 version:
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try? AVAudioSession.sharedInstance().setActive(true)
Voici comment je le fais dans 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
}
Vous pouvez voir plus de AVAudioSessionCategoryOptions ici: https://developer.Apple.com/reference/avfoundation/avaudiosessioncategoryoptions
Voici ce que j'utilise pour Swift 2.0:
let sess = AVAudioSession.sharedInstance()
if sess.otherAudioPlaying {
_ = try? sess.setCategory(AVAudioSessionCategoryAmbient, withOptions: .DuckOthers)
_ = try? sess.setActive(true, withOptions: [])
}
Veuillez noter que vous pouvez remplacer .DuckOthers
par []
si vous ne voulez pas baisser la musique d’arrière-plan, mais plutôt jouer dessus.
la solution de lchamp a parfaitement fonctionné pour moi, adaptée pour Objective-C:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
**
**
Le nom du son que je joue est 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);
}
}
Alors, où que vous vouliez jouer l'appel sonore
shatterSound()
Si vous voulez jouer une alerte sonore:
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)")
}
}
Et si vous voulez jouer de la musique:
importer 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)")
}
}
Pour Swift (Objective-C comme ça aussi)
vous pouvez utiliser this link pour la meilleure réponse et si vous n'avez pas le temps de regarder 10 minutes, la meilleure chose à faire est de changer simplement le code copy
ci-dessous dans votre AppDelegate
dans didFinishLaunchingWithOptions
puis de sélectionner votre project's target
puis d'aller à Capabilities
enfin dans Background modes
vérifier sur 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 {
}
}
Je ne pensais pas que le fait de définir AVAudioSession sur AVAudioSessionCategoryOptions.duckOthers fonctionnerait, mais cela a fonctionné. Voici mon code complet pour aider les recrues comme moi.
Swift 4 - Exemple complet:
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")
}
}
Je dois encore comprendre setActive ( Je regardais ce billet de blog ), mais le son cesse de baisser lorsque je quitte l'application, donc cela fonctionne pour mon application.