From c6400931390d05a09d534c7876079ee04926f832 Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Sun, 14 Oct 2018 10:29:02 +0200 Subject: [PATCH] Added Google-based TTS plugin --- platypush/plugins/tts/google.py | 94 +++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 platypush/plugins/tts/google.py diff --git a/platypush/plugins/tts/google.py b/platypush/plugins/tts/google.py new file mode 100644 index 00000000..feefb672 --- /dev/null +++ b/platypush/plugins/tts/google.py @@ -0,0 +1,94 @@ +import subprocess +import tempfile + +from google.cloud import texttospeech + +from platypush.plugins import Plugin, action + +class TtsGooglePlugin(Plugin): + """ + Advanced text-to-speech engine that leverages the Google Cloud TTS API. + See https://cloud.google.com/text-to-speech/docs/quickstart-client-libraries#client-libraries-install-python + for how to enable the API on your account and get your credentials. + + Requires: + + * **google-cloud-texttospeech** - ``pip install google-cloud-texttospeech`` + * **mplayer** - see your distribution docs on how to install the mplayer package + """ + + def __init__(self, language='en-US', voice='en-US-Wavenet-C', gender='FEMALE'): + """ + :param language: Language code, see https://cloud.google.com/text-to-speech/docs/basics for supported languages + :type language: str + + :param voice: Voice type, see https://cloud.google.com/text-to-speech/docs/basics for supported voices + :type voice: str + + :param gender: Voice gender (MALE, FEMALE or NEUTRAL) + :type gender: str + """ + + super().__init__() + self.language = language + self.voice = voice + self.gender = getattr(texttospeech.enums.SsmlVoiceGender, gender.upper()) + + @action + def say(self, text, language=None, voice=None, gender=None): + """ + Say a phrase + + :param text: Text to say + :type text: str + + :param language: Language code override + :type language: str + + :param voice: Voice type override + :type voice: str + + :param gender: Gender override + :type gender: str + """ + + client = texttospeech.TextToSpeechClient() + synthesis_input = texttospeech.types.SynthesisInput(text=text) + + if language is None: + language = self.language + + if gender is None: + gender = self.gender + else: + gender = getattr(texttospeech.enums.SsmlVoiceGender, gender.upper()) + + if voice is None: + voice = self.voice + + voice = texttospeech.types.VoiceSelectionParams( + language_code=language, ssml_gender=gender, + name=voice) + + audio_config = texttospeech.types.AudioConfig( + audio_encoding=texttospeech.enums.AudioEncoding.MP3) + + response = client.synthesize_speech(synthesis_input, voice, audio_config) + + with tempfile.NamedTemporaryFile() as f: + f.write(response.audio_content) + + output = None + errors = [] + cmd = ['mplayer -ao alsa -really-quiet -noconsolecontrols {}' + .format(f.name)] + + try: + return subprocess.check_output( + cmd, stderr=subprocess.STDOUT, shell=True).decode('utf-8') + except subprocess.CalledProcessError as e: + raise RuntimeError(e.output.decode('utf-8')) + + +# vim:sw=4:ts=4:et: +