AVAudioPlayerDidFinishPlaying никогда не вызывается, поэтому «другие звуки» остаются «приглушенными». Что я делаю не так? - PullRequest
0 голосов
/ 26 января 2020

Многие вопросы по этой теме c, но большинство из них настолько старые, что ответы больше не применяются из-за того, что как Swift, так и iOS эволюционировали так много с тех пор, как были опубликованы. Те немногие, которые кажутся полезными на первый взгляд, на самом деле не говорят мне ничего, что я еще не понял, и не сделали ничего, чтобы помочь мне решить мою проблему, несмотря на то, что кажется, что она почти идентична проблеме, которую я ». m.

За исключением того, что AVAudioPlayerDidFinishPlaying никогда не вызывается (и, следовательно, оставляя "другие звуки", производимые устройством, "приглушенными", пока приложение полностью не закрывается), код ниже функционирует точно так, как ожидается, в обоих симуляторах и на физическом iPhone 7 Plus работает iOS 13.3. Если это имеет значение, я пишу код Swift 5.1, нацеленный на iOS 13.3, в Xcode 11.3, на буровой установке, которая запускает Catalina (10.15.2).

Вот «сломанный» код:

import Foundation
import AVFoundation

class NoiseMaker: NSObject, AVAudioPlayerDelegate {
    var ourSession = AVAudioSession()
    var ourPlayer  = AVAudioPlayer()

    func playSound(sound: String) {
        print("Entered NoiseMaker.playSound(sound: \(sound))")
        let theURL: URL = Bundle.main.url(forResource: sound, withExtension: "mp3")!

        try!ourSession.setCategory(AVAudioSession.Category.ambient, options: AVAudioSession.CategoryOptions.duckOthers)
        try!ourSession.setActive(true)
        ourPlayer.delegate = self
        ourPlayer.prepareToPlay()
        do {
            ourPlayer = try AVAudioPlayer(contentsOf: theURL)
            ourPlayer.play()
        } catch let theError as NSError {
            print("Couldn't load \(sound).mp3 - Error \(theError)")
        }
    }

    // MARK: - AVAudioPlayer delegate methods
    // Never gets called - Other sound sources remain "ducked" until the app is completely shut down.
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        print("Arrived in audioPlayerDidFinishPlaying")
        try!ourSession.setActive(false)
    }

    func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
        print("Decoding error from AVAudioPlayer: \(error!.localizedDescription)")
    }
}

Как уже отмечалось, все работает, как и ожидалось - за исключением моего метода audioPlayerDidFinishPlaying, который никогда не вызывается, что означает, что у меня никогда не будет возможности "отсоединить" другие звуки, которые могут воспроизводиться. (хотя все «отстает», как только приложение полностью закрывается)

Почему? Как я испорчу то, что кажется почти тривиальной задачей?

1 Ответ

2 голосов
/ 26 января 2020

Я вижу проблему, вы устанавливаете self в качестве делегата, но затем вы меняете ссылку на новый экземпляр AVAudioPlayer

. Вы должны установить делегат после создания нового экземпляра здесь

ourPlayer = try AVAudioPlayer(contentsOf: theURL)
ourPlayer.delegate = self
ourPlayer.play()
...