Open whogben opened 4 years ago
Issue-Label Bot is automatically applying the label bug
to this issue, with a confidence of 0.52. Please mark this comment with :thumbsup: or :thumbsdown: to give our bot feedback!
Links: app homepage, dashboard and code for this bot.
not sure if this is a bug or there's a different approach
I not really familar with espeak but I don't understand how this could work.
For example, with espeak implementation, the sentence is generated and played with aplay
command. So, I don't see how the module can stop play the sound.
Another problem, the stop() command call _espeak.IsPlaying()
but as espeak no longer play sound due to the change the parameter AUDIO_OUTPUT_RETRIEVAL the function will always return False... and to stop() method do nothing.
All those changes seem to come with save_to_file()
... Perhaps an old version work better...
I worked out a method to stop the text to speech. Basically, if you press 'q' the test to speech stops. It uses multithreading so the code execution doesn't pause during the talking:
import multiprocessing
import pyttsx3
import keyboard
def sayFunc(phrase):
engine = pyttsx3.init()
engine.setProperty('rate', 160)
engine.say(phrase)
engine.runAndWait()
def say(phrase):
if __name__ == "__main__":
p = multiprocessing.Process(target=sayFunc, args=(phrase,))
p.start()
while p.is_alive():
if keyboard.is_pressed('q'):
p.terminate()
else:
continue
p.join()
say("this process is running right now")
I have made the test. On Linux (eSpeak), the program returns but the whole text will be read.
And, if I add a started-word
callback, the callback is called for each word before I heard the first word.
engine.connect("started-word", on_word)
In fact, after a short evaluation, I no longer use this module.
It's sad because I like the libraries based approach of pyttsx module. Even if I chose to not use it, thank to all the maintainers, this library seem appreciated.
Any answer regarding the given question. i am also facing the same problem.
That is my solution:
import multiprocessing
import pyttsx3
import time
from threading import Thread
def threaded(fn):
def wrapper(*args, **kwargs):
thread = Thread(target=fn, args=args, kwargs=kwargs)
thread.start()
return thread
return wrapper
def speak(phrase):
engine = pyttsx3.init()
engine.say(phrase)
engine.runAndWait()
engine.stop()
def stop_speaker():
global term
term = True
t.join()
@threaded
def manage_process(p):
global term
while p.is_alive():
if term:
p.terminate()
term = False
else:
continue
def say(phrase):
global t
global term
term = False
p = multiprocessing.Process(target=speak, args=(phrase,))
p.start()
t = manage_process(p)
if __name__ == "__main__":
say("this process is running right now")
time.sleep(1)
stop_speaker()
say("this process is running right now")
time.sleep(1.5)
stop_speaker()
I got the decorator function from this https://stackoverflow.com/a/19846691 post. And the idea how to terminate the Process from @z3r0flag.
I had no problems so far with my early implementation within my home assistant. If someone comes up with a more efficient/structured solution i would be very happy if it is shared with me.
thanks a you guys for providing your solutions ^-^
`#Hi`` Guys, I added a change of voice to the above code and it works perfectly.
import multiprocessing
import pyttsx3
import time
from threading import Thread
def threaded(fn):
def wrapper(*args, **kwargs):
thread = Thread(target=fn, args=args, kwargs=kwargs)
thread.start()
return thread
return wrapper
def speak(phrase,vc):
engine = pyttsx3.init()
voices = engine.getProperty("voices")
engine.setProperty('voice', voices[vc].id)
engine.say(phrase)
engine.runAndWait()
engine.stop()
def stop_speaker():
global term
term = True
t.join()
@threaded
def manage_process(p):
global term
while p.is_alive():
if term:
p.terminate()
term = False
else:
continue
def say(phrase,vc):
global t
global term
term = False
p = multiprocessing.Process(target=speak, args=(phrase,vc))
p.start()
t = manage_process(p)
if __name__ == "__main__":
say("this process is running right now",1)#vc is voice ID
time.sleep(4)
stop_speaker()
say("this process is running right now",0)
time.sleep(4)
stop_speaker()
That is my solution:
import multiprocessing import pyttsx3 import time from threading import Thread def threaded(fn): def wrapper(*args, **kwargs): thread = Thread(target=fn, args=args, kwargs=kwargs) thread.start() return thread return wrapper def speak(phrase): engine = pyttsx3.init() engine.say(phrase) engine.runAndWait() engine.stop() def stop_speaker(): global term term = True t.join() @threaded def manage_process(p): global term while p.is_alive(): if term: p.terminate() term = False else: continue def say(phrase): global t global term term = False p = multiprocessing.Process(target=speak, args=(phrase,)) p.start() t = manage_process(p) if __name__ == "__main__": say("this process is running right now") time.sleep(1) stop_speaker() say("this process is running right now") time.sleep(1.5) stop_speaker()
I got the decorator function from this https://stackoverflow.com/a/19846691 post. And the idea how to terminate the Process from @z3r0flag.
I had no problems so far with my early implementation within my home assistant. If someone comes up with a more efficient/structured solution i would be very happy if it is shared with me.
I can't understand why but when I'm calling these 2 functions in another Python file
def on_publicmsg(connection, event):
"""
Called when a public message is received in the channel.
Prints the message and triggers the dubbing function.
"""
print(f"Message from {event.source.nick}: {event.arguments[0]}")
chat_message = event.arguments[0]
say(chat_message)
time.sleep(1)
stop_speaker()
It's just not working. It's opening the new tkinter window when the process is starting, it's even not starting the speech
I am trying to interrupt pyttsx3 while it is talking to say something else.
I am using pyttsx3 with an external event loop, which works great - except for not being able to stop the speech and interrupt it. Here is some code demonstrating the issue:
Expected behavior: "interrupting cow" is said partway through the "knock knock who's there" Actual behavior: "knock knock who's there" is said, and "interrupting cow" is never said
Does anyone have a workaround that would make it possible to interrupt pyttsx3 and have it speak something else? Am I misunderstanding the docs on this / is there a different approved way to interrupt it?
I've tried using endLoop and startLoop(false) again to create a new loop, but no luck there - that just causes "interrupting cow" to be said after the sentence, instead of interrupting it.