Merge pull request #712 from pipecat-ai/aleix/some-languages-tweaks

some languages tweaks
This commit is contained in:
Mark Backman
2024-11-14 09:33:26 -05:00
committed by GitHub
10 changed files with 353 additions and 519 deletions

View File

@@ -49,7 +49,7 @@ async def main():
tts = PlayHTTTSService(
user_id=os.getenv("PLAYHT_USER_ID"),
api_key=os.getenv("PLAYHT_API_KEY"),
voice_url="s3://voice-cloning-zero-shot/801a663f-efd0-4254-98d0-5c175514c3e8/jennifer/manifest.json",
voice_url="s3://voice-cloning-zero-shot/d9ff78ba-d016-47f6-b0ef-dd630f59414e/female-cs/manifest.json",
params=PlayHTTTSService.InputParams(language=Language.EN),
)

View File

@@ -5,7 +5,6 @@
#
import asyncio
from typing import AsyncGenerator, Optional
from loguru import logger
@@ -33,6 +32,40 @@ except ModuleNotFoundError as e:
raise Exception(f"Missing module: {e}")
def language_to_aws_language(language: Language) -> str | None:
language_map = {
Language.CA: "ca-ES",
Language.ZH: "cmn-CN",
Language.DA: "da-DK",
Language.NL: "nl-NL",
Language.NL_BE: "nl-BE",
Language.EN: "en-US",
Language.EN_US: "en-US",
Language.EN_AU: "en-AU",
Language.EN_GB: "en-GB",
Language.EN_NZ: "en-NZ",
Language.EN_IN: "en-IN",
Language.FI: "fi-FI",
Language.FR: "fr-FR",
Language.FR_CA: "fr-CA",
Language.DE: "de-DE",
Language.HI: "hi-IN",
Language.IT: "it-IT",
Language.JA: "ja-JP",
Language.KO: "ko-KR",
Language.NO: "nb-NO",
Language.PL: "pl-PL",
Language.PT: "pt-PT",
Language.PT_BR: "pt-BR",
Language.RO: "ro-RO",
Language.RU: "ru-RU",
Language.ES: "es-ES",
Language.SV: "sv-SE",
Language.TR: "tr-TR",
}
return language_map.get(language)
class AWSTTSService(TTSService):
class InputParams(BaseModel):
engine: Optional[str] = None
@@ -65,7 +98,7 @@ class AWSTTSService(TTSService):
"engine": params.engine,
"language": self.language_to_service_language(params.language)
if params.language
else Language.EN,
else "en-US",
"pitch": params.pitch,
"rate": params.rate,
"volume": params.volume,
@@ -77,62 +110,7 @@ class AWSTTSService(TTSService):
return True
def language_to_service_language(self, language: Language) -> str | None:
match language:
case Language.CA:
return "ca-ES"
case Language.ZH:
return "cmn-CN"
case Language.DA:
return "da-DK"
case Language.NL:
return "nl-NL"
case Language.NL_BE:
return "nl-BE"
case Language.EN | Language.EN_US:
return "en-US"
case Language.EN_AU:
return "en-AU"
case Language.EN_GB:
return "en-GB"
case Language.EN_NZ:
return "en-NZ"
case Language.EN_IN:
return "en-IN"
case Language.FI:
return "fi-FI"
case Language.FR:
return "fr-FR"
case Language.FR_CA:
return "fr-CA"
case Language.DE:
return "de-DE"
case Language.HI:
return "hi-IN"
case Language.IT:
return "it-IT"
case Language.JA:
return "ja-JP"
case Language.KO:
return "ko-KR"
case Language.NO:
return "nb-NO"
case Language.PL:
return "pl-PL"
case Language.PT:
return "pt-PT"
case Language.PT_BR:
return "pt-BR"
case Language.RO:
return "ro-RO"
case Language.RU:
return "ru-RU"
case Language.ES:
return "es-ES"
case Language.SV:
return "sv-SE"
case Language.TR:
return "tr-TR"
return None
return language_to_aws_language(language)
def _construct_ssml(self, text: str) -> str:
ssml = "<speak>"

View File

@@ -61,6 +61,67 @@ except ModuleNotFoundError as e:
raise Exception(f"Missing module: {e}")
def language_to_azure_language(language: Language) -> str | None:
language_map = {
Language.BG: "bg-BG",
Language.CA: "ca-ES",
Language.ZH: "zh-CN",
Language.ZH_TW: "zh-TW",
Language.CS: "cs-CZ",
Language.DA: "da-DK",
Language.NL: "nl-NL",
Language.EN: "en-US",
Language.EN_US: "en-US",
Language.EN_AU: "en-AU",
Language.EN_GB: "en-GB",
Language.EN_NZ: "en-NZ",
Language.EN_IN: "en-IN",
Language.ET: "et-EE",
Language.FI: "fi-FI",
Language.NL_BE: "nl-BE",
Language.FR: "fr-FR",
Language.FR_CA: "fr-CA",
Language.DE: "de-DE",
Language.DE_CH: "de-CH",
Language.EL: "el-GR",
Language.HI: "hi-IN",
Language.HU: "hu-HU",
Language.ID: "id-ID",
Language.IT: "it-IT",
Language.JA: "ja-JP",
Language.KO: "ko-KR",
Language.LV: "lv-LV",
Language.LT: "lt-LT",
Language.MS: "ms-MY",
Language.NO: "nb-NO",
Language.PL: "pl-PL",
Language.PT: "pt-PT",
Language.PT_BR: "pt-BR",
Language.RO: "ro-RO",
Language.RU: "ru-RU",
Language.SK: "sk-SK",
Language.ES: "es-ES",
Language.SV: "sv-SE",
Language.TH: "th-TH",
Language.TR: "tr-TR",
Language.UK: "uk-UA",
Language.VI: "vi-VN",
}
return language_map.get(language)
def sample_rate_to_output_format(sample_rate: int) -> SpeechSynthesisOutputFormat:
sample_rate_map = {
8000: SpeechSynthesisOutputFormat.Raw8Khz16BitMonoPcm,
16000: SpeechSynthesisOutputFormat.Raw16Khz16BitMonoPcm,
22050: SpeechSynthesisOutputFormat.Raw22050Hz16BitMonoPcm,
24000: SpeechSynthesisOutputFormat.Raw24Khz16BitMonoPcm,
44100: SpeechSynthesisOutputFormat.Raw44100Hz16BitMonoPcm,
48000: SpeechSynthesisOutputFormat.Raw48Khz16BitMonoPcm,
}
return sample_rate_map.get(sample_rate, SpeechSynthesisOutputFormat.Raw24Khz16BitMonoPcm)
class AzureLLMService(BaseOpenAILLMService):
def __init__(
self, *, api_key: str, endpoint: str, model: str, api_version: str = "2023-12-01-preview"
@@ -89,23 +150,6 @@ class AzureLLMService(BaseOpenAILLMService):
return OpenAIContextAggregatorPair(_user=user, _assistant=assistant)
def sample_rate_to_output_format(sample_rate: int) -> SpeechSynthesisOutputFormat:
match sample_rate:
case 8000:
return SpeechSynthesisOutputFormat.Raw8Khz16BitMonoPcm
case 16000:
return SpeechSynthesisOutputFormat.Raw16Khz16BitMonoPcm
case 22050:
return SpeechSynthesisOutputFormat.Raw22050Hz16BitMonoPcm
case 24000:
return SpeechSynthesisOutputFormat.Raw24Khz16BitMonoPcm
case 44100:
return SpeechSynthesisOutputFormat.Raw44100Hz16BitMonoPcm
case 48000:
return SpeechSynthesisOutputFormat.Raw48Khz16BitMonoPcm
return SpeechSynthesisOutputFormat.Raw16Khz16BitMonoPcm
class AzureBaseTTSService(TTSService):
class InputParams(BaseModel):
emphasis: Optional[str] = None
@@ -134,7 +178,7 @@ class AzureBaseTTSService(TTSService):
"emphasis": params.emphasis,
"language": self.language_to_service_language(params.language)
if params.language
else Language.EN_US,
else "en-US",
"pitch": params.pitch,
"rate": params.rate,
"role": params.role,
@@ -152,92 +196,7 @@ class AzureBaseTTSService(TTSService):
return True
def language_to_service_language(self, language: Language) -> str | None:
match language:
case Language.BG:
return "bg-BG"
case Language.CA:
return "ca-ES"
case Language.ZH:
return "zh-CN"
case Language.ZH_TW:
return "zh-TW"
case Language.CS:
return "cs-CZ"
case Language.DA:
return "da-DK"
case Language.NL:
return "nl-NL"
case Language.EN | Language.EN_US:
return "en-US"
case Language.EN_AU:
return "en-AU"
case Language.EN_GB:
return "en-GB"
case Language.EN_NZ:
return "en-NZ"
case Language.EN_IN:
return "en-IN"
case Language.ET:
return "et-EE"
case Language.FI:
return "fi-FI"
case Language.NL_BE:
return "nl-BE"
case Language.FR:
return "fr-FR"
case Language.FR_CA:
return "fr-CA"
case Language.DE:
return "de-DE"
case Language.DE_CH:
return "de-CH"
case Language.EL:
return "el-GR"
case Language.HI:
return "hi-IN"
case Language.HU:
return "hu-HU"
case Language.ID:
return "id-ID"
case Language.IT:
return "it-IT"
case Language.JA:
return "ja-JP"
case Language.KO:
return "ko-KR"
case Language.LV:
return "lv-LV"
case Language.LT:
return "lt-LT"
case Language.MS:
return "ms-MY"
case Language.NO:
return "nb-NO"
case Language.PL:
return "pl-PL"
case Language.PT:
return "pt-PT"
case Language.PT_BR:
return "pt-BR"
case Language.RO:
return "ro-RO"
case Language.RU:
return "ru-RU"
case Language.SK:
return "sk-SK"
case Language.ES:
return "es-ES"
case Language.SV:
return "sv-SE"
case Language.TH:
return "th-TH"
case Language.TR:
return "tr-TR"
case Language.UK:
return "uk-UA"
case Language.VI:
return "vi-VN"
return None
return language_to_azure_language(language)
def _construct_ssml(self, text: str) -> str:
language = self._settings["language"]

View File

@@ -44,29 +44,24 @@ except ModuleNotFoundError as e:
def language_to_cartesia_language(language: Language) -> str | None:
match language:
case Language.DE:
return "de"
case (
Language.EN
| Language.EN_US
| Language.EN_GB
| Language.EN_AU
| Language.EN_NZ
| Language.EN_IN
):
return "en"
case Language.ES:
return "es"
case Language.FR | Language.FR_CA:
return "fr"
case Language.JA:
return "ja"
case Language.PT | Language.PT_BR:
return "pt"
case Language.ZH | Language.ZH_TW:
return "zh"
return None
language_map = {
Language.DE: "de",
Language.EN: "en",
Language.EN_US: "en",
Language.EN_GB: "en",
Language.EN_AU: "en",
Language.EN_NZ: "en",
Language.EN_IN: "en",
Language.ES: "es",
Language.FR: "fr",
Language.FR_CA: "fr",
Language.JA: "ja",
Language.PT: "pt",
Language.PT_BR: "pt",
Language.ZH: "zh",
Language.ZH_TW: "zh",
}
return language_map.get(language)
class CartesiaTTSService(WordTTSService):
@@ -117,7 +112,7 @@ class CartesiaTTSService(WordTTSService):
},
"language": self.language_to_service_language(params.language)
if params.language
else Language.EN,
else "en",
"speed": params.speed,
"emotion": params.emotion,
}
@@ -331,7 +326,7 @@ class CartesiaHttpTTSService(TTSService):
},
"language": self.language_to_service_language(params.language)
if params.language
else Language.EN,
else "en",
"speed": params.speed,
"emotion": params.emotion,
}

View File

@@ -42,6 +42,48 @@ except ModuleNotFoundError as e:
ElevenLabsOutputFormat = Literal["pcm_16000", "pcm_22050", "pcm_24000", "pcm_44100"]
def language_to_elevenlabs_language(language: Language) -> str | None:
language_map = {
Language.BG: "bg",
Language.ZH: "zh",
Language.CS: "cs",
Language.DA: "da",
Language.NL: "nl",
Language.EN: "en",
Language.EN_US: "en",
Language.EN_AU: "en",
Language.EN_GB: "en",
Language.EN_NZ: "en",
Language.EN_IN: "en",
Language.FI: "fi",
Language.FR: "fr",
Language.FR_CA: "fr",
Language.DE: "de",
Language.DE_CH: "de",
Language.EL: "el",
Language.HI: "hi",
Language.HU: "hu",
Language.ID: "id",
Language.IT: "it",
Language.JA: "ja",
Language.KO: "ko",
Language.MS: "ms",
Language.NO: "no",
Language.PL: "pl",
Language.PT: "pt-PT",
Language.PT_BR: "pt-BR",
Language.RO: "ro",
Language.RU: "ru",
Language.SK: "sk",
Language.ES: "es",
Language.SV: "sv",
Language.TR: "tr",
Language.UK: "uk",
Language.VI: "vi",
}
return language_map.get(language)
def sample_rate_from_output_format(output_format: str) -> int:
match output_format:
case "pcm_16000":
@@ -135,7 +177,7 @@ class ElevenLabsTTSService(WordTTSService):
"sample_rate": sample_rate_from_output_format(output_format),
"language": self.language_to_service_language(params.language)
if params.language
else Language.EN,
else "en",
"output_format": output_format,
"optimize_streaming_latency": params.optimize_streaming_latency,
"stability": params.stability,
@@ -158,73 +200,7 @@ class ElevenLabsTTSService(WordTTSService):
return True
def language_to_service_language(self, language: Language) -> str | None:
match language:
case Language.BG:
return "bg"
case Language.ZH:
return "zh"
case Language.CS:
return "cs"
case Language.DA:
return "da"
case Language.NL:
return "nl"
case (
Language.EN
| Language.EN_US
| Language.EN_AU
| Language.EN_GB
| Language.EN_NZ
| Language.EN_IN
):
return "en"
case Language.FI:
return "fi"
case Language.FR | Language.FR_CA:
return "fr"
case Language.DE | Language.DE_CH:
return "de"
case Language.EL:
return "el"
case Language.HI:
return "hi"
case Language.HU:
return "hu"
case Language.ID:
return "id"
case Language.IT:
return "it"
case Language.JA:
return "ja"
case Language.KO:
return "ko"
case Language.MS:
return "ms"
case Language.NO:
return "no"
case Language.PL:
return "pl"
case Language.PT:
return "pt-PT"
case Language.PT_BR:
return "pt-BR"
case Language.RO:
return "ro"
case Language.RU:
return "ru"
case Language.SK:
return "sk"
case Language.ES:
return "es"
case Language.SV:
return "sv"
case Language.TR:
return "tr"
case Language.UK:
return "uk"
case Language.VI:
return "vi"
return None
return language_to_elevenlabs_language(language)
def _set_voice_settings(self):
voice_settings = {}

View File

@@ -34,6 +34,53 @@ except ModuleNotFoundError as e:
raise Exception(f"Missing module: {e}")
def language_to_gladia_language(language: Language) -> str | None:
language_map = {
Language.BG: "bg",
Language.CA: "ca",
Language.ZH: "zh",
Language.CS: "cs",
Language.DA: "da",
Language.NL: "nl",
Language.EN: "en",
Language.EN_US: "en",
Language.EN_AU: "en",
Language.EN_GB: "en",
Language.EN_NZ: "en",
Language.EN_IN: "en",
Language.ET: "et",
Language.FI: "fi",
Language.FR: "fr",
Language.FR_CA: "fr",
Language.DE: "de",
Language.DE_CH: "de",
Language.EL: "el",
Language.HI: "hi",
Language.HU: "hu",
Language.ID: "id",
Language.IT: "it",
Language.JA: "ja",
Language.KO: "ko",
Language.LV: "lv",
Language.LT: "lt",
Language.MS: "ms",
Language.NO: "no",
Language.PL: "pl",
Language.PT: "pt",
Language.PT_BR: "pt",
Language.RO: "ro",
Language.RU: "ru",
Language.SK: "sk",
Language.ES: "es",
Language.SV: "sv",
Language.TH: "th",
Language.TR: "tr",
Language.UK: "uk",
Language.VI: "vi",
}
return language_map.get(language)
class GladiaSTTService(STTService):
class InputParams(BaseModel):
sample_rate: Optional[int] = 16000
@@ -79,50 +126,7 @@ class GladiaSTTService(STTService):
self._confidence = confidence
def language_to_service_language(self, language: Language) -> str | None:
language_map = {
Language.BG: "bg",
Language.CA: "ca",
Language.ZH: "zh",
Language.CS: "cs",
Language.DA: "da",
Language.NL: "nl",
Language.EN: "en",
Language.EN_US: "en",
Language.EN_AU: "en",
Language.EN_GB: "en",
Language.EN_NZ: "en",
Language.EN_IN: "en",
Language.ET: "et",
Language.FI: "fi",
Language.FR: "fr",
Language.FR_CA: "fr",
Language.DE: "de",
Language.DE_CH: "de",
Language.EL: "el",
Language.HI: "hi",
Language.HU: "hu",
Language.ID: "id",
Language.IT: "it",
Language.JA: "ja",
Language.KO: "ko",
Language.LV: "lv",
Language.LT: "lt",
Language.MS: "ms",
Language.NO: "no",
Language.PL: "pl",
Language.PT: "pt",
Language.PT_BR: "pt",
Language.RO: "ro",
Language.RU: "ru",
Language.SK: "sk",
Language.ES: "es",
Language.SV: "sv",
Language.TH: "th",
Language.TR: "tr",
Language.UK: "uk",
Language.VI: "vi",
}
return language_map.get(language)
return language_to_gladia_language(language)
async def start(self, frame: StartFrame):
await super().start(frame)

View File

@@ -55,6 +55,53 @@ except ModuleNotFoundError as e:
raise Exception(f"Missing module: {e}")
def language_to_google_language(language: Language) -> str | None:
language_map = {
Language.BG: "bg-BG",
Language.CA: "ca-ES",
Language.ZH: "cmn-CN",
Language.ZH_TW: "cmn-TW",
Language.CS: "cs-CZ",
Language.DA: "da-DK",
Language.NL: "nl-NL",
Language.EN: "en-US",
Language.EN_US: "en-US",
Language.EN_AU: "en-AU",
Language.EN_GB: "en-GB",
Language.EN_IN: "en-IN",
Language.ET: "et-EE",
Language.FI: "fi-FI",
Language.NL_BE: "nl-BE",
Language.FR: "fr-FR",
Language.FR_CA: "fr-CA",
Language.DE: "de-DE",
Language.EL: "el-GR",
Language.HI: "hi-IN",
Language.HU: "hu-HU",
Language.ID: "id-ID",
Language.IT: "it-IT",
Language.JA: "ja-JP",
Language.KO: "ko-KR",
Language.LV: "lv-LV",
Language.LT: "lt-LT",
Language.MS: "ms-MY",
Language.NO: "nb-NO",
Language.PL: "pl-PL",
Language.PT: "pt-PT",
Language.PT_BR: "pt-BR",
Language.RO: "ro-RO",
Language.RU: "ru-RU",
Language.SK: "sk-SK",
Language.ES: "es-ES",
Language.SV: "sv-SE",
Language.TH: "th-TH",
Language.TR: "tr-TR",
Language.UK: "uk-UA",
Language.VI: "vi-VN",
}
return language_map.get(language)
class GoogleUserContextAggregator(OpenAIUserContextAggregator):
async def _push_aggregation(self):
if len(self._aggregation) > 0:
@@ -499,7 +546,7 @@ class GoogleTTSService(TTSService):
"emphasis": params.emphasis,
"language": self.language_to_service_language(params.language)
if params.language
else Language.EN,
else "en-US",
"gender": params.gender,
"google_style": params.google_style,
}
@@ -530,88 +577,7 @@ class GoogleTTSService(TTSService):
return True
def language_to_service_language(self, language: Language) -> str | None:
match language:
case Language.BG:
return "bg-BG"
case Language.CA:
return "ca-ES"
case Language.ZH:
return "cmn-CN"
case Language.ZH_TW:
return "cmn-TW"
case Language.CS:
return "cs-CZ"
case Language.DA:
return "da-DK"
case Language.NL:
return "nl-NL"
case Language.EN | Language.EN_US:
return "en-US"
case Language.EN_AU:
return "en-AU"
case Language.EN_GB:
return "en-GB"
case Language.EN_IN:
return "en-IN"
case Language.ET:
return "et-EE"
case Language.FI:
return "fi-FI"
case Language.NL_BE:
return "nl-BE"
case Language.FR:
return "fr-FR"
case Language.FR_CA:
return "fr-CA"
case Language.DE:
return "de-DE"
case Language.EL:
return "el-GR"
case Language.HI:
return "hi-IN"
case Language.HU:
return "hu-HU"
case Language.ID:
return "id-ID"
case Language.IT:
return "it-IT"
case Language.JA:
return "ja-JP"
case Language.KO:
return "ko-KR"
case Language.LV:
return "lv-LV"
case Language.LT:
return "lt-LT"
case Language.MS:
return "ms-MY"
case Language.NO:
return "nb-NO"
case Language.PL:
return "pl-PL"
case Language.PT:
return "pt-PT"
case Language.PT_BR:
return "pt-BR"
case Language.RO:
return "ro-RO"
case Language.RU:
return "ru-RU"
case Language.SK:
return "sk-SK"
case Language.ES:
return "es-ES"
case Language.SV:
return "sv-SE"
case Language.TH:
return "th-TH"
case Language.TR:
return "tr-TR"
case Language.UK:
return "uk-UA"
case Language.VI:
return "vi-VN"
return None
return language_to_google_language(language)
def _construct_ssml(self, text: str) -> str:
ssml = "<speak>"

View File

@@ -35,6 +35,27 @@ except ModuleNotFoundError as e:
raise Exception(f"Missing module: {e}")
def language_to_lmnt_language(language: Language) -> str | None:
language_map = {
Language.DE: "de",
Language.EN: "en",
Language.EN_US: "en",
Language.EN_AU: "en",
Language.EN_GB: "en",
Language.EN_NZ: "en",
Language.EN_IN: "en",
Language.ES: "es",
Language.FR: "fr",
Language.FR_CA: "fr",
Language.PT: "pt",
Language.PT_BR: "pt",
Language.ZH: "zh",
Language.ZH_TW: "zh",
Language.KO: "ko",
}
return language_map.get(language)
class LmntTTSService(TTSService):
def __init__(
self,
@@ -72,29 +93,7 @@ class LmntTTSService(TTSService):
return True
def language_to_service_language(self, language: Language) -> str | None:
match language:
case Language.DE:
return "de"
case (
Language.EN
| Language.EN_US
| Language.EN_AU
| Language.EN_GB
| Language.EN_NZ
| Language.EN_IN
):
return "en"
case Language.ES:
return "es"
case Language.FR | Language.FR_CA:
return "fr"
case Language.PT | Language.PT_BR:
return "pt"
case Language.ZH | Language.ZH_TW:
return "zh"
case Language.KO:
return "ko"
return None
return language_to_lmnt_language(language)
async def start(self, frame: StartFrame):
await super().start(frame)

View File

@@ -47,63 +47,40 @@ except ModuleNotFoundError as e:
def language_to_playht_language(language: Language) -> str | None:
match language:
case Language.BG:
return "BULGARIAN"
case Language.CA:
return "CATALAN"
case Language.CS:
return "CZECH"
case Language.DA:
return "DANISH"
case Language.DE:
return "GERMAN"
case (
Language.EN
| Language.EN_US
| Language.EN_GB
| Language.EN_AU
| Language.EN_NZ
| Language.EN_IN
):
return "ENGLISH"
case Language.ES:
return "SPANISH"
case Language.FR | Language.FR_CA:
return "FRENCH"
case Language.EL:
return "GREEK"
case Language.HI:
return "HINDI"
case Language.HU:
return "HUNGARIAN"
case Language.ID:
return "INDONESIAN"
case Language.IT:
return "ITALIAN"
case Language.JA:
return "JAPANESE"
case Language.KO:
return "KOREAN"
case Language.MS:
return "MALAY"
case Language.NL:
return "DUTCH"
case Language.PL:
return "POLISH"
case Language.PT | Language.PT_BR:
return "PORTUGUESE"
case Language.RU:
return "RUSSIAN"
case Language.SV:
return "SWEDISH"
case Language.TH:
return "THAI"
case Language.TR:
return "TURKISH"
case Language.UK:
return "UKRAINIAN"
return None
language_map = {
Language.BG: "bulgarian",
Language.CA: "catalan",
Language.CS: "czech",
Language.DA: "danish",
Language.DE: "german",
Language.EN: "english",
Language.EN_US: "english",
Language.EN_GB: "english",
Language.EN_AU: "english",
Language.EN_NZ: "english",
Language.EN_IN: "english",
Language.ES: "spanish",
Language.FR: "french",
Language.FR_CA: "french",
Language.EL: "greek",
Language.HI: "hindi",
Language.HU: "hungarian",
Language.ID: "indonesian",
Language.IT: "italian",
Language.JA: "japanese",
Language.KO: "korean",
Language.MS: "malay",
Language.NL: "dutch",
Language.PL: "polish",
Language.PT: "portuguese",
Language.PT_BR: "portuguese",
Language.RU: "russian",
Language.SV: "swedish",
Language.TH: "thai",
Language.TR: "turkish",
Language.UK: "ukrainian",
}
return language_map.get(language)
class PlayHTTTSService(TTSService):
@@ -118,7 +95,7 @@ class PlayHTTTSService(TTSService):
api_key: str,
user_id: str,
voice_url: str,
voice_engine: str = "PlayHT3.0-mini",
voice_engine: str = "Play3.0-mini",
sample_rate: int = 24000,
output_format: str = "wav",
params: InputParams = InputParams(),
@@ -140,7 +117,7 @@ class PlayHTTTSService(TTSService):
"sample_rate": sample_rate,
"language": self.language_to_service_language(params.language)
if params.language
else Language.EN,
else "english",
"output_format": output_format,
"voice_engine": voice_engine,
"speed": params.speed,
@@ -153,8 +130,7 @@ class PlayHTTTSService(TTSService):
return True
def language_to_service_language(self, language: Language) -> str | None:
# Keep your existing language mapping logic here
pass
return language_to_playht_language(language)
async def start(self, frame: StartFrame):
await super().start(frame)
@@ -234,17 +210,11 @@ class PlayHTTTSService(TTSService):
async def _receive_task_handler(self):
try:
header_size = 78 # Size of the WAV header + extra bytes we want to skip
header_received = False
async for message in self._get_websocket():
if isinstance(message, bytes):
chunk_size = len(message)
# Skip the WAV header
if not header_received and chunk_size == header_size:
header_received = True
# Skip the WAV header message
if message.startswith(b"RIFF"):
continue
await self.stop_ttfb_metrics()
frame = TTSAudioRawFrame(message, self._settings["sample_rate"], 1)
await self.push_frame(frame)
@@ -254,7 +224,6 @@ class PlayHTTTSService(TTSService):
msg = json.loads(message)
if "request_id" in msg and msg["request_id"] == self._request_id:
await self.push_frame(TTSStoppedFrame())
header_received = False # Reset for the next audio stream
self._request_id = None
elif "error" in msg:
logger.error(f"{self} error: {msg}")
@@ -334,7 +303,7 @@ class PlayHTHttpTTSService(TTSService):
api_key: str,
user_id: str,
voice_url: str,
voice_engine: str = "PlayHT3.0-mini",
voice_engine: str = "Play3.0-mini",
sample_rate: int = 24000,
params: InputParams = InputParams(),
**kwargs,
@@ -352,7 +321,7 @@ class PlayHTHttpTTSService(TTSService):
"sample_rate": sample_rate,
"language": self.language_to_service_language(params.language)
if params.language
else Language.EN,
else "english",
"format": Format.FORMAT_WAV,
"voice_engine": voice_engine,
"speed": params.speed,

View File

@@ -31,6 +31,34 @@ from loguru import logger
# https://github.com/coqui-ai/xtts-streaming-server
def language_to_xtts_language(language: Language) -> str | None:
language_map = {
Language.CS: "cs",
Language.DE: "de",
Language.EN: "en",
Language.EN_US: "en",
Language.EN_AU: "en",
Language.EN_GB: "en",
Language.EN_NZ: "en",
Language.EN_IN: "en",
Language.ES: "es",
Language.FR: "fr",
Language.HI: "hi",
Language.HU: "hu",
Language.IT: "it",
Language.JA: "ja",
Language.KO: "ko",
Language.NL: "nl",
Language.PL: "pl",
Language.PT: "pt",
Language.PT_BR: "pt",
Language.RU: "ru",
Language.TR: "tr",
Language.ZH: "zh-cn",
}
return language_map.get(language)
class XTTSService(TTSService):
def __init__(
self,
@@ -56,47 +84,7 @@ class XTTSService(TTSService):
return True
def language_to_service_language(self, language: Language) -> str | None:
match language:
case Language.CS:
return "cs"
case Language.DE:
return "de"
case (
Language.EN
| Language.EN_US
| Language.EN_AU
| Language.EN_GB
| Language.EN_NZ
| Language.EN_IN
):
return "en"
case Language.ES:
return "es"
case Language.FR:
return "fr"
case Language.HI:
return "hi"
case Language.HU:
return "hu"
case Language.IT:
return "it"
case Language.JA:
return "ja"
case Language.KO:
return "ko"
case Language.NL:
return "nl"
case Language.PL:
return "pl"
case Language.PT | Language.PT_BR:
return "pt"
case Language.RU:
return "ru"
case Language.TR:
return "tr"
case Language.ZH:
return "zh-cn"
return None
return language_to_xtts_language(language)
async def start(self, frame: StartFrame):
await super().start(frame)