我正在使用一个需要基于语音命令打开某些屏幕的应用程序,例如,如果用户说“Open Setting”(打开设置),那么它应该打开设置屏幕,到目前为止,我已经使用了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)
}
}
}
}
但是,当我说任何单词/句子(例如“打开设置”)时,多次调用了closure(
recognitionTask(with:)
),并且我将方法(idenifyVoiceCommand
)放入了多次调用的closure中,因此,如何限制只调用一次。此外,我还在使用Google谷歌搜索时查看了Timer逻辑(SFSpeechRecognizer - detect end of utterance),但在我的方案中,它没有用,因为我没有停止音频引擎,因为它像 Siri 一样不断监听用户的声音。
B)通过委托(delegate)(
SFSpeechRecognitionTaskDelegate
)speechRecognizer.recognitionTask(使用:self.request,委托(delegate):self)
func speechRecognitionTaskWasCancelled(_ task: SFSpeechRecognitionTask) {
}
func speechRecognitionTask(_ task: SFSpeechRecognitionTask, didFinishSuccessfully successfully: Bool) {
}
我发现处理语音结束时的代表不叫它,有时不小心叫了它。
最佳答案
直到现在我都遇到了同样的问题。
我检查了您的问题,并认为以下代码可帮助您实现与我相同的操作:
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秒钟是否未收到输入