Ich habe eine App erstellt und versuche dem Benutzer zu erlauben, seine Musik während des Spiels weiterhin zu hören. Wenn sie jedoch auf "Play" klicken und die Ingame-Sounds auftreten, wird die Hintergrundmusik gestoppt. Ich entwickle auf iOS mit Swift. Hier ist ein Teil des Codes, der die Ingame-Sounds initiiert.
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()
}
}
Sie müssen die Kategorie AVAudioSession
mit einem der folgenden Werte festlegen: https://developer.Apple.com/library/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html (AVAudioSession-Klassenreferenz).
Der Standardwert ist auf AVAudioSessionCategorySoloAmbient
gesetzt. Wie du lesen kannst:
Wenn Sie diese Kategorie verwenden, bedeutet dies, dass das Audio Ihrer App nicht mischbar ist. Wenn Sie Ihre Sitzung aktivieren, werden alle anderen Audiositzungen unterbrochen, die ebenfalls nicht mischbar sind. Verwenden Sie stattdessen die Kategorie
AVAudioSessionCategoryAmbient
, um das Mischen zu ermöglichen.
Sie müssen die Kategorie ändern, bevor Sie Ihren Sound abspielen. Um dies zu tun:
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil)
AVAudioSession.sharedInstance().setActive(true, error: nil)
Sie müssen diese Leitung nicht jedes Mal anrufen, wenn Sie den Ton abspielen. Vielleicht möchten Sie es nur einmal tun.
Swift 4 Version:
try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try? AVAudioSession.sharedInstance().setActive(true)
So mache ich es in 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
}
Weitere AVAudioSessionCategoryOptions-Optionen finden Sie hier: https://developer.Apple.com/reference/avfoundation/avaudiosessioncategoryoptions
Folgendes verwende ich für Swift 2.0:
let sess = AVAudioSession.sharedInstance()
if sess.otherAudioPlaying {
_ = try? sess.setCategory(AVAudioSessionCategoryAmbient, withOptions: .DuckOthers)
_ = try? sess.setActive(true, withOptions: [])
}
Bitte beachten Sie, dass Sie .DuckOthers
durch []
ersetzen können, wenn Sie die Hintergrundmusik nicht senken und stattdessen darauf spielen möchten.
die Lösung von lchamp funktionierte perfekt für mich, angepasst an Objective-C:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
**
**
Der Name des Sounds, den ich spiele, ist 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);
}
}
Wo auch immer Sie den Tonanruf abspielen möchten
shatterSound()
Wenn Sie einen Alarmton abspielen möchten:
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)")
}
}
Und wenn Sie Musik spielen wollen:
aVFoundation importieren
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)")
}
}
Für Swift (Objective-C auch so)
sie können this link verwenden, um die beste Antwort zu erhalten. Wenn Sie keine Zeit zum Ansehen von 10 Minuten haben, ist es am besten, wenn Sie copy
unten in AppDelegate
in didFinishLaunchingWithOptions
Code eingeben und dann Ihren project's target
auswählen und dann Capabilities
und endlich in Background modes
auf Audio, AirPlay and Picture in Picture
überprüfen
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 {
}
}
Da sie sich scheinbar nicht von Version zu Version entscheiden können. Hier ist es in Swift 5.0
do{
try AVAudioSession.sharedInstance().setCategory(.ambient)
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)
} catch {
NSLog(error.localizedDescription)
}
Ich dachte nicht, dass es einfach funktionieren würde, AVAudioSession auf AVAudioSessionCategoryOptions.duckOthers zu setzen. Hier ist mein vollständiger Code, um den Anfängern wie mir zu helfen.
Swift 4 - Vollständiges Beispiel:
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")
}
}
Ich muss noch setActive herausfinden ( ich habe mir diesen Blogbeitrag angesehen ), aber das Audio stoppt, wenn ich die App verlasse, also funktioniert es für meine App.