diff --git a/src/edge_tts/communicate.py b/src/edge_tts/communicate.py index 87267d4..ab23cdf 100644 --- a/src/edge_tts/communicate.py +++ b/src/edge_tts/communicate.py @@ -433,9 +433,9 @@ class Communicate: trust_env=True, timeout=self.session_timeout, ) as session, session.ws_connect( - f"{WSS_URL}&Sec-MS-GEC={DRM.generate_sec_ms_gec()}" - f"&Sec-MS-GEC-Version={SEC_MS_GEC_VERSION}" - f"&ConnectionId={connect_id()}", + f"{WSS_URL}&ConnectionId={connect_id()}" + f"&Sec-MS-GEC={DRM.generate_sec_ms_gec()}" + f"&Sec-MS-GEC-Version={SEC_MS_GEC_VERSION}", compress=15, proxy=self.proxy, headers=WSS_HEADERS, diff --git a/src/edge_tts/constants.py b/src/edge_tts/constants.py index 9395a06..131e24d 100644 --- a/src/edge_tts/constants.py +++ b/src/edge_tts/constants.py @@ -1,10 +1,14 @@ """Constants for the edge_tts package.""" -BASE_URL = "speech.platform.bing.com/consumer/speech/synthesize/readaloud" +BASE_URL = "api.msedgeservices.com/tts/cognitiveservices" TRUSTED_CLIENT_TOKEN = "6A5AA1D4EAFF4E9FB37E23D68491D6F4" -WSS_URL = f"wss://{BASE_URL}/edge/v1?TrustedClientToken={TRUSTED_CLIENT_TOKEN}" -VOICE_LIST = f"https://{BASE_URL}/voices/list?trustedclienttoken={TRUSTED_CLIENT_TOKEN}" +WSS_URL = ( + f"wss://{BASE_URL}/websocket/v1?Ocp-Apim-Subscription-Key={TRUSTED_CLIENT_TOKEN}" +) +VOICE_LIST = ( + f"https://{BASE_URL}/voices/list?Ocp-Apim-Subscription-Key={TRUSTED_CLIENT_TOKEN}" +) DEFAULT_VOICE = "en-US-EmmaMultilingualNeural" @@ -22,6 +26,8 @@ WSS_HEADERS = { "Pragma": "no-cache", "Cache-Control": "no-cache", "Origin": "chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold", + "Sec-WebSocket-Protocol": "synthesize", + "Sec-WebSocket-Version": "13", } WSS_HEADERS.update(BASE_HEADERS) VOICE_HEADERS = { diff --git a/src/edge_tts/typing.py b/src/edge_tts/typing.py index df92e87..f402a26 100644 --- a/src/edge_tts/typing.py +++ b/src/edge_tts/typing.py @@ -20,49 +20,8 @@ class TTSChunk(TypedDict): class VoiceTag(TypedDict): """VoiceTag data.""" - ContentCategories: List[ - Literal[ - "Cartoon", - "Conversation", - "Copilot", - "Dialect", - "General", - "News", - "Novel", - "Sports", - ] - ] - VoicePersonalities: List[ - Literal[ - "Approachable", - "Authentic", - "Authority", - "Bright", - "Caring", - "Casual", - "Cheerful", - "Clear", - "Comfort", - "Confident", - "Considerate", - "Conversational", - "Cute", - "Expressive", - "Friendly", - "Honest", - "Humorous", - "Lively", - "Passion", - "Pleasant", - "Positive", - "Professional", - "Rational", - "Reliable", - "Sincere", - "Sunshine", - "Warm", - ] - ] + ContentCategories: List[str] + VoicePersonalities: List[str] class Voice(TypedDict): @@ -70,14 +29,15 @@ class Voice(TypedDict): Name: str ShortName: str - Gender: Literal["Female", "Male"] + DisplayName: str + LocalName: str + LocaleName: str Locale: str - SuggestedCodec: Literal["audio-24khz-48kbitrate-mono-mp3"] - FriendlyName: str - Status: Literal["GA"] + Gender: Literal["Female", "Male"] + WordsPerMinute: str + Status: Literal["Deprecated", "GA", "Preview"] VoiceTag: VoiceTag - class VoicesManagerVoice(Voice): """Voice data for VoicesManager.""" diff --git a/src/edge_tts/voices.py b/src/edge_tts/voices.py index 81a5448..f48cd55 100644 --- a/src/edge_tts/voices.py +++ b/src/edge_tts/voices.py @@ -41,17 +41,14 @@ async def __list_voices( data: List[Voice] = json.loads(await url.text()) for voice in data: - # Remove leading and trailing whitespace from categories and personalities. - # This has only happened in one case with the zh-CN-YunjianNeural voice - # where there was a leading space in one of the categories. - voice["VoiceTag"]["ContentCategories"] = [ - category.strip() # type: ignore - for category in voice["VoiceTag"]["ContentCategories"] - ] - voice["VoiceTag"]["VoicePersonalities"] = [ - personality.strip() # type: ignore - for personality in voice["VoiceTag"]["VoicePersonalities"] - ] + if "VoiceTag" not in voice: + voice["VoiceTag"] = {} + + if "ContentCategories" not in voice["VoiceTag"]: + voice["VoiceTag"]["ContentCategories"] = [] + + if "VoicePersonalities" not in voice["VoiceTag"]: + voice["VoiceTag"]["VoicePersonalities"] = [] return data