mklement0 / speak.awf

An Alfred 3 workflow that uses macOS's TTS (text-to-speech) feature to speak text aloud.
36 stars 2 forks source link

How to select a Siri voice (other language) if it is not your default? #1

Open mvaneijgen opened 4 years ago

mvaneijgen commented 4 years ago

For most of my work I research in english so that is my main voice on my machine, but I've created a custom Automator service which also speaks in Dutch if I need it. The problem is that the Automator team over at Apple has not been brieft to update the voices list to reflect all the new Siri voices. Now I've found your plugins and I'm coming form https://github.com/mklement0/voices/issues/4 but really like this Alfred workflow, fits right in with my other workflows.

The only problem is that if a Siri voice is not my default I can't have it play with this workflow. I like to convert text to speech in both English US the Siri voice I like is "Nora Siri" which can be found listed in /System/Library/Speech/Voices/NoraSiri.SpeechVoice and the Dutch voice which is called "Klaar Siri". As I said earlier if the voices is select as default within Settings > Accessibility > Speech this app works great, but I can't tell your app to speak with "Klaar Siri" even though that is what the name is called in your workflow when it is selected as default.

I've created a small screen cast to further illustrate that issue

Video The error I got

WARNING:
  Failed to restart the speech-synthesis server.
  While the `say` utility will reflect the new default voice instantly,
  the text-to-speech feature may not use the new voice until after a reboot.
WARNING: 'Klaar Siri' is not an installed voice.
RubenBenBen commented 4 years ago

Hey @mvaneijgen , I'm trying to use siri voices through terminal as well, but it seems that apple doesn't allow it? I've tried using the Arthur Siri voice through its bundle id instead of name, say -v com.apple.speech.synthesis.voice.custom.siri.arthur.premium "hello" , and it gives me error Open speech channel failed: -86 . If you use it with other non-siri voices, it works fine. say -v com.apple.speech.synthesis.voice.tom.premium "hello"

mvaneijgen commented 4 years ago

Same here, still no luck. It seems indeed that Apple is just blocking it somehow.

If you don't mind me asking @RubenBenBen how do you get the bundle ID if a particular voice? Is there a way to list them all?

mklement0 commented 4 years ago

Thanks for looking into this, and sorry for being silent so far - I plan to look into this soonish, but @RubenBenBen's finding is not encouraging.

You can find the bundle IDs as follows:

For a given voice:

/usr/libexec/PlistBuddy -c 'print CFBundleIdentifier' /System/Library/Speech/Voices/NoraSiri.SpeechVoice/Contents/Info.plist

For all voices:

ls /System/Library/Speech/Voices/*.SpeechVoice/Contents/Info.plist | xargs -n 1  /usr/libexec/PlistBuddy -c 'print CFBundleIdentifier'

mklement0 commented 4 years ago

Unfortunately, as of macOS 10.15.4, this appears not to be possible, due to lack of system API support - see this Stack Overflow question.

mvaneijgen commented 4 years ago

I see, thanks for looking in to it! This is better than me hitting a wall each time I think "this should be possible, right?" and finding nothing online. Now I know at least that others have the same issue.

Only fix I can think of now, is writing an Apple script that changes the selected voice and than speaks the text, but that seems like a lot of hassle and I also would still like to convert text to .aiff/.mp3 files, which is also something that is not possible with the Siri voices.

mklement0 commented 4 years ago

To be clear, @mvaneijgen, it was I who posted the Stack Overflow question, but I hope it'll attract someone more knowledgable than me about macOS system APIs to either definitely confirm the lack of support or provide a solution.

AppleScript doesn't offer a solution either, from what I can tell:

say "Who am I?" using "NoraSiri"  # doesn't work; neither does use of a bundle ID
RubenBenBen commented 4 years ago

@mvaneijgen I tried a simple python script to change the voice with mouse and then say something, while recording it with quicktime, but it produces some serious glitches... such as: -hotkeys on all apps stop working properly -when you open and listen to the recording, the last word of every sentence said is repeated twice... This happens if you use single script for switching and saying. If you just switch with script, then close python and say the text manually, it works okay, but then it loses the point of writing the script. Please let me know if you maybe think of some solution to this.