在SpeechKit框架中连续收听用户语音并检测语音结束语

时间:2018-04-06 12:55:45

标签: swift speech-recognition ios10 speech-to-text speechkit

我正在开发一个应用程序,我们需要根据语音命令打开某个屏幕,就像用户说"打开设置"然后它应该打开设置屏幕,到目前为止我已经使用了SpeechKit框架,但我无法检测到语音结束的沉默。就像 Siri 一样。我想检测用户是否已结束他的句子/短语。

请在以下两个方面集成SpeechKit框架的地方找到以下代码。

A)通过闭合(recognitionTask(with request: SFSpeechRecognitionRequest, resultHandler: @escaping (SFSpeechRecognitionResult?, Error?) -> Swift.Void) -> SFSpeechRecognitionTask

let audioEngine = AVAudioEngine()
let speechRecognizer = SFSpeechRecognizer()
let request = SFSpeechAudioBufferRecognitionRequest()
var recognitionTask: SFSpeechRecognitionTask?

func startRecording() throws {

        let node = audioEngine.inputNode
        let recordingFormat = node.outputFormat(forBus: 0)

        node.installTap(onBus: 0, bufferSize: 1024,
                        format: recordingFormat) { [unowned self]
                            (buffer, _) in
                            self.request.append(buffer)
        }

        audioEngine.prepare()
        try audioEngine.start()

        weak var weakSelf = self

        recognitionTask = speechRecognizer?.recognitionTask(with: request) {
            (result, error) in

            if result != nil {

                if let transcription = result?.bestTranscription {
                    weakSelf?.idenifyVoiceCommand(transcription)
                }
            }
        }            
}

但是,当我说任何单词/句子如" Open Setting"然后关闭(recognitionTask(with:))多次调用,我把方法(idenifyVoiceCommand)放在多次调用的闭包中,所以如何限制只调用一次。

我还会在谷歌搜索时查看定时器逻辑(SFSpeechRecognizer - detect end of utterance),但在我的观点中它不起作用,因为我没有停止音频引擎,因为它不断地听着用户的声音,如 Siri 确实。

B)通过委托(SFSpeechRecognitionTaskDelegate

speechRecognizer.recognitionTask(with:self.request,delegate:self)

func speechRecognitionTaskWasCancelled(_ task: SFSpeechRecognitionTask) {

}

func speechRecognitionTask(_ task: SFSpeechRecognitionTask, didFinishSuccessfully successfully: Bool) {

}

我发现在演讲结束时处理的代表不会调用它,有时会不小心调用它。

1 个答案:

答案 0 :(得分:0)

直到现在我都遇到了同样的问题。

我检查了您的问题,我想下面的代码可以帮助您实现与我相同的操作:

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

    var isFinal = false

    if result != nil {

        self.inputTextView.text = result?.bestTranscription.formattedString
        isFinal = (result?.isFinal)!
    }

    if let timer = self.detectionTimer, timer.isValid {
        if isFinal {
            self.inputTextView.text = ""
            self.textViewDidChange(self.inputTextView)
            self.detectionTimer?.invalidate()
        }
    } else {
        self.detectionTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false, block: { (timer) in
            self.handleSend()
            isFinal = true
            timer.invalidate()
        })
    }

})

这将检查1.5秒钟是否没有收到输入