Как использовать Pyttsx в потоке Python
Я работаю с pyttsx3
для преобразования текста в речь. Я понял, что могу использовать это в потоке (или я делаю что-то не так). Ты знаешь почему?
Пример кода:
from threading import Thread
import pyttsx3
def myfunc():
engine = pyttsx3.init()
engine.say("ok")
engine.runAndWait()
t = Thread(target=myfunc)
t.start()
Ошибка:
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/python3/3.6.4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "test.py", line 9, in myfunc
engine.runAndWait() #blocks
File "/usr/local/lib/python3.6/site-packages/pyttsx3/engine.py", line 188, in runAndWait
self.proxy.runAndWait()
File "/usr/local/lib/python3.6/site-packages/pyttsx3/driver.py", line 204, in runAndWait
self._driver.startLoop()
File "/usr/local/lib/python3.6/site-packages/pyttsx3/drivers/nsss.py", line 33, in startLoop
AppHelper.runConsoleEventLoop()
File "/usr/local/lib/python3.6/site-packages/PyObjCTools/AppHelper.py", line 241, in runConsoleEventLoop
nextfire = nextfire.earlierDate_(soon)
AttributeError: 'NoneType' object has no attribute 'earlierDate_'
2 ответа
Кажется, ошибка в том, что он не работает в потоках на OSX. Вот несколько примеров, которые могут хорошо работать:
Если вам просто нужно конвертировать текст в речь, вы можете использовать os.system('say %s')
:
import os
def myfunc():
os.system('say ok')
gTTS или Google TextToSpeech engine поддерживает 64 языка, включая итальянский. Использование:
from gtts import gTTS
import os
tts = gTTS(text='Good morning', lang='it')
tts.save("good.mp3")
os.system("mpg321 good.mp3")
Я думаю, что pyttsx3 не может издавать звук в нескольких потоках (можно издавать звук только один раз). Если вы хотите воспроизвести звук в нескольких потоках, система Macos должна использовать команду say.
Другие операционные системы также должны иметь соответствующие команды
import sys
import os
import threading
print('threading1:',threading.activeCount())
text = 'Please start'
def myfunc():
while True:
# os.system('say another')
# os.system('say -v Daniel "another"')
# os.system('say -v Daniel "[[rate 160]] another"') # 速度默认200
os.system('say -v Daniel -r 140 "{}"'.format(text))
os.system('say -v Samantha -r 140 "{}"'.format(text))
# print(111)
loopThread = threading.Thread(target=myfunc, name='backgroundMusicThread')
loopThread.daemon = True
loopThread.start()
print('threading2:',threading.activeCount())
while True:
text = input('input:\n')
if text == 'end':
sys.exit()