Python Text to Speech in Macintosh
Asked Answered
D

4

14

Are there any libraries in Python that does or allows Text To Speech Conversion using Mac Lion's built in text to speech engine? I did google but most are windows based. I tried pyttx. I tried to run

import pyttsx
engine = pyttsx.init()
engine.say('Sally sells seashells by the seashore.')
engine.say('The quick brown fox jumped over the lazy dog.')
engine.runAndWait()

But I get these errors

File "/Users/manabchetia/Documents/Codes/Speech.py", line 2, in <module>
    engine = pyttsx.init()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pyttsx-1.0.egg/pyttsx/__init__.py", line 39, in init
    eng = Engine(driverName, debug)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pyttsx-1.0.egg/pyttsx/engine.py", line 45, in __init__
    self.proxy = driver.DriverProxy(weakref.proxy(self), driverName, debug)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pyttsx-1.0.egg/pyttsx/driver.py", line 64, in __init__
    self._module = __import__(name, globals(), locals(), [driverName])
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pyttsx-1.0.egg/pyttsx/drivers/nsss.py", line 18, in <module>
ImportError: No module named Foundation

How do I solve these errors?

Duty answered 6/10, 2012 at 9:39 Comment(10)
Surely you can just use the OSX say command?Grooms
@MartijnPieters: I did google and tried pyttx but i get errors.Duty
@ManabChetia: That is a material difference, now you have a practical question! :-)Ureter
Foundation is part of the pyobjc library; did you install it? It comes by default with the system python, but I see you installed your own Python 2.7.Ureter
@MartijnPieters: I have not installed it. So I need to type in easy_install pyobjc now?Duty
@ManabChetia: Yup, looks like it.Ureter
@MartijnPieters: Still Same errors.Duty
@ManabChetia: Then you didn't install PyObjC into the right python installation. Double-check what python is used when you run easy_install.Ureter
@MartijnPieters: I get these pyobjc 2.3 is already the active version in easy-install.pth. Please help.Duty
@ManabChetia: Check the python path of easy_install: head `which easy_install`Ureter
M
44

Wouldn't it be much simpler to do this?

from os import system
system('say Hello world!')

You can enter man say to see other things you can do with the say command.

However, if you want some more advanced features, importing AppKit would also be a possibility, although some Cocoa/Objective C knowledge is needed.

from AppKit import NSSpeechSynthesizer
speechSynthesizer = NSSpeechSynthesizer.alloc().initWithVoice_("com.apple.speech.synthesis.voice.Bruce")
speechSynthesizer.startSpeakingString_('Hi! Nice to meet you!')

If you would like to see more things you can do with NSSpeechSynthesizer take a look at Apple's documentation: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSSpeechSynthesizer_Class/Reference/Reference.html

Malathion answered 6/10, 2012 at 16:12 Comment(8)
if hello world is in a variable how do i make say speak it? I tried AppKit but it's not available. `easy_install' was not able to do it either. how do i do that?Duty
If you want to pass a variable to the say command, you could do this: str = "Test" system('say %s' % (str))Malathion
The code snippet in this answer is slightly off. .alloc is a function, so it should be .alloc()What
Including an apostrophe in the string may cause this to not work. For example trying to do system("Can't touch this") will run without an error, but not actually say anything out loud.Chandelier
@ProQ normal shell quoting rules apply of course. You could embed that string in literal quotes for example (like you would normally have to)Malathion
So then doing system('say "{}"'.format(words)) seems to be the way to goChandelier
Another odd thing about the system option is that it doesn't appear to work with bluetooth headphones. YouTube plays just fine, but I hear nothing when running this command. If I turn off bluetooth, I hear it just fine.Chandelier
Does that also happen if you change the default audio source? I'm not behind a Mac rn, but maybe there is option within say to change it.Malathion
C
13

If you are targeting Mac OS X as your platform - PyObjC and NSSpeechSynthesizer is your best bet.

Here is a quick example for you

#!/usr/bin/env python

from  AppKit import NSSpeechSynthesizer
import time
import sys


if len(sys.argv) < 2:
   text = raw_input('type text to speak> ')
else:
   text = sys.argv[1]

nssp = NSSpeechSynthesizer

ve = nssp.alloc().init()

for voice in nssp.availableVoices():
   ve.setVoice_(voice)
   print voice
   ve.startSpeakingString_(text)

   while not ve.isSpeaking():
      time.sleep(0.1)

   while ve.isSpeaking():
      time.sleep(0.1)

Please note that AppKit module is part of PyObjC bridge and should be already installed on your Mac. No need to install it if you are using OS provided python (/usr/bin/python)

Conchiferous answered 20/2, 2013 at 6:33 Comment(1)
For more detail on how to use the Cocoa Speech Synthesizer interface (e.g. what does setRate_'s argument mean?), have a look at Apple's Developer documentation: developer.apple.com/documentation/appkit/nsspeechsynthesizerPennyroyal
S
1

This might work:

import subprocess
subprocess.call(["say","Hello World! (MESSAGE)"])
Salangia answered 7/2, 2017 at 3:0 Comment(0)
C
0

As an alternative, you can use StyleTTS2. It's fairly close to the state-of-the-art (as of 2024) in TTS, and this Python package means you can just do pip install styletts2 and use it in your Python code like how it's specified in the docs! It can be used on machines with or without GPU. The PyPi page: https://pypi.org/project/styletts2/

Chirm answered 24/6 at 19:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.