158 lines
4.2 KiB
Python
Executable File
158 lines
4.2 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")
|
|
|
|
@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
|