core/homeassistant/components/marytts/tts.py

106 lines
3.2 KiB
Python

"""Support for the MaryTTS service."""
import asyncio
import logging
import re
import aiohttp
import async_timeout
import voluptuous as vol
from homeassistant.components.tts import CONF_LANG, PLATFORM_SCHEMA, Provider
from homeassistant.const import CONF_HOST, CONF_PORT
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__)
SUPPORT_LANGUAGES = ["de", "en-GB", "en-US", "fr", "it", "lb", "ru", "sv", "te", "tr"]
SUPPORT_CODEC = ["aiff", "au", "wav"]
CONF_VOICE = "voice"
CONF_CODEC = "codec"
DEFAULT_HOST = "localhost"
DEFAULT_PORT = 59125
DEFAULT_LANG = "en-US"
DEFAULT_VOICE = "cmu-slt-hsmm"
DEFAULT_CODEC = "wav"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_HOST, default=DEFAULT_HOST): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
vol.Optional(CONF_LANG, default=DEFAULT_LANG): vol.In(SUPPORT_LANGUAGES),
vol.Optional(CONF_VOICE, default=DEFAULT_VOICE): cv.string,
vol.Optional(CONF_CODEC, default=DEFAULT_CODEC): vol.In(SUPPORT_CODEC),
}
)
async def async_get_engine(hass, config, discovery_info=None):
"""Set up MaryTTS speech component."""
return MaryTTSProvider(hass, config)
class MaryTTSProvider(Provider):
"""MaryTTS speech api provider."""
def __init__(self, hass, conf):
"""Init MaryTTS TTS service."""
self.hass = hass
self._host = conf.get(CONF_HOST)
self._port = conf.get(CONF_PORT)
self._codec = conf.get(CONF_CODEC)
self._voice = conf.get(CONF_VOICE)
self._language = conf.get(CONF_LANG)
self.name = "MaryTTS"
@property
def default_language(self):
"""Return the default language."""
return self._language
@property
def supported_languages(self):
"""Return list of supported languages."""
return SUPPORT_LANGUAGES
async def async_get_tts_audio(self, message, language, options=None):
"""Load TTS from MaryTTS."""
websession = async_get_clientsession(self.hass)
actual_language = re.sub("-", "_", language)
try:
with async_timeout.timeout(10):
url = f"http://{self._host}:{self._port}/process?"
audio = self._codec.upper()
if audio == "WAV":
audio = "WAVE"
url_param = {
"INPUT_TEXT": message,
"INPUT_TYPE": "TEXT",
"AUDIO": audio,
"VOICE": self._voice,
"OUTPUT_TYPE": "AUDIO",
"LOCALE": actual_language,
}
request = await websession.get(url, params=url_param)
if request.status != 200:
_LOGGER.error(
"Error %d on load url %s", request.status, request.url
)
return (None, None)
data = await request.read()
except (asyncio.TimeoutError, aiohttp.ClientError):
_LOGGER.error("Timeout for MaryTTS API")
return (None, None)
return (self._codec, data)