Нежелательный обратный вызов из `SFSpeechRecognizer`` translationTask` на отметке ~ 30 с - PullRequest
1 голос
/ 09 ноября 2019

Если я проверял штампы на обратные вызовы от обратного вызова SFSpeechRecognizer recognitionTask (в 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 секунд после моего последнего высказывания.

result равен nil для этого последнего обратного вызова.

Тот факт, что он близок к 30 секундам, подсказывает мне, что этопредставляющий максимальный тайм-аут.

Я не ожидаю тайм-аут, потому что я вручную отключил свой сеанс (около отметки 5 с, нажав кнопку):

    @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" )
    }

Там много закомментированного кода, как мне кажется, есть какой-то процесс, который мне не удается закрыть, но я не могу понять это.

Полный код здесь .

Кто-нибудь может увидеть, что идет не так?

1 Ответ

1 голос
/ 09 ноября 2019

ПРИМЕЧАНИЕ: в этом решении все еще остается один нежелательный обратный вызов сразу после запуска последовательности уничтожения. Поэтому я пока не собираюсь принимать ответ. Возможно, существует более изящное решение этой проблемы, или кто-то может пролить свет на наблюдаемые явления.

Следующий код выполняет работу:

        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 - Я не уверен, насколько он чувствителен к порядку.

Для начала, эта последовательность уничтожения, кажется, устраняет тайм-аут 30 с? обратный вызов.

Однако замыкания все еще получают удар после stopListening.

Чтобы справиться с этим, я создал флаг is_listening.

У меня есть догадка AppleВозможно, следовало бы усвоить эту логику в рамках, но мне это нравится, я счастливый кролик.

...