Switch to aiohttp

This commit is contained in:
rany
2021-06-18 02:29:43 +03:00
parent a38cacce87
commit 66511837ab
2 changed files with 67 additions and 62 deletions

View File

@@ -1,6 +1,6 @@
[metadata]
name = edge-tts
version = 2.0.9
version = 2.1.0
author = rany
author_email = ranygh@riseup.net
description = Microsoft Edge's TTS

View File

@@ -5,15 +5,13 @@ import uuid
import argparse
import asyncio
import ssl
import websockets
import logging
import httpx
import time
import math
import aiohttp
from xml.sax.saxutils import escape
# Default variables
ssl_context = ssl.create_default_context()
trustedClientToken = '6A5AA1D4EAFF4E9FB37E23D68491D6F4'
wssUrl = 'wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1?TrustedClientToken=' + trustedClientToken
voiceList = 'https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=' + trustedClientToken
@@ -55,9 +53,10 @@ def mktimestamp(ns):
# Return loaded JSON data of list of Edge's voices
# NOTE: It's not the total list of available voices.
# This is only what is presented in the UI.
def list_voices():
async def list_voices():
logger = logging.getLogger("edgeTTS.list_voices")
with httpx.Client(http2=True, headers={
async with aiohttp.ClientSession(trust_env=True) as session:
async with session.get(voiceList, headers={
'Authority': 'speech.platform.bing.com',
'Sec-CH-UA': "\" Not;A Brand\";v=\"99\", \"Microsoft Edge\";v=\"91\", \"Chromium\";v=\"91\"",
'Sec-CH-UA-Mobile': '?0',
@@ -70,7 +69,7 @@ def list_voices():
'Accept-Language': 'en-US,en;q=0.9'
}) as url:
logger.debug("Loading json from %s" % voiceList)
data = json.loads(url.get(voiceList).content)
data = json.loads(await url.text())
logger.debug("JSON Loaded")
return data
@@ -132,11 +131,13 @@ class Communicate:
if type(msgs) is str:
msgs = [msgs]
async with websockets.connect(
async with aiohttp.ClientSession(trust_env=True) as session:
async with session.ws_connect(
wssUrl + "&ConnectionId=" + connectId(),
ssl=ssl_context,
compression="deflate",
extra_headers={
compress = 15,
autoclose = True,
autoping = True,
headers={
"Pragma": "no-cache",
"Origin": "chrome-extension://jdiccldimpdaibmpdkjnbmckianbfold",
"Accept-Encoding": "gzip, deflate, br",
@@ -155,25 +156,29 @@ class Communicate:
message='X-Timestamp:'+self.date+'\r\nContent-Type:application/json; charset=utf-8\r\nPath:speech.config\r\n\r\n'
message+='{"context":{"synthesis":{"audio":{"metadataoptions":{"sentenceBoundaryEnabled":"'+sentenceBoundary+'","wordBoundaryEnabled":"'+wordBoundary+'"},"outputFormat":"' + codec + '"}}}}\r\n'
await ws.send(message)
await ws.send(msg)
await ws.send_str(message)
await ws.send_str(msg)
download = False
async for recv in ws:
if type(recv) is str:
if 'turn.start' in recv:
if recv.type in (aiohttp.WSMsgType.CLOSED, aiohttp.WSMsgType.ERROR):
break
if recv.type == aiohttp.WSMsgType.TEXT:
if 'turn.start' in recv.data:
download = True
elif 'turn.end' in recv:
elif 'turn.end' in recv.data:
download = False
break
elif 'audio.metadata' in recv:
elif 'audio.metadata' in recv.data:
#print("".join(recv.split('Path:audio.metadata\r\n\r\n')[1:]), file=sys.stderr)
metadata = json.loads("".join(recv.split('Path:audio.metadata\r\n\r\n')[1:]))
text = metadata['Metadata'][0]['Data']['text']['Text']
offset = metadata['Metadata'][0]['Data']['Offset']
yield [ offset, text, None ]
elif type(recv) is bytes:
elif recv.type == aiohttp.WSMsgType.BINARY:
if download:
yield [ None, None, b"".join(recv.split(b'Path:audio\r\n')[1:]) ]
yield [ None, None, b"".join(recv.data.split(b'Path:audio\r\n')[1:]) ]
await ws.close()
@@ -250,7 +255,7 @@ async def _main():
media_file.write(i[2])
elif i[0] is not None and i[1] is not None:
subs.createSub(i[0], i[1])
media_file.close()
if args.write_media: media_file.close()
if not subs.subsAndOffset == {}:
if not args.write_subtitles:
sys.stderr.write(subs.generateSubs())
@@ -260,7 +265,7 @@ async def _main():
subtitle_file.close()
elif args.list_voices:
seperator = False
for voice in list_voices():
for voice in await list_voices():
if seperator: print()
for key in voice.keys():
logger.debug("Processing key %s" % key)