it-swarm.com.de

Wie kann ich zulassen, dass Hintergrundmusik weiter abgespielt wird, während meine App während der Verwendung von Swift weiterhin ihre Sounds wiedergibt?

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()
    }
}
34
Nathan Harper

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.

43
lchamp

Swift 4 Version:

try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
try? AVAudioSession.sharedInstance().setActive(true)
14
Milan Nosáľ

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

12
Setera

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.

9
sameer

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];

5
itnAAnti

**

Aktualisiert für Swift 3.0

**

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()
2
Timmy Sorensen

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)")
    }
}
1
Amr

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 {

    }
}
1
shor67

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)
}
1
Matt

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. 

0
Joshua Dance