3

I want pyttsx to read text from my clipboard, so I can copy a text, and then let the computer read it for me, it works excellent, except its really annoying I can't stop the text to speech as I please, I either have to stop the whole program and restart or let it finish although I've lost interest.

I've tried using engine.startloop and engine.endloop but it just got my code stuck, maybe theres a way to use startloop in a way where I can exit the speech on a button press but I honestly cant figure out how to use startloop.

I've then tried this script:

    import win32com.client as wincl
    speak = wincl.Dispatch("SAPI.SpVoice")
    speak.Speak("Hello World")

again. works great, but I don't know how to stop it mid speech.

oh, and yes I tried using threads, problem is engine.runAndWait() literally makes the speech run and everything else wait.

    import keyboard
    import win32clipboard
    import pyttsx3

    def init():
        print("init")
        def start(text):
            engine = pyttsx3.init()
            #more code here but its just setting the volume and speech rate
            engine.say(text,"txt")
            engine.runAndWait()

        def action():
              win32clipboard.OpenClipboard()
              data = win32clipboard.GetClipboardData()
              win32clipboard.CloseClipboard()
              start(data)

        keyboard.add_hotkey("ctrl+alt", lambda: action())

    init()

so yeah basically, I'm looking for a way to stop text to speech with a hotkey, its fine if its not possible with pyttsx3 but I'd like to use a text to speech module that doesn't require internet as my connection is quiet poor at times haha

1 Answers1

3

I feel really dumb right now, I solved it, I used pynput in my previous attempts, then tried with keyboard, got to the same point I was previously at (couldn't stop the text mid speech)

well anyway, if you are wondering about how to make pyttsx3 shut up with user input... here it is:

def onWord(name, location, length):
    print ('word', name, location, length)
    if keyboard.is_pressed("esc"):
       engine.stop()

    engine.connect('started-word', onWord)

just copy and paste that right above "engine.say('your text')" and the engine will stop the moment you press esc on your keyboard, also make sure to have:

     import keyboard

at the top of your script

  • 1
    Is there a way to do this by speaking into the microphone? Instead of keboard.is_pressed("esc"), could you call the microphone hearing "stop"? – KingT753 Apr 19 '21 at 16:23