# Copyright 2017 Mycroft AI Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # from gtts import gTTS from gtts.lang import tts_langs from .tts import TTS, TTSValidator from mycroft.util.log import LOG # Live list of languages # Cached list of supported languages (2021-02-09) _default_langs = {'af': 'Afrikaans', 'sq': 'Albanian', 'ar': 'Arabic', 'hy': 'Armenian', 'bn': 'Bengali', 'bs': 'Bosnian', 'ca': 'Catalan', 'hr': 'Croatian', 'cs': 'Czech', 'da': 'Danish', 'nl': 'Dutch', 'en': 'English', 'eo': 'Esperanto', 'et': 'Estonian', 'tl': 'Filipino', 'fi': 'Finnish', 'fr': 'French', 'de': 'German', 'el': 'Greek', 'gu': 'Gujarati', 'hi': 'Hindi', 'hu': 'Hungarian', 'is': 'Icelandic', 'id': 'Indonesian', 'it': 'Italian', 'ja': 'Japanese', 'jw': 'Javanese', 'kn': 'Kannada', 'km': 'Khmer', 'ko': 'Korean', 'la': 'Latin', 'lv': 'Latvian', 'mk': 'Macedonian', 'ml': 'Malayalam', 'mr': 'Marathi', 'my': 'Myanmar (Burmese)', 'ne': 'Nepali', 'no': 'Norwegian', 'pl': 'Polish', 'pt': 'Portuguese', 'ro': 'Romanian', 'ru': 'Russian', 'sr': 'Serbian', 'si': 'Sinhala', 'sk': 'Slovak', 'es': 'Spanish', 'su': 'Sundanese', 'sw': 'Swahili', 'sv': 'Swedish', 'ta': 'Tamil', 'te': 'Telugu', 'th': 'Thai', 'tr': 'Turkish', 'uk': 'Ukrainian', 'ur': 'Urdu', 'vi': 'Vietnamese', 'cy': 'Welsh', 'zh': 'Chinese (Mandarin/China)' } _supported_langs = None def get_supported_langs(): """Get dict of supported languages. Tries to fetch remote list, if that fails a local cache will be used. Returns: (dict): Lang code to lang name map. """ global _supported_langs if not _supported_langs: try: _supported_langs = tts_langs() except Exception: LOG.warning('Couldn\'t fetch upto date language codes') return _supported_langs or _default_langs class GoogleTTS(TTS): """Interface to google TTS.""" def __init__(self, lang, config): self._google_lang = None super(GoogleTTS, self).__init__(lang, config, GoogleTTSValidator( self), 'mp3') LOG.warning( "The Google TTS module uses the gTTS Python package which itself " "interfaces with the Google Translate text-to-speech API. This is " "not intended for commercial or production usage. The service " "may break at any time, and you are subject to their Terms of " "Service that can be found at https://policies.google.com/terms" ) @property def google_lang(self): """Property containing a converted language code suitable for gTTS.""" supported_langs = get_supported_langs() if not self._google_lang: if self.lang.lower() in supported_langs: self._google_lang = self.lang.lower() elif self.lang[:2].lower() in supported_langs: self._google_lang = self.lang[:2] return self._google_lang or self.lang.lower() def get_tts(self, sentence, wav_file): """Fetch tts audio using gTTS. Args: sentence (str): Sentence to generate audio for wav_file (str): output file path Returns: Tuple ((str) written file, None) """ tts = gTTS(text=sentence, lang=self.google_lang) tts.save(wav_file) return (wav_file, None) # No phonemes class GoogleTTSValidator(TTSValidator): def __init__(self, tts): super(GoogleTTSValidator, self).__init__(tts) def validate_lang(self): lang = self.tts.google_lang if lang.lower() not in get_supported_langs(): raise ValueError("Language not supported by gTTS: {}".format(lang)) def validate_connection(self): try: gTTS(text='Hi').save(self.tts.filename) except Exception: raise Exception( 'GoogleTTS server could not be verified. Please check your ' 'internet connection.') def get_tts_class(self): return GoogleTTS