I've looked for a solution, but all of the ones I've seen are confusing so I thought I'd create a new question.
I'm using the speech library and I want the recognition task to stop after 2 seconds without input from the user. I know I want to use a timer, but I'm having trouble figuring out where to put it and how to update it.
I start the timer when the record button is pressed and I invalidate it when the stop recording button is pressed.
But where do I check if the user added new input? I was thinking of saving the last transcription and comparing it to the next one: when they are different, reset the timer.
Here's what my code looks like:
recognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in
var isFinal = false
if let result = result {
self.textView.text = result.bestTranscription.formattedString
// Should I compare the result here to see if it changed?
isFinal = result.isFinal
}
// Or should I do it here? In what order is this code even running?
if error != nil || isFinal {
self.result = self.textView.text
self.audioEngine.stop()
inputNode.removeTap(onBus: 0)
self.recognitionRequest = nil
self.recognitionTask = nil
self.recordButton.isEnabled = true
self.recordButton.setTitle("Start Recording", for: [])
}
}
I had the same issue until now. Checked your question and I suppose the code below helps you achieve the same thing I did.
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()
})
}
})
This checks if input wasn't received for 1.5 seconds.
This is what ended up working for me:
func restartSpeechTimer() {
timer?.invalidate()
timer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false, block: { (timer) in
// Do whatever needs to be done when the timer expires
})
}
And inside the recognition task:
var isFinal = false
if letresult = result {
// do something with the result
isFinal = result.isFinal
}
if iFinal {
self.stopRecording()
}
else if error == nil {
self.restartSpeechTimer()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With