Swift SFSpeechRecognizer, добавляющий существующий контент UITextView - PullRequest
0 голосов
/ 21 ноября 2018

Я использую SFSpeechRecognizer в своем приложении, которое работает нормально, чтобы облегчить конечному пользователю ввод комментария в UITextView благодаря специальной кнопке (Начать распознавание речи).

Но если пользователь печатает некоторыесначала текст вручную, а затем начинает распознавание речи, предыдущий текст, введенный вручную, стирается.Это также имеет место, если пользователь выполняет два раза распознавание речи (пользователь «произносит речь», записывает первую часть своего текста, затем останавливает запись и, наконец, перезапускает запись) в том же UITextView, предыдущий текст стирается.

Следовательно, я хотел бы знать, как добавить текст, распознаваемый SFSpeechRecognizer, к существующему.

Вот мой код:

func recordAndRecognizeSpeech(){

    if recognitionTask != nil {
        recognitionTask?.cancel()
        recognitionTask = nil
    }
    let audioSession = AVAudioSession.sharedInstance()
    do {
        try audioSession.setCategory(AVAudioSessionCategoryRecord)
        try audioSession.setMode(AVAudioSessionModeMeasurement)
        try audioSession.setActive(true, with: .notifyOthersOnDeactivation)
    } catch {
        print("audioSession properties weren't set because of an error.")
    }
    self.recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
    guard let inputNode = audioEngine.inputNode else {
        fatalError("Audio engine has no input node")
    }
    let recognitionRequest = self.recognitionRequest
    recognitionRequest.shouldReportPartialResults = true

    recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
        var isFinal = false
        self.decaration.text = (result?.bestTranscription.formattedString)!

        isFinal = (result?.isFinal)!
        let bottom = NSMakeRange(self.decaration.text.characters.count - 1, 1)
        self.decaration.scrollRangeToVisible(bottom)

        if error != nil || isFinal {
            self.audioEngine.stop()
            inputNode.removeTap(onBus: 0)
            self.recognitionTask = nil
            self.recognitionRequest.endAudio()
            self.oBtSpeech.isEnabled = true
        }
    })
    let recordingFormat = inputNode.outputFormat(forBus: 0)
    inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
        self.recognitionRequest.append(buffer)
    }
    audioEngine.prepare()

    do {
        try audioEngine.start()
    } catch {
        print("audioEngine couldn't start because of an error.")
    }

}

Я пытался обновить

self.decaration.text = (result?.bestTranscription.formattedString)!

от

self.decaration.text += (result?.bestTranscription.formattedString)!

но он распознает дублон для каждого предложения.

Есть идеи, как мне это сделать?

1 Ответ

0 голосов
/ 21 ноября 2018

Попробуйте сохранить текст перед запуском системы распознавания.

func recordAndRecognizeSpeech(){
    // one change here
    let defaultText = self.decaration.text

    if recognitionTask != nil {
        recognitionTask?.cancel()
        recognitionTask = nil
    }
    let audioSession = AVAudioSession.sharedInstance()
    do {
        try audioSession.setCategory(AVAudioSessionCategoryRecord)
        try audioSession.setMode(AVAudioSessionModeMeasurement)
        try audioSession.setActive(true, with: .notifyOthersOnDeactivation)
    } catch {
        print("audioSession properties weren't set because of an error.")
    }
    self.recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
    guard let inputNode = audioEngine.inputNode else {
        fatalError("Audio engine has no input node")
    }
    let recognitionRequest = self.recognitionRequest
    recognitionRequest.shouldReportPartialResults = true

    recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
        var isFinal = false
        // one change here
        self.decaration.text = defaultText + " " + (result?.bestTranscription.formattedString)!

        isFinal = (result?.isFinal)!
        let bottom = NSMakeRange(self.decaration.text.characters.count - 1, 1)
        self.decaration.scrollRangeToVisible(bottom)

        if error != nil || isFinal {
            self.audioEngine.stop()
            inputNode.removeTap(onBus: 0)
            self.recognitionTask = nil
            self.recognitionRequest.endAudio()
            self.oBtSpeech.isEnabled = true
        }
    })
    let recordingFormat = inputNode.outputFormat(forBus: 0)
    inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
        self.recognitionRequest.append(buffer)
    }
    audioEngine.prepare()

    do {
        try audioEngine.start()
    } catch {
        print("audioEngine couldn't start because of an error.")
    }
}

result?.bestTranscription.formattedString возвращает всю распознанную фразу, поэтому вы должны сбрасывать self.decaration.text каждый раз, когда получаете ответ от SFSpeechRecognnizer.

...