我正在使用SpeechKit将语音返回到文本列表中。例如列出杂货店清单。但是我不断获得多个价值。我没什么问题我知道该函数仅被调用一次,但是它返回多个值。下面是它的外观和代码的gif图像。请给我一些指导。
func prepareAudioEngine() {
let node = audioEngine.inputNode
let recordingFormat = node.outputFormat(forBus: 0)
node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, _) in
self.request.append(buffer)
}
audioEngine.prepare()
do {
try audioEngine.start()
} catch {
return print(error)
}
guard let myRecogizer = speechRecognizer else { return }
if !myRecogizer.isAvailable {
return
}
recordandRecognizeSpeech()
}
func recordandRecognizeSpeech() {
recognitionTask = speechRecognizer?.recognitionTask(with: request, resultHandler: { (result, error) in
if let result = result {
let stringArray = result.bestTranscription.formattedString
let size = stringArray.reversed().firstIndex(of: " ") ?? stringArray.count
let startWord = stringArray.index(stringArray.endIndex, offsetBy: -size)
let last = stringArray[startWord...]
self.detectedTextLabel.text = String(last).capitalized
} else if let error = error {
print("There was an error",error)
}
self.ingredients.append(Ingredient(name: self.detectedTextLabel.text ?? "Default", imageName: "🍉"))
let indexPath = IndexPath(item: self.ingredients.count - 1, section: 0)
self.tableView.insertRows(at: [indexPath], with: .automatic)
})
}
所以,我认为这是在发生以下情况:request.shouldReportPartialResults = true
时,随着SpeechRecognizer解析它们,返回了多个SFSpeechRecognitionResultResult。用下面的代码替换recognitionTask
代码:
let df = DateFormatter()
df.dateFormat = "y-MM-dd H:m:ss.SSSS"
recognitionTask = speechRecognizer?.recognitionTask(with: request, resultHandler: { (result, error) in
if let result = result {
let d = Date()
print(df.string(from: d)) // -> "2016-11-17 17:51:15.1720"
print("isFinal: \(result.isFinal)")
for (isegment, segment) in result.bestTranscription.segments.enumerated() {
print("\(isegment): \(segment.substring) (ts \(segment.timestamp), dur \(segment.duration), conf \(segment.confidence)")
}
} else if let error = error {
print("There was an error",error)
}
})
并且在我的iPad上进行测试时检查Xcode控制台输出...
[这是我启动音频引擎时看到的,说“嘿,”,暂时停顿一下(〜1秒),然后说“你听到了我的声音]
2020-06-07 17:31:14.0330
isFinal: false
0: Hey (ts 0.0, dur 0.0, conf 0.0)
2020-06-07 17:31:14.2190
isFinal: false
0: Hey (ts 0.0, dur 0.0, conf 0.0)
1: do (ts 0.0, dur 0.0, conf 0.0)
2020-06-07 17:31:14.2560
isFinal: false
0: Hey (ts 0.0, dur 0.0, conf 0.0)
2020-06-07 17:31:14.5600
isFinal: false
0: Hey (ts 0.0, dur 0.0, conf 0.0)
1: do (ts 0.0, dur 0.0, conf 0.0)
2020-06-07 17:31:14.6690
isFinal: false
0: Hey (ts 0.0, dur 0.0, conf 0.0)
1: do (ts 0.0, dur 0.0, conf 0.0)
2020-06-07 17:31:14.7930
isFinal: false
0: Hey (ts 0.55, dur -0.55, conf 0.745)
1: do (ts 0.84, dur -0.84, conf 0.816)
2020-06-07 17:31:15.6900
isFinal: false
0: Hey (ts 0.0, dur 0.0, conf 0.0)
1: do (ts 0.0, dur 0.0, conf 0.0)
2: you (ts 0.0, dur 0.0, conf 0.0)
2020-06-07 17:31:15.8630
isFinal: false
0: Hey (ts 0.0, dur 0.0, conf 0.0)
1: do (ts 0.0, dur 0.0, conf 0.0)
2: you (ts 0.0, dur 0.0, conf 0.0)
3: hear (ts 0.0, dur 0.0, conf 0.0)
2020-06-07 17:31:16.1120
isFinal: false
0: Hey (ts 0.0, dur 0.0, conf 0.0)
1: do (ts 0.0, dur 0.0, conf 0.0)
2: you (ts 0.0, dur 0.0, conf 0.0)
3: hear (ts 0.0, dur 0.0, conf 0.0)
4: me (ts 0.0, dur 0.0, conf 0.0)
2020-06-07 17:31:16.1950
isFinal: false
0: Hey (ts 0.55, dur -0.55, conf 0.93)
1: do (ts 0.84, dur -0.84, conf 0.915)
2: you (ts 1.92, dur -1.92, conf 0.927)
3: hear (ts 2.2800000000000002, dur -2.2800000000000002, conf 0.932)
4: me (ts 2.5100000000000002, dur -2.5100000000000002, conf 0.923)
等一会儿(〜2秒),然后停止audioEngine:
2020-06-07 17:31:18.4710
isFinal: false
0: Hey (ts 0.55, dur -0.55, conf 0.93)
1: do (ts 0.84, dur -0.84, conf 0.915)
2: you (ts 1.92, dur -1.92, conf 0.927)
3: hear (ts 2.2800000000000002, dur -2.2800000000000002, conf 0.932)
4: me (ts 2.5100000000000002, dur -2.5100000000000002, conf 0.923)
2020-06-07 17:31:18.5200
isFinal: true
0: Hey (ts 0.55, dur 0.2899999999999999, conf 0.93)
1: do (ts 0.84, dur 0.42000000000000004, conf 0.915)
2: you (ts 1.92, dur 0.3600000000000003, conf 0.927)
3: hear (ts 2.2800000000000002, dur 0.22999999999999998, conf 0.932)
4: me (ts 2.5100000000000002, dur 0.3099999999999996, conf 0.923)
注意一些事项:
result
上的时间戳为0.0]result
上的isFinal标志才为True。[不幸的是,我没有在SFTranscriptionSegment或SFSpeechRecognitionResult类中看到任何其他标志来帮助区分“仍在解析中”与“好,我已经完成了”。
推荐
对于实时处理转录,我建议根据结果的时间戳过滤结果。保留令牌和时间戳(或其他内容)的输出列表,并仅在令牌以较大的时间戳到达时才添加到列表中。
我希望在identificationTask决定在整个音频片段的末尾确定要从片段的开头更改单词的情况下,这可能会崩溃。然后,您将在该段的早期获得更改的令牌和时间戳。
对于您的特定情况,如果音频中有一段时间没有声音,则停止audioEngine并重新启动它可能会有所帮助。这将强制RecognitionTask完成音频的解析,并确保片段/时间戳/令牌不发生更改。