Unwanted callback from `SFSpeechRecognizer` `recognitionTask` at ~30s mark

和自甴很熟 提交于 2020-01-25 00:19:09

问题


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" )
            :

... I observe:

:
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

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

result is nil for this last callback.

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

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.

Complete code is here.

Can anyone see what's going wrong?


回答1:


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
    }

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.

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

However the closures still get hit after stopListening.

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.



来源:https://stackoverflow.com/questions/58774314/unwanted-callback-from-sfspeechrecognizer-recognitiontask-at-30s-mark

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!