Reputation: 647
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.
Upvotes: 0
Views: 3787
Reputation: 41
using pygame and pyttsx3 without tkinter
from pygame import mixer
import pyttsx3
engine = pyttsx3.init()
say = 'getting details of current voice'
voices = engine.getProperty('voices')
# engine.setProperty('volume',1.0)
engine.setProperty('voice', voices[1].id)
engine.setProperty('rate', 200) # setting up new voice rate
outfile = "temp.wav"
engine.save_to_file(say, outfile)
engine.runAndWait()
mixer.init()
mixer.music.load("temp.wav")
mixer.music.play()
def stop():
mixer.music.stop()
def pause():
mixer.music.pause()
def unpause():
mixer.music.unpause()
while True:
print("Press 'p' to pause, 'r' to resume")
print("Press 'e' to exit the program")
query = input(" ")
if query == 'p':
pause()
elif query == 'r':
unpause()
elif query == 'e':
mixer.music.stop()
break
Upvotes: 0
Reputation: 46761
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()
Upvotes: 1