Swift - AVAudioPlayer не работает должным образом

У меня есть следующий код:

let speechRecognizer = SFSpeechRecognizer()!
let audioEngine = AVAudioEngine()
var recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
var recognitionTask = SFSpeechRecognitionTask()
var audioPlayer : AVAudioPlayer!

override func viewDidLoad() {
    super.viewDidLoad()
    playSound(sound: "oops")
    speechRecognizer.delegate = self
    requestSpeechAuth()

}

func requestSpeechAuth(){
    SFSpeechRecognizer.requestAuthorization { (authStatus) in
        OperationQueue.main.addOperation({ 
            switch authStatus {
            case.authorized:
                print("authorized")
            case.denied:
                print("denied")
            case.restricted:
                print("restricted")
            case.notDetermined:
                print("not determined")
            }
        })

    }
}

// Function called when I press on my record button
func SpeechButtonDown() {
    print("Start recording")

    if audioEngine.isRunning {

        endRecording() {

    } else {
       do {

        let audioSession = AVAudioSession.sharedInstance()
        try audioSession.setCategory(AVAudioSessionCategoryRecord)
        try audioSession.setMode(AVAudioSessionModeMeasurement)
        try audioSession.setActive(true, with: .notifyOthersOnDeactivation)

        if let inputNode = audioEngine.inputNode {

            recognitionRequest.shouldReportPartialResults = true

            recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
                print("1")
                if let result = result {
                    self.instructionLabel.text = result.bestTranscription.formattedString
                    print("2")
                    if result.isFinal {
                        self.audioEngine.stop()
                        inputNode.removeTap(onBus: 0)
                        if self.instructionLabel.text != "" {
                            self.compareWordwithVoice()
                        }
                    }   
                }
            })

            let recognitionFormat = inputNode.outputFormat(forBus: 0)

            inputNode.installTap(onBus: 0, bufferSize: 1024, format: recognitionFormat, block: { (buffer, when) in
                self.recognitionRequest.append(buffer)
            })

            audioEngine.prepare()

                try audioEngine.start()
       }
    } catch {

    } 
    }
}

// Function called when I release the record button
func EndRecording() {
    endRecording()
    print("Stop recording")
}

func endRecording() {
    audioEngine.stop()
    recognitionRequest.endAudio()
    audioEngine.inputNode?.removeTap(onBus: 0)
}

func playSound(sound: String) {
    if let url = Bundle.main.url(forResource: sound, withExtension: "wav") {
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            guard let player = audioPlayer else { return }
            player.prepareToPlay()
            player.play()
            print("tutu")
        } catch let error {
            print(error.localizedDescription)
        }
    }
}

func compareWordwithVoice() {

    let StringToLearn = setWordToLearn()
    print("StringToLearn : \(StringToLearn)")
    if let StringRecordedFull = instructionLabel.text{
        let StringRecorded = (StringRecordedFull as NSString).replacingOccurrences(of: " ", with: "").lowercased()
    print("StringRecorded : \(StringRecorded)")
        if StringRecorded == "appuyezsurleboutonendessousetprenoncezl’expression" {
            print("not yet")
        } else {
            if StringToLearn == StringRecorded {

        playSound(sound: "success")
        print("success")
        // update UI
    } else {
        playSound(sound: "oops")
        print("oops")
        // update UI
    }
        }

    }
}

 func setWordToLearn() -> String {
    if let wordToLearnFull = expr?.expression {
        print(wordToLearnFull)
        var wordToLearn = (wordToLearnFull as NSString).replacingOccurrences(of: " ", with: "").lowercased()
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: ".", with: "")
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: "!", with: "")
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: "?", with: "")
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: ",", with: "")
        wordToLearn = (wordToLearn as NSString).replacingOccurrences(of: "/", with: "")
        print(wordToLearn)
        return wordToLearn
    }
    print("no wordToLearn")
    return ""

}

Проблема в том, что playSound отлично работает, когда он находится в viewDidLoad, но не работает, когда он вызывается функцией compareThing(), но отображает "пачку" в обоих случаях, поэтому он каждый раз выполняет функцию playSound.

Может ли быть проблема, если AVAudioPlayer и AVAudioEngine не могут работать одновременно?

Спасибо

2 ответа

Решение

Я испытал то же самое с моим кодом, и из поиска в Интернете кажется, что есть негласная ошибка "при использовании AvAudioPlayer и Engine отдельно"

Я получил информацию по следующей ссылке. Я не нашел ничего другого в Интернете, в котором говорится, почему эта ошибка происходит, хотя. https://swiftios8dev.wordpress.com/2015/03/05/sound-effects-using-avaudioengine/

Было предложено использовать AVAudioEngine для всего.

Я думаю, что "CompareThings" всегда воспроизводит звук "упс", и этот звук не очень хороший (слишком тихий или сломанный).

Пожалуйста, попробуйте воспроизвести звук "упс" из функции "viewDidLoad", чтобы убедиться, что звук нормальный. Если все в порядке (я так не думаю) - установите точку останова в функции "playSound", чтобы увидеть, что происходит (название звука, существует ли он и т. Д.).

Другие вопросы по тегам