我正在使用新的 iOS10 框架进行实时语音识别。我使用 AVCaptureSession
获取音频。
我有一个“正在收听”的哔哔声,通知用户他可以开始说话了。放置声音的最佳方式是在第一次调用 captureOutput(:didOutputSampleBuffer..)
时,但是如果我在开始 session 后尝试播放声音,声音就不会播放。并且没有抛出任何错误..它只是静静地无法播放...
我尝试过的:
- 通过系统声音播放 (
AudioServicesPlaySystemSound...()
) - 使用
AVPlayer
播放 Assets - 还在主队列上尝试了上述两种解决方案异步/同步
似乎无论我在做什么,都不可能在触发识别后触发播放任何类型的音频(不确定它是否特别是 AVCaptureSession
或 SFSpeechAudioBufferRecognitionRequest
/SFSpeechRecognitionTask
...)
有什么想法吗? Apple even recommends playing a "listening" sound effect (并用 Siri 自己做)但我找不到任何引用/示例来说明如何实际操作...(他们的“SpeakToMe”示例不播放声音)
- 我可以在触发 session 之前播放声音,它确实有效(在播放声音完成后开始 session 时)但有时在实际开始识别时会有延迟(主要是在使用 BT 耳机并从不同的 AudioSession 类别 - 我没有完成事件...) - 因此我需要一种在录音实际开始时播放声音的方法,而不是在它触发和交叉手指之前它不会延迟开始它...
最佳答案
好吧,显然必须遵循一堆“规则”才能成功开始语音识别 session 并仅在(之后)识别真正开始时才发挥“聆听”效果。
必须在主队列上调用 session 设置和触发。所以:
DispatchQueue.main.async { speechRequest = SFSpeechAudioBufferRecognitionRequest() task = recognizer.recognitionTask(with: speechRequest, delegate: self) capture = AVCaptureSession() //..... shouldHandleRecordingBegan = true capture?.startRunning() }
“聆听”效果应该是通过
AVPlayer
播放,而不是作为系统声音。知道我们肯定录音的最安全的地方是在
AVCaptureAudioDataOutputSampleBufferDelegate
的委托(delegate)调用中,当我们得到第一个 sampleBuffer 回调时:func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { //only once per recognition session if shouldHandleRecordingBegan { shouldHandleRecordingBegan = false player = AVPlayer(url: Bundle.main.url(forResource: "listening", withExtension: "aiff")!) player.play() DispatchQueue.main.async { //call delegate/handler closure/post notification etc... } } // append buffer to speech recognition speechRequest?.appendAudioSampleBuffer(sampleBuffer) }
结束识别效果要容易得多:
var ended = false if task?.state == .running || task?.state == .starting { task?.finish() // or task?.cancel() to cancel and not get results. ended = true } if true == capture?.isRunning { capture?.stopRunning() } if ended { player = AVPlayer(url: Bundle.main.url(forResource: "done", withExtension: "aiff")!) player.play() }
关于iOS10语音识别 "Listening"音效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41096150/