125 lines
4.7 KiB
Python
Executable File
125 lines
4.7 KiB
Python
Executable File
# 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
|