在大约30秒的时间从`SFSpeechRecognizer``recognitionTask`进行的不必要的回调 [英] Unwanted callback from `SFSpeechRecognizer` `recognitionTask` at ~30s mark

查看:277
本文介绍了在大约30秒的时间从`SFSpeechRecognizer``recognitionTask`进行的不必要的回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我检查了邮票中来自SFSpeechRecognizer recognitionTask回调的回调(在macOS上):

If I inspected the stamps for callbacks from the SFSpeechRecognizer recognitionTask callback (on macOS):

        recognitionTask = speechRecognizer.recognitionTask( with: recognitionRequest )
        { result, error in
            // if more than two seconds elapsed since the last update, we send a notification
            NSLog( "speechRecognizer.recognitionTask callback" )
            :

...我观察到

:
2019-11-08 14:51:00.35 ... speechRecognizer.recognitionTask callback
2019-11-08 14:51:00.45 ... speechRecognizer.recognitionTask callback

2019-11-08 14:51:32.31 ... speechRecognizer.recognitionTask callback

即在我上一次发声后大约30秒,还有另外一个不需要的回叫.

i.e. There is an additional unwanted callback approximately 30 seconds after my last utterance.

resultnil.

接近30秒这一事实对我来说意味着它代表了最大超时时间.

The fact that it's close to 30 seconds suggests to me it is representing a max-timeout.

我不希望超时,因为我已经手动关闭了会话(在5秒左右,通过单击一个按钮):

I'm not expecting a time out, because I have manually shutdown my session (at around the 5s mark, by clicking a button):

    @objc
    func stopRecording()
    {
        print( "stopRecording()" )

        // Instructs the task to stop accepting new audio (e.g. stop recording) but complete processing on audio already buffered.
        // This has no effect on URL-based recognition requests, which effectively buffer the entire file immediately.
        recognitionTask?.finish()

        // Indicate that the audio source is finished and no more audio will be appended
        recognitionRequest?.endAudio()

        //self.recognitionRequest = nil

        audioEngine.stop()

        audioEngine.inputNode.removeTap( onBus: 0 )

        //recognitionTask?.cancel()

        //self.recognitionTask = nil

        self.timer?.invalidate()

        print( "stopRecording() DONE" )
    }

有很多注释掉的代码,因为在我看来,有些程序无法关闭,但我无法弄清楚.

There's a lot of commented out code, as it seems to me there is some process I'm failing to shut down, but I can't figure it out.

完整代码为此处.

任何人都可以看到出了什么问题吗?

Can anyone see what's going wrong?

推荐答案

注意:在此解决方案中,销毁序列启动后,仍然存在一个不需要的回调.因此,我暂不接受答案.也许对于这个问题有一个更优雅的解决方案,或者有人可以阐明观察到的现象.

NOTE: in this solution, there is still one unwanted callback immediately after the destruction sequence is initiated. Hence I'm not going to accept the answer yet. Maybe there exists a more elegant solution to this problem, or someone may shed light on observed phenomena.

以下代码可以完成这项工作:

The following code does the job:

        is_listening = true
        recognitionTask = speechRecognizer.recognitionTask( with: recognitionRequest )
        { result, error in
            if !self.is_listening {
                NSLog( "IGNORED: speechRecognizer.recognitionTask callback" )
                return
            }

            // if more than two seconds elapsed since the last update, we send a notification
            self.timer?.invalidate()
            NSLog( "speechRecognizer.recognitionTask callback" )
            self.timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { _ in
                if !self.is_listening {
                    print( "IGNORED: Inactivity (timer) Callback" )
                    return
                }
                print( "Inactivity (timer) Callback" )
                self.timer?.invalidate()
                NotificationCenter.default.post( name: Dictation.notification_paused,  object: nil )
                //self.stopRecording()
            }
        :
    }


    @objc
    func stopRecording()
    {
        print( "stopRecording()" )

        is_listening = false

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

        recognitionRequest?.endAudio()
        recognitionRequest = nil

        timer?.invalidate()
        timer = nil;

        recognitionTask?.cancel()
        recognitionTask = nil
    }

确切的序列来自 https://github.com/2bbb/ofxSpeechRecognizer/blob/master/src/ofxSpeechRecognizer.mm -我不确定订单的敏感程度.

The exact sequence is taken from https://github.com/2bbb/ofxSpeechRecognizer/blob/master/src/ofxSpeechRecognizer.mm -- I'm not sure to what extent it is order sensitive.

对于初学者而言,这种销毁顺序似乎可以消除30秒钟的超时时间?回调.

For starters, that destruction sequence seems to eliminate the 30s timeout? callback.

然而,封包在stopListening之后仍然受到打击.

However the closures still get hit after stopListening.

为解决这个问题,我创建了一个is_listening标志.

To deal with this I've created an is_listening flag.

我有一种直觉,苹果也许应该在框架中内化这种逻辑,但是它起作用了,我是一个快乐的兔子.

I have a hunch Apple should maybe have internalised this logic within the framework, but meh it works, I am a happy bunny.

这篇关于在大约30秒的时间从`SFSpeechRecognizer``recognitionTask`进行的不必要的回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆