Avi*_*oss 5 iphone speech-recognition ios
我正在使用新的 iOS10 框架进行实时语音识别。我AVCaptureSession用来获取音频。
我有一个“聆听”蜂鸣声来通知用户他可以开始说话了。放置该声音的最佳方法是在第一次调用 时captureOutput(:didOutputSampleBuffer..),但如果我在开始会话后尝试播放声音,该声音将不会播放。并且没有抛出任何错误......它只是默默地无法播放......
我试过的:
AudioServicesPlaySystemSound...())AVPlayer似乎无论我在做什么,在触发识别后都不可能触发播放任何类型的音频(不确定是特定的AVCaptureSession还是SFSpeechAudioBufferRecognitionRequest/ SFSpeechRecognitionTask...)
有任何想法吗?Apple 甚至建议播放“聆听”音效(并使用 Siri 自己做),但我找不到任何参考/示例展示如何实际做到这一点......(他们的“ SpeakToMe ”示例不播放声音)
嗯,显然,为了成功开始语音识别会话,并且只有在识别真正开始时(之后)才能发挥“聆听”效果,必须遵循一堆“规则”。
会话设置和触发必须在主队列上调用。所以:
DispatchQueue.main.async {
speechRequest = SFSpeechAudioBufferRecognitionRequest()
task = recognizer.recognitionTask(with: speechRequest, delegate: self)
capture = AVCaptureSession()
//.....
shouldHandleRecordingBegan = true
capture?.startRunning()
}
Run Code Online (Sandbox Code Playgroud)“聆听”效果应该是通过播放器播放的AVPlayer,而不是系统声音。
知道我们肯定在录制的最安全的地方是在 的委托调用中AVCaptureAudioDataOutputSampleBufferDelegate,当我们得到第一个 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)
}
Run Code Online (Sandbox Code Playgroud)识别结束效果要容易得多:
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()
}
Run Code Online (Sandbox Code Playgroud)