Open TypicalHog opened 5 years ago
That code snippet doesn't work for me. I ended up doing the following:
try:
tts_engine = pyttsx3.init()
temp_list = []
for i in tts_engine.getProperty('voices'):
if i.name not in self.combobox_voice['values']:
temp_list.append(i.name)
self.combobox_voice['values'] = temp_list
except:
print('error')
It seems to me that you're improperly assigning the voices to the combobox.
Perhaps you could supply me with a complete example and I could be of further help.
Ok, I got 3 voices when I ran this program.
import pyttsx3
from time import sleep
try:
tts_engine = pyttsx3.init()
for i in tts_engine.getProperty('voices'):
print(i.name)
except:
print('error')
sleep(60)
However, when I compiled it with PyInstaller I got only 2 voices (as I anticipated). I built it with these parameters:
pyinstaller -F test2.py --hidden-import=pyttsx3.drivers --hidden-import=pyttsx3.drivers.dummy --hidden-import=pyttsx3.drivers.espeak --hidden-import=pyttsx3.drivers.nsss --hidden-import=pyttsx3.drivers.sapi5
Why are you using hidden imports? Those shouldn't be necessary.
I would highly recommend using a .spec file and building your program like that. Below are examples I use for a fun project I've been working on that uses pyttsx3, with generic my_app names. You won't be able to use it as a drop-in replacement for what you're doing, but it should give you something to work with.
Example my_app_build.bat file for building the executable:
pyinstaller --clean --onefile --windowed my_app_build.spec
Example my_app_build.spec file referenced by my build file:
# -*- mode: python -*-
block_cipher = None
a = Analysis(['my_app.py'],
pathex=['C:\\Program Files (x86)\\Windows Kits\\10\\Redist\\ucrt\\DLLs\\x86'],
binaries=[],
datas=[('my_app_icon.ico', '.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
Tree('Images', prefix='Images\\'),
Tree('Sound', prefix='Sound\\'),
a.zipfiles,
a.datas,
name='name_of_my_application',
debug=False,
strip=False,
upx=False,
console=False, icon='my_app_icon.ico' )
Hmm..., I don't specifically import pyttsx3 or it's submodules in my project, but I have apparently done that in an example or two I've run.
Why don't you try the following:
Create a pyttsx_speech_example.py file with the following code:
import pyttsx3
try:
tts_engine = pyttsx3.init()
for i in tts_engine.getProperty('voices'):
print(i.name)
input('Press enter to exit.')
except:
print('error')
Create a pyttsx_speech_example.bat file with this command:
pyinstaller --onefile --windowed pyttsx_speech_example.spec --clean
Create a pyttsx_speech_example.spec file with these parameters:
# -*- mode: python -*-
from PyInstaller.utils.hooks import collect_submodules
block_cipher = None
my_hidden_imports = collect_submodules('pyttsx3')
a = Analysis(['pyttsx_speech_example.py'],
pathex=['C:\\Program Files (x86)\\Windows Kits\\10\\Redist\\ucrt\\DLLs\\x64'],
binaries=[],
datas=[],
hiddenimports=my_hidden_imports,
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
name='pyttsx_speech_example',
debug=False,
strip=False,
upx=False,
console=True)
You can remove the contents of the pathex parameter, if you don't have the Windows 10 SDK installed. Your program just won't likely run correctly on other computers.
The code you posted above does work, but the 3rd voice is still not there when I run the .exe.
Assuming, the code works, and it lists the 3rd voice correctly.
That would make me take a serious look at pyinstaller as the code works, but the compiled executable doesn't.
I would recommend reviewing this page https://pythonhosted.org/PyInstaller/hooks.html. Then post an issue here https://github.com/pyinstaller/pyinstaller/issues. In the event that someone there might be able to help you track down the issue.
I've reviewed the code as pertaining to how it uses the SAPI driver for Windows and loads the voice(s). The SAPI5.py file in the driver folder specifies a few common voices, but those variables aren't used to load the voice(s).
You may need to create a hook, or add the additional voice as a data file and load it manually, or something else. As far as I can tell it should "just work" with the additional voice(s).
I successfully installed the English (Great Britain) language-pack and it added the Hazel voice to my list of voices. https://support.microsoft.com/en-us/help/22805 I had to go into the language settings and choose download language pack to get it to install.
When I go to Settings->Ease of Access->Narrator->Choose a Voice I get several voices to choose from. Including George and Susan.
Interestingly enough, only Microsoft David, Zira, and Hazel show up when I run the code mentioned previously. I'm guessing, because those are the only SAPI5 voices that are installed.
When I compile the code with no special additions, etc. with pyinstaller. It lists those 3 voices.
Microsoft David Desktop - English (United States)
Microsoft Hazel Desktop - English (Great Britain)
Microsoft Zira Desktop - English (United States)
Press enter to exit.
Example that prints the above and uses the female british voice to say "This is just a test":
import pyttsx3
try:
tts_engine = pyttsx3.init()
voices = tts_engine.getProperty('voices')
for voice in voices:
print(voice.name)
tts_engine.setProperty('voice', voices[1].id)
tts_engine.say('This is just a test.')
tts_engine.runAndWait()
input('Press enter to exit.')
except:
print('error')
Maybe it has something to do with the fact the voice is from a 3rd party and not officially from Microsoft. Anyway, thank You so much for all the time you took to look into this problem. I might try to find a solution by messing with PyInstaller some more in the future.
Ok, I got 3 voices when I ran this program.
import pyttsx3 from time import sleep try: tts_engine = pyttsx3.init() for i in tts_engine.getProperty('voices'): print(i.name) except: print('error') sleep(60)
However, when I compiled it with PyInstaller I got only 2 voices (as I anticipated). I built it with these parameters:
pyinstaller -F test2.py --hidden-import=pyttsx3.drivers --hidden-import=pyttsx3.drivers.dummy --hidden-import=pyttsx3.drivers.espeak --hidden-import=pyttsx3.drivers.nsss --hidden-import=pyttsx3.drivers.sapi5
thxxxxxx you are king
I successfully installed the English (Great Britain) language-pack and it added the Hazel voice to my list of voices. https://support.microsoft.com/en-us/help/22805 I had to go into the language settings and choose download language pack to get it to install.
When I go to Settings->Ease of Access->Narrator->Choose a Voice I get several voices to choose from. Including George and Susan.
Interestingly enough, only Microsoft David, Zira, and Hazel show up when I run the code mentioned previously. I'm guessing, because those are the only SAPI5 voices that are installed.
When I compile the code with no special additions, etc. with pyinstaller. It lists those 3 voices.
Microsoft David Desktop - English (United States) Microsoft Hazel Desktop - English (Great Britain) Microsoft Zira Desktop - English (United States) Press enter to exit.
Example that prints the above and uses the female british voice to say "This is just a test":
import pyttsx3 try: tts_engine = pyttsx3.init() voices = tts_engine.getProperty('voices') for voice in voices: print(voice.name) tts_engine.setProperty('voice', voices[1].id) tts_engine.say('This is just a test.') tts_engine.runAndWait() input('Press enter to exit.') except: print('error')
I have also encountered this problem and I found the solution
https://www.ghacks.net/2018/08/11/unlock-all-windows-10-tts-voices-system-wide-to-get-more-of-them/
After I finally got my program to work with PyInstaller with the help of this, another issue arose. When I run the .py file there are 3 voices (2nd one has been manually installed), but when I run the .exe created by PyInstaller there are only 2 default voices (as seen in the images below).
This piece of code runs fine, just refuses to find the missing voice:
I would greatly appreciate any suggestions that may lead to a fix or at least a better understanding of this problem.