Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用线程时不触发Pyttsx3回调_Python_Python 3.x_Text To Speech - Fatal编程技术网

Python 使用线程时不触发Pyttsx3回调

Python 使用线程时不触发Pyttsx3回调,python,python-3.x,text-to-speech,Python,Python 3.x,Text To Speech,我使用线程作为绕过pyttsx3的“运行并等待”默认功能的一种方式,这样我就可以在演讲中打断别人说的话。但是,这会阻止库的回调,因此我无法检测一块文本何时被说出-我必须使用秒数来猜测它 我希望检测的回调是finished outrance,它与self.engine.connect('finished-outrance',self.onEnd)连接。这遵循中给出的示例。当我在真实的程序中使用它时,一个文本块可以有数百个单词长,而下一个文本块只能有几个单词长。我想知道什么时候说一句话,这样程序就可

我使用线程作为绕过pyttsx3的“运行并等待”默认功能的一种方式,这样我就可以在演讲中打断别人说的话。但是,这会阻止库的回调,因此我无法检测一块文本何时被说出-我必须使用秒数来猜测它

我希望检测的回调是finished outrance,它与
self.engine.connect('finished-outrance',self.onEnd)
连接。这遵循中给出的示例。当我在真实的程序中使用它时,一个文本块可以有数百个单词长,而下一个文本块只能有几个单词长。我想知道什么时候说一句话,这样程序就可以自动进入下一个“说”功能

我读过使用多重处理的文章,但我不知道如何做到这一点。有没有办法让回调使用线程?我正在使用Windows10

from threading import Event, Thread
import pyttsx3

class Voice(object):
    def __init__(self, skip, play_beep):
        self.t = None
        self._running = False
        self.engine = pyttsx3.init()
        self.skip = skip
        self.engine.connect('finished-utterance', self.onEnd)

    def onEnd(self, name, completed):
        print('finishing : ', name, completed)
        self.stop()

    def on_finished_utterance(self, name, completed):
        print('END')
        t = Thread(target=self.killme, args=(self.engine), daemon=True)
        t.start()

    def process_speech(self, text):
        self.engine.say(str(text))
        self.engine.startLoop(False)
        while self._running:
            self.engine.iterate()

    def say(self, text, length=2):
        # check if thread is running
        if self.t and self._running:
            # stop it if it is
            self.stop()
        # iterate speech in a thread

        self.t = Thread(target=self.process_speech, args=(text,), daemon=True)
        self._running = True
        self.t.start()

        elapsed_seconds = 0
        poll_interval = .1
        while not self.skip.is_set() and elapsed_seconds < length:
            self.skip.wait(poll_interval)
            elapsed_seconds += poll_interval

    def stop(self):
        self._running = False
        try:
            self.engine.endLoop()
        except:
            pass
        try:
            self.t.join()
        except Exception as e:
            pass

skip = Event()
myVoice = Voice(skip, 0)
myVoice.say("test", 2)
myVoice.say("test two", 2)
从线程导入事件,线程
导入pyttsx3
类声音(对象):
定义初始化(自我、跳过、播放提示音):
self.t=None
self.\u running=False
self.engine=pyttsx3.init()
self.skip=跳过
self.engine.connect('finished-speutation',self.onEnd)
def onEnd(自我、姓名、已完成):
打印('完成:',名称,已完成)
self.stop()
已完成话语的定义(自我、姓名、已完成):
打印('结束')
t=Thread(target=self.killme,args=(self.engine),daemon=True)
t、 开始()
def过程_语音(自我、文本):
self.engine.say(str(text))
self.engine.startOOP(错误)
当self.\u运行时:
self.engine.iterate()
def say(self,text,length=2):
#检查线程是否正在运行
如果self.t和self.\u正在运行:
#如果是的话就停下来
self.stop()
#在线程中迭代语音
self.t=Thread(target=self.process\u speech,args=(text,),daemon=True)
self.\u running=True
self.t.start()
已用秒数=0
轮询间隔=.1
而不是self.skip.is_set()和经过的_秒<长度:
self.skip.wait(轮询间隔)
已用秒数+=轮询间隔
def停止(自):
self.\u running=False
尝试:
self.engine.endLoop()
除:
通过
尝试:
self.t.join()
例外情况除外,如e:
通过
跳过=事件()
myVoice=语音(跳过,0)
我的声音。说(“测试”,2)
我的声音。说(“测试二”,2)
问题:根据
事件触发/结束多个
say()

此实现基于

注意
TTSThread
从实例化开始,一直运行

您必须在
EXIT\uuuu main\uuuu
处调用
.terminate()
,以防止等待


用法1:一次传递多个句子,并自动运行
引擎。对所有句子说(…)

用法2:一句接一句地说,取决于事件“完成的话语”

输出

.say add[1.0]: "Use your h..."
finishing[18.0], delay next sentence 1.5 sec.
__main__ 20.0
.say add[34.0]: "Time will ..."
__main__ 40.0
finishing[51.0], delay next sentence 1.5 sec.
__main__ 60.0
.say add[67.0]: "Strike whi..."
__main__ 80.0
finishing
__main__ 100.0
EXIT __main__

使用Python:3.5测试-pyttsx3版本:2.71

“阻止回调…因此我无法检测文本块何时完成”:我有一个运行的可中断线程版本,但我不清楚您缺少哪个
回调以及您希望如何使用它。你的问题并展示出来。回叫是“完成的话语”。当我在真实的程序中使用它时,一个文本块可以有数百个单词长,而下一个文本块只能有几个单词长。我想知道什么时候说一句话,这样程序就可以自动进入下一个“说”功能。我编辑了这个问题。“自动前进到下一个”说“文本块”:所以你不想“打断正在说的话”,而是想要连续的
说(…
一个文本块列表?还没有测试过这个场景,但这只需要一个简单的
FIFO
。我已经有了处理跳过事件的中断()我希望根据引擎启动/结束多个say()。say()被检测为完成。当我复制/粘贴它们时,你的两个用法对我来说根本不起作用。第一个只说say use your head to save your foots.的第一句话。第二个说同样的话,并打印出
。说添加[1.0]:“使用你的h…”
then main 20/40/60/80/100。我是在新安装的python版本3.5和相同的pyttsx3版本(通过pycharms下载)下完成的pip@bvs:我在Linux上运行,无法使用
Windows 10
进行测试。您简单描述了您的问题以及未获得事件
'finished-outrance'
的问题。包括用法1和美国您的
GitHub问题
尚未得到解答。我认为这是一个解决方案。此外,我尝试实现proposal@bvs:更新我的答案,执行来自
GitHub
的建议,并将整个
引擎
部分移动到同一
线程
中,以防止跨线程事件。如果成功,请尝试第二个实施方案现在生效,但不是第一个。我会奖励你,而我考虑接受。answer@bvs太好了!在用法1中,我忘记了让
\uuu main\uuu
保持活动状态并调用
语音。terminate()
EXIT\uuuu main\uuuu
处。请记住,
TTSThread
将永远运行。更新了我的答案。
from TTS import TTSThread

SAY = ["Use your head to save your feet.", "Time will tell.", "Strike while the iron is hot."]

class Voice(TTSThread):
    def __init__(self):
        super().__init__(rate=115)

if __name__ == "__main__":
    voice = Voice()
    voice.say(SAY)

    # Simulate __main__.is_alive
    count = 0.0
    while True:
        time.sleep(0.1)
        count += 1

        if count >= 100:
            voice.terminate()
            break

print('EXIT __main__'.format())
from TTS import TTSThread
import time

class Voice(TTSThread):
    def __init__(self):
        self.completed = None
        super().__init__(rate=115, event='completed')

    def on_finished_utterance(self, name, completed):
        """
        Overloads `TTSThread.on_finished_utterance`
        which is connected to event 'finished-utterance'
        """
        if len(SAY):
            print('finishing[{}], delay next sentence {} sec.'.format(count, 1.5))
            time.sleep(1.5)
            self.completed.set()
        else:
            print('finishing')


if __name__ == "__main__":
    voice = Voice()

    # Start simulation, `say(...)` while __main__ is running
    voice.completed.set()

    _terminate = 100
    count = 0.0

    while True:
        time.sleep(0.1)
        count += 1

        if voice.completed.is_set():
            voice.completed.clear()

            if len(SAY):
                print('.say add[{}]: "{}..."'.format(count, SAY[0][:10]))
                voice.say(SAY.pop(0))

        if count % 20 == 0:
            print('__main__ {}'.format(count))

        if count >= _terminate:
            voice.terminate()

print('EXIT __main__'.format())
.say add[1.0]: "Use your h..."
finishing[18.0], delay next sentence 1.5 sec.
__main__ 20.0
.say add[34.0]: "Time will ..."
__main__ 40.0
finishing[51.0], delay next sentence 1.5 sec.
__main__ 60.0
.say add[67.0]: "Strike whi..."
__main__ 80.0
finishing
__main__ 100.0
EXIT __main__