iOS10语音识别 "Listening"音效

标签 ios iphone speech-recognition

我正在使用新的 iOS10 框架进行实时语音识别。我使用 AVCaptureSession 获取音频。

我有一个“正在收听”的哔哔声,通知用户他可以开始说话了。放置声音的最佳方式是在第一次调用 captureOutput(:didOutputSampleBuffer..) 时,但是如果我在开始 session 后尝试播放声音,声音就不会播放。并且没有抛出任何错误..它只是静静地无法播放...

我尝试过的:

  • 通过系统声音播放 (AudioServicesPlaySystemSound...())
  • 使用 AVPlayer 播放 Assets
  • 还在主队列上尝试了上述两种解决方案异步/同步

似乎无论我在做什么,都不可能在触发识别后触发播放任何类型的音频(不确定它是否特别是 AVCaptureSessionSFSpeechAudioBufferRecognitionRequest/SFSpeechRecognitionTask...)

有什么想法吗? Apple even recommends playing a "listening" sound effect (并用 Siri 自己做)但我找不到任何引用/示例来说明如何实际操作...(他们的“SpeakToMe”示例不播放声音)

  • 我可以在触发 session 之前播放声音,它确实有效(在播放声音完成后开始 session 时)但有时在实际开始识别时会有延迟(主要是在使用 BT 耳机并从不同的 AudioSession 类别 - 我没有完成事件...) - 因此我需要一种在录音实际开始时播放声音的方法,而不是在它触发和交叉手指之前它不会延迟开始它...

最佳答案

好吧,显然必须遵循一堆“规则”才能成功开始语音识别 session 并仅在(之后)识别真正开始时才发挥“聆听”效果。

  1. 必须在主队列上调用 session 设置和触发。所以:

    DispatchQueue.main.async {
        speechRequest = SFSpeechAudioBufferRecognitionRequest()
        task = recognizer.recognitionTask(with: speechRequest, delegate: self)
        capture = AVCaptureSession()
        //.....
        shouldHandleRecordingBegan = true
        capture?.startRunning()
    }
    
  2. “聆听”效果应该是通过AVPlayer播放,而不是作为系统声音。

  3. 知道我们肯定录音的最安全的地方是在 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)
    }
    
  4. 结束识别效果要容易得多:

    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/

相关文章:

iphone - 创建自定义 slider 的方法

iphone - NSPredicate 不工作

c# - Windows 8.1 和 Windows Phone 8 中的语音识别

python - Python 中的语音或非语音检测

ios - 多次触发 MapBox regionDidChangeAnimated

ios - Xamarin.iOS 上的启动屏幕未显示。而是显示蓝屏

ios - 斯坦福cs193p Fall 2011 course第9讲有错?

ios - 刷新时,UI TableView 以错误的顺序使可重用单元出队

iphone - 绘制隐藏在半透明 View 下的阴影?

ios - iPhone 5 上的语音识别