SFSpeechRecognizer - 检测话语结束

Tom*_*ner 18 ios sfspeechrecognizer

我正在使用iOS 10内置语音识别来攻击一个小项目.我有使用设备麦克风的工作结果,我的语音被非常准确地识别.

我的问题是每个可用的部分转录都会调用识别任务回调,我希望它能够检测到人们停止说话,并在isFinal属性设置为true的情况下调用回调.它没有发生 - 应用程序无限期地倾听.

SFSpeechRecognizer能够检测句末永远不会消失?

这是我的代码 - 它基于在互联网上找到的示例,它主要是从麦克风源识别所需的样板.我通过添加识别来修改它taskHint.我也设置shouldReportPartialResults为假,但它似乎被忽略了.

    func startRecording() {

    if recognitionTask != nil {
        recognitionTask?.cancel()
        recognitionTask = nil
    }

    let audioSession = AVAudioSession.sharedInstance()
    do {
        try audioSession.setCategory(AVAudioSessionCategoryRecord)
        try audioSession.setMode(AVAudioSessionModeMeasurement)
        try audioSession.setActive(true, with: .notifyOthersOnDeactivation)
    } catch {
        print("audioSession properties weren't set because of an error.")
    }

    recognitionRequest = SFSpeechAudioBufferRecognitionRequest()
    recognitionRequest?.shouldReportPartialResults = false
    recognitionRequest?.taskHint = .search

    guard let inputNode = audioEngine.inputNode else {
        fatalError("Audio engine has no input node")
    }

    guard let recognitionRequest = recognitionRequest else {
        fatalError("Unable to create an SFSpeechAudioBufferRecognitionRequest object")
    }

    recognitionRequest.shouldReportPartialResults = true

    recognitionTask = speechRecognizer?.recognitionTask(with: recognitionRequest, resultHandler: { (result, error) in

        var isFinal = false

        if result != nil {
            print("RECOGNIZED \(result?.bestTranscription.formattedString)")
            self.transcriptLabel.text = result?.bestTranscription.formattedString
            isFinal = (result?.isFinal)!
        }

        if error != nil || isFinal {
            self.state = .Idle

            self.audioEngine.stop()
            inputNode.removeTap(onBus: 0)

            self.recognitionRequest = nil
            self.recognitionTask = nil

            self.micButton.isEnabled = true

            self.say(text: "OK. Let me see.")
        }
    })

    let recordingFormat = inputNode.outputFormat(forBus: 0)
    inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { (buffer, when) in
        self.recognitionRequest?.append(buffer)
    }

    audioEngine.prepare()

    do {
        try audioEngine.start()
    } catch {
        print("audioEngine couldn't start because of an error.")
    }

    transcriptLabel.text = "Say something, I'm listening!"

    state = .Listening
}
Run Code Online (Sandbox Code Playgroud)

Joe*_*ara 18

当用户停止按预期说话时,似乎isFinal标志不会变为真.我想这是Apple的通缉行为,因为"用户停止说话"这一事件是一个未定义的事件.

我相信实现目标的最简单方法是执行以下操作:

  • 你必须建立一个"沉默的间隔".这意味着如果用户没有说话的时间超过你的间隔时间,他就会停止说话(即2秒).

  • 在以下的开头创建一个Timeraudio session:

var timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "didFinishTalk", userInfo: nil, repeats: false)

  • 当您获得recognitionTask无效的新转录并重新启动计时器时

    timer.invalidate() timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "didFinishTalk", userInfo: nil, repeats: false)

  • 如果计时器到期,这意味着用户不会在2秒内通话.您可以安全地停止音频会话并退出

  • FWIW,不是使计时器失效并重新创建计时器,而是可以通过更新其 `fireDate` 属性来延迟它。 (3认同)
  • 为什么苹果会发现这种凝灰岩?只需要实现有用的委托方法。 (2认同)
  • 对我来说似乎是一个重大失败。使用这些预定的计时器感觉就像一个黑客 (2认同)