简体   繁体   中英

Stop recognition in Swift3 without stop word

I'm attempting to simplify usage of the Speech framework in a textview. I can easily start the speech recognition process with code based on entering the textview, startup code or other actions. However, I also want to END the speech recognition without user touches. I have not been able to find anything in the Speech framework to indicate that there are methods available to do this. I have crafted a way to accomplish it by defining a word to be the trigger to stop transcription and then to remove the word from the transcription. It does work, but of course the user can never speak that word. Is there a better way to handle this concept? iOS 10, Swift 3, Xcode 8.2.1

Here's the subset of code for the recognitionTask:

private var bufferedString = String()
private var stopWord = "myStopWord"

recognitionRequest.shouldReportPartialResults = true
let startText = self.sayTextView.text
bufferedString = ""

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

    if let result = result {

        self.bufferedString = startText! + result.bestTranscription.formattedString
            self.sayTextView.text = self.bufferedString
            finished = result.isFinal

    }//if let result

    //for testing
    self.stopWord = "Relationship"
    //for testing

    if self.bufferedString.lowercased().contains(self.stopWord.lowercased()) {
        print("buffered string contains \(self.stopWord)")

        if let stopWordRange = self.bufferedString.lowercased().range(of: self.stopWord.lowercased()) {
            self.bufferedString.replaceSubrange(stopWordRange, with: "")
            self.sayTextView.text = self.bufferedString
        }//if let

        self.stopRecording(self)

    }//if contains - look for stopWord

    if error != nil || finished {

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

        self.recognitionRequest = nil
        self.recognitionTask = nil
        self.startRecordingButton.isEnabled = true

    }//if error
})//recognitionTask resultHandler

It seems that isFinal flag doesn't became true when user stops talking as expected. I guess this is a wanted behaviour by Apple, because the event "User stops talk" is an undefined event.

I believe that the easiest way to achieve your goal is the follow:

  • You have to estabilish an "interval of silence" that means if the user doesn't talk for a time greater than your interval he has stopped talking (ie 2 seconds).

  • Create a Timer at the beginning of the audio session:

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

  • when you get new transcriptions in recognitionTask invalidate and restart your timer

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

  • if the timer expires this means the user doesn't talk from 2 seconds. You can safely stop Audio Session and exit

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM