Search code examples
pythonmultithreadingspeech-recognition

Ending a Thread in python (also using callbacks)


I was working with speech recognition software and found a way to have the speech recognizer listen indefinitely such that there is a smoother user experience. I have a kickout command that should end the program if the word terminate is ever said. The code is shown below...

import speech_recognition as sr
import sys

def callback(recognizer, audio):                          # this is called from the background thread
    try:
        print("You said " + recognizer.recognize_google(audio))
        if(text == 'Terminate' or  text == 'terminate'):
             sys.exit()
    except:
        pass
r = sr.Recognizer()
r.listen_in_background(sr.Microphone(), callback)
import time
while True: time.sleep(0.1) 

I have tried setting all the threads to daemon and have tried using Os.exit(). Please let me know if there is any other things I should try.


Solution

  • Disclaimer: this is untested. I don't have this package installed.

    However, just by reading the source code at https://github.com/Uberi/speech_recognition/blob/master/speech_recognition/__init__.py I discovered this:

    The call listen_in_background returns a reference to the stopper() function, which terminates the listening thread in an acceptably nice way. In order to leverage this, try the following:

    import time
    import speech_recognition as sr
    import sys
    
    stop_it = False
    
    def callback(recognizer, audio):  # this is called from the background thread
        global stop_it
        try:
            print("You said " + recognizer.recognize_google(audio))
            if text.lower() == 'terminate':
                stop_it = True
        except:
            pass
    
    r = sr.Recognizer()
    just_try_and_stop_me = r.listen_in_background(sr.Microphone(), callback)
    
    while True:
        if stop_it:
            just_try_and_stop_me(wait_for_stop=True)
            break
        time.sleep(0.1)
    

    NB: Globals are kinda hackish, so for your next challenge, try to encapsulate all this in a proper class. But for now, this should be pretty good for starters. Also, there is no need for parentheses around your condition (this isn't C). Also, .lower() method on a string will return the lowercase version for simpler case-insensitive comparisons.