Is there any way to pause , resume and stop pyttsx3 from speaking?
I've tried many ways but I couldn't find a solution.
Here's the code:
from tkinter import *
import pyttsx3
import threading
root = Tk()
def read():
engine.say(text.get(1.0 , END))
engine.runAndWait()
def stop():
# Code to stop pyttsx3 from speaking
pass
def pause():
# Code to pause pyttsx3
pass
def unpause():
# Code to unpause pyttsx3
pass
engine = pyttsx3.init()
text = Text(width = 65 , height = 20 , font = "consolas 14")
text.pack()
text.insert(END , "This is a text widget\n"*10)
read_button = Button(root , text = "Read aloud" , command = lambda: threading.Thread(target=read, daemon=True).start())
read_button.pack(pady = 20)
pause_button = Button(root , text = "Pause" , command = lambda: threading.Thread(target=pause , daemon = True).start())
pause_button.pack()
unpause_button = Button(root , text = "Unpause" , command = unpause)
unpause_button.pack(pady = 20)
stop_button = Button(root , text = "Stop" , command = threading.Thread(target=stop, daemon = True).start())
stop_button.pack()
mainloop()
What I want is to pause, resume, and stop pyttsx3 whenever I want by clicking the buttons.
Is there any way to achieve this in tkinter?
It would be great if anyone could help me out.
There is no pause and resume function provided by pyttsx3
, but you can simulate these feature by splitting the sentence into words, and then speak word by word. In between words, you can check whether pause, unpause or stop button is clicked and do corresponding action:
from tkinter import *
import pyttsx3
import threading
root = Tk()
class Speaking(threading.Thread):
def __init__(self, sentence, **kw):
super().__init__(**kw)
self.words = sentence.split()
self.paused = False
def run(self):
self.running = True
while self.words and self.running:
if not self.paused:
word = self.words.pop(0)
print(word)
engine.say(word)
engine.runAndWait()
print("finished")
self.running = False
def stop(self):
self.running = False
def pause(self):
self.paused = True
def resume(self):
self.paused = False
speak = None
def read():
global speak
if speak is None or not speak.running:
speak = Speaking(text.get(1.0, END), daemon=True)
speak.start()
def stop():
global speak
if speak:
speak.stop()
speak = None
def pause():
if speak:
speak.pause()
def unpause():
if speak:
speak.resume()
engine = pyttsx3.init()
text = Text(width=65, height=20, font="consolas 14")
text.pack()
text.insert(END, "This is a text widget\n"*10)
read_button = Button(root, text="Read aloud", command=read)
read_button.pack(pady=20)
pause_button = Button(root, text="Pause", command=pause)
pause_button.pack()
unpause_button = Button(root, text="Unpause", command=unpause)
unpause_button.pack(pady=20)
stop_button = Button(root, text="Stop", command=stop)
stop_button.pack()
mainloop()
Update: Using pygame
as the player:
from tkinter import *
import pyttsx3
import pygame
pygame.mixer.init()
engine = pyttsx3.init()
root = Tk()
def read():
outfile = "temp.wav"
engine.save_to_file(text.get('1.0', END), outfile)
engine.runAndWait()
pygame.mixer.music.load(outfile)
pygame.mixer.music.play()
def stop():
pygame.mixer.music.stop()
def pause():
pygame.mixer.music.pause()
def unpause():
pygame.mixer.music.unpause()
text = Text(width=65, height=20, font="consolas 14")
text.pack()
text.insert(END, "This is a text widget\n"*10)
read_button = Button(root, text="Read aloud", command=read)
read_button.pack(pady=20)
pause_button = Button(root, text="Pause", command=pause)
pause_button.pack()
unpause_button = Button(root, text="Unpause", command=unpause)
unpause_button.pack(pady=20)
stop_button = Button(root, text="Stop", command=stop)
stop_button.pack()
mainloop()