-
-
Save Dobby233Liu/873c2abc393de72ce3a067b15addef2a to your computer and use it in GitHub Desktop.
superb edit of an old parameterless script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding:utf-8 -*- | |
"""Edge Microsoft TTS for Python.""" | |
import sys | |
from ws4py.client.threadedclient import WebSocketClient | |
import binascii | |
import argparse | |
import json | |
import requests | |
import re | |
import errno | |
trustedClientToken = '6A5AA1D4EAFF4E9FB37E23D68491D6F4' | |
wsUrl = 'wss://speech.platform.bing.com/consumer/speech/synthesize/readaloud/edge/v1?TrustedClientToken='+trustedClientToken | |
engineListUrl = 'https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken='+trustedClientToken | |
class ListEngineAction(argparse.Action): | |
def __init__(self, option_strings, dest, nargs=1, **kwargs): | |
super(ListEngineAction, self).__init__(option_strings, dest, **kwargs) | |
def __call__(self, parser, namespace, values, option_string=None): | |
list = requests.get(engineListUrl).json() | |
if values == '__all__': | |
for obj in list: | |
print('---------------') | |
for x in obj: | |
name_splited = [] | |
name_splited = re.findall('[A-Z][^A-Z]*', x) | |
for x2 in name_splited: | |
sys.stdout.write(x2) | |
if x2 != name_splited[len(name_splited)-1]: | |
sys.stdout.write(' ') | |
sys.stdout.flush() | |
print(': '+obj[x]) | |
print('---------------') | |
else: | |
found = False | |
for obj in list: | |
if obj['Name'] == values: | |
for x in obj: | |
name_splited = [] | |
name_splited = re.findall('[A-Z][^A-Z]*', x) | |
for x2 in name_splited: | |
sys.stdout.write(x2) | |
if x2 != name_splited[len(name_splited)-1]: | |
sys.stdout.write(' ') | |
sys.stdout.flush() | |
print(': '+obj[x]) | |
found = True | |
break | |
if found == False: | |
print('none found') | |
sys.exit() | |
parser = argparse.ArgumentParser( | |
description=__doc__ | |
) | |
parser.add_argument( | |
'text', | |
help='Text to speak.', | |
default='hello, world', | |
nargs='?' | |
) | |
parser.add_argument( | |
'-e', '--engine', | |
help='Speak engine (default: "Microsoft Server Speech Text to Speech Voice (zh-CN, XiaoxiaoNeural)")', | |
default='Microsoft Server Speech Text to Speech Voice (zh-CN, XiaoxiaoNeural)' | |
) | |
parser.add_argument( | |
'-c', '--codec', | |
help='Output codec (default: "audio-24khz-48kbitrate-mono-mp3")', | |
default='audio-24khz-48kbitrate-mono-mp3' | |
) | |
parser.add_argument( | |
'-l','--list', | |
help='Index an engine then exit. For everything use "__all__"', | |
action=ListEngineAction | |
) | |
class WSClient(WebSocketClient): | |
def __init__(self, url, text, engine, codec): | |
self.text = text | |
self.engine = engine | |
self.format = codec | |
super(WSClient, self).__init__(url) | |
def opened(self): | |
self.send('Content-Type:application/json; charset=utf-8\r\n\r\nPath:speech.config\r\n\r\n{"context":{"synthesis":{"audio":{"metadataoptions":{"sentenceBoundaryEnabled":"false","wordBoundaryEnabled":"true"},"outputFormat":"'+self.format+'"}}}}\r\n') | |
self.send("X-RequestId:fe83fbefb15c7739fe674d9f3e81d38f\r\nContent-Type:application/ssml+xml\r\nPath:ssml\r\n\r\n<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='en-US'><voice name='"+self.engine+"'><prosody pitch='+0Hz' rate ='+0%' volume='+0%'>"+self.text+"</prosody></voice></speak>\r\n") | |
def received_message(self, m): | |
try: | |
if 'turn.end' in m.data: | |
self.close() | |
elif 'Path:audio\r\n' in m.data: | |
sys.stdout.write(m.data.split('Path:audio\r\n')[1]) | |
sys.stdout.flush() | |
else: | |
pass | |
except IOError as nonsense_error: | |
if nonsense_error.errno == errno.EIO: # useless I/O errors | |
pass | |
else: # e.g. broken pipe | |
sys.exit() | |
if __name__ == '__main__': | |
arg = parser.parse_args() | |
ws = WSClient(wsUrl, arg.text, arg.engine, arg.codec) | |
ws.connect() | |
ws.run_forever() |
如何重用一个 wss connection
每次wss connect 都要花费不少时间。
能否用同一个 wss 做多次的tts 请求
Good morning, but pythoni is foreign to mე. problem hare: line 92, in received_message
if 'turn.end' in m.data:
TypeError: a bytes-like object is required, not 'str'
[Finished in 1.4s]
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
不能用了