Сбой сеанса распознавания речи - PullRequest
2 голосов
/ 19 сентября 2019

Я знаю, что подобные вопросы уже задавались, но предложенные решения не помогли мне.

В моем приложении я должен распознавать речь пользователя и синтезировать текст в речь.Проблема в том, что у меня возникают случайные сбои, когда приложение пытается распознать (особенно после преобразования текста в речь, но также и в других случаях: например, при второй попытке распознавания).

У меня есть специальный классSpeecher с несколькими очевидными переменными (некоторые частные) и двумя основными функциями: startRecord и killRecord.

func startRecord() {

    session = AVAudioSession.sharedInstance()

    do {
        try session.setCategory(AVAudioSession.Category.playAndRecord, mode: .spokenAudio, options: [.defaultToSpeaker, .mixWithOthers])
    } catch {
        print("audio session \(error)")
        return
    }

    audioEngine = AVAudioEngine()

    inputNode = audioEngine.inputNode
    inputNode.removeTap(onBus: 0)
    let recordingFormat = inputNode.inputFormat(forBus: 0)

    recognitionRequest = SFSpeechAudioBufferRecognitionRequest()

    guard let recognitionRequest = recognitionRequest else { fatalError("Unable to create a SFSpeechAudioBufferRecognitionRequest object") }
    recognitionRequest.shouldReportPartialResults = true

    if #available(iOS 13, *) {
        recognitionRequest.requiresOnDeviceRecognition = true
    }

    inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
        self.recognitionRequest.append(buffer)
    }

    audioEngine.prepare()

    do {
        try audioEngine.start()
    } catch {
        return print("audio engine start error \(error)")
    }

    guard let myRecognizer = SFSpeechRecognizer() else {
        print("recognizer error")
        return
    }

    if !myRecognizer.isAvailable {
        print("Recognizer is not available right now error")
        return
    }

    recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { result, error in
            if let result = result {

                let bestString = result.bestTranscription.formattedString
                print(bestString)
                self.speecherDelegate?.sendSpeechString(str: bestString)
            } else if let error = error {
                print("result error \(error)")
            }
        })

}

Следующая функция вызывается до того, как я пытаюсь использовать преобразование текста в речь или передЯ хочу отменить / остановить сеанс распознавания:

func killRecord() {
    if recognitionRequest != nil {
        recognitionRequest.endAudio()
    }


    if audioEngine != nil {

        audioEngine.stop()

        if audioEngine.inputNode != nil {
            audioEngine.inputNode.removeTap(onBus: 0)
        }
    }

    if recognitionTask != nil {
        recognitionTask?.cancel()
    }

    if session != nil {

        do {
            try session.setCategory(AVAudioSession.Category.playback, mode: .spokenAudio, options: [.allowBluetooth, .allowBluetoothA2DP, .defaultToSpeaker, .mixWithOthers])
            try session.setActive(false, options: .notifyOthersOnDeactivation)
        } catch {
            print("switch audiosession error not nil \(error)")
            return
        }

    } else {
        session = AVAudioSession.sharedInstance()

        do {
            try session.setCategory(AVAudioSession.Category.playback, mode: .spokenAudio, options: [.allowBluetooth, .allowBluetoothA2DP, .defaultToSpeaker, .mixWithOthers])
            try session.setActive(false, options: .notifyOthersOnDeactivation)
        } catch {
            print("switch audiosession error \(error)")
            return
        }
    }
}

Я получаю много ошибок lldb.Это выглядит так:

enter image description here

Строка проблемы в коде выглядит как inputNode = audioEngine.inputNode, но я не знаю, как ее решить.Я уже пробовал audioEngine.inputNode.removeTap(onBus: 0) как раз перед inputNode = audioEngine.inputNode, но безрезультатно.

...