Как реализовать SFSpeechRecognizationTaskDelegates
Я пытаюсь реализовать преобразование речи в текстовое приложение, я могу записывать звук с микрофона с помощью SFSpeechRecognizer . Сценарий использования - как только пользователь перестанет говорить, метод должен автоматически вызвать и остановить запись. чтобы помочь мне в использовании.
Пожалуйста, найдите приведенный ниже код
func startRecording() {
// Clear all previous session data and cancel task
if recognitionTask != nil {
recognitionTask?.cancel()
recognitionTask = nil
}
// Create instance of audio session to record voice
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSession.Category.record, mode: AVAudioSession.Mode.measurement, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print("audioSession properties weren't set because of an error.")
}
self.recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
let inputNode = audioEngine.inputNode
guard let recognitionRequest = recognitionRequest else {
fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object")
}
recognitionRequest.shouldReportPartialResults = true
self.recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
var isFinal = false
if result != nil {
self.lblText.text = result?.bestTranscription.formattedString
print(result?.bestTranscription.formattedString)
print(result?.isFinal)
isFinal = (result?.isFinal)!
}
if error != nil || isFinal {
self.audioEngine.stop()
inputNode.removeTap(onBus: 0)
self.recognitionRequest = nil
self.recognitionTask = nil
self.btnStart.isEnabled = true
}
})
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
self.recognitionRequest?.append(buffer)
}
self.audioEngine.prepare()
do {
try self.audioEngine.start()
} catch {
print("audioEngine couldn't start because of an error.")
}
self.lblText.text = "Say something, I'm listening!"
}
}
2 ответа
Насколько я понимаю, вы хотите остановить распознавание, когда пользователь перестает говорить. Я предлагаю использовать Таймер, чтобы отслеживать время, проведенное в тишине. Добавитьvar detectionTimer: Timer?
вне вашего startRecording(). И внутриresultHandler
из recognitionTask
вставить
self.detectionTimer?.invalidate()
self.detectionTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: false, block: { (timer) in
self.stopRecording()
})
Таким образом, после каждого распознанного слова вы запускаете таймер, который остановит распознавание, если в течение 2 секунд ничего не было захвачено. stopRecording должен выглядеть примерно так
audioEngine.stop()
recognitionRequest?.endAudio()
recognitionRequest = nil
audioEngine.inputNode.removeTap(onBus: 0)
// Cancel the previous task if it's running
if let recognitionTask = recognitionTask {
recognitionTask.cancel()
self.recognitionTask = nil
}
Для этого можно использовать таймер. Начните отсчет времени, как только вы начнете воспроизводить звуковой движок, чтобы распознать речь.
- Если речь будет распознаваться постоянно, таймер будет постоянно перезапускаться.
- Если по истечении фиксированных секунд будет тишина, будет вызван метод селектора и остановит распознавание.
Ниже приведен код -
func timerReStart() {
if timer != nil {
timer?.invalidate()
timer = nil
}
// Change the interval as per the requirement
timer = Timer.scheduledTimer(timeInterval: 20, target: self, selector: #selector(self.handleTimerValue), userInfo: nil, repeats: false)
}
@objc func handleTimerValue() {
cancelRecording()
}
func timerStop() {
guard timer != nil else { return }
timer?.invalidate()
timer = nil
}
func startRecording() {
// Clear all previous session data and cancel task
if recognitionTask != nil {
recognitionTask?.cancel()
recognitionTask = nil
}
// Create instance of audio session to record voice
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSession.Category.record, mode: AVAudioSession.Mode.measurement, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print("audioSession properties weren't set because of an error.")
}
self.recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
let inputNode = audioEngine.inputNode
guard let recognitionRequest = recognitionRequest else {
fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object")
}
recognitionRequest.shouldReportPartialResults = true
self.recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in
var isFinal = false
if result != nil {
self.lblText.text = result?.bestTranscription.formattedString
print(result?.bestTranscription.formattedString)
print(result?.isFinal)
isFinal = (result?.isFinal)!
self.timerReStart()
}
if error != nil || isFinal {
self.audioEngine.stop()
inputNode.removeTap(onBus: 0)
self.recognitionRequest = nil
self.recognitionTask = nil
self.btnStart.isEnabled = true
self.timerStop()
}
})
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
self.recognitionRequest?.append(buffer)
}
self.audioEngine.prepare()
do {
try self.audioEngine.start()
//Start timer to check if there is silence
self.timerReStart()
} catch {
print("audioEngine couldn't start because of an error.")
}
self.lblText.text = "Say something, I'm listening!"
}
}
func cancelRecording() {
if audioEngine.isRunning {
let node = audioEngine.inputNode
node.removeTap(onBus: 0)
audioEngine.stop()
recognitionTask?.cancel()
recognitionTask = nil
}
self.timerStop()
}