准备工作 (Prerequisites)
在调用任何接口之前,您需要准备好您在本站的用户名和密码。请注意,请勿使用注册邮箱作为user参数,应使用您的用户名。
核心概念:认证与授权
为了保障接口安全,我们所有的请求都需要进行签名和加密验证。
-
时间戳 (Timestamp):所有接口都需要一个13位的毫秒级时间戳,参数名为 ts。
-
签名 (Sign):部分接口需要对请求进行签名,签名算法为 md5(username + ts)。
-
授权头 (Authorization Header):queryorder 和 mstts 接口需要在HTTP请求头中加入 Authorization 字段。该字段的值是通过 AES 加密生成
-
模式:ECB
-
填充:PKCS7
-
密钥 (Key):一个16位的自定义字符串,在首次获取token时生成或指定。
-
待加密数据:一个包含user, token, ts的JSON字符串。
-
API 接口详解
基础URL (Base URL): http://47.96.88.233:2048
1. 获取Token (/gettoken)
此接口用于获取后续接口调用所需的 token 和 key。
接口地址:/gettoken
请求方法:POST
请求参数 (data):
- user (string): 您的网站用户名。
- psw (string): 您的网站密码。
- type (integer): 操作类型。0表示获取token,1表示更新key和token。
- key (string, optional): 16位自定义密钥。如果留空,系统将为您随机生成一个(建议自动生成,更安全)。
- ts (string): 13位时间戳。
- sign (string): 签名,计算方式为 md5(user + ts)。
返回数据示例:
{ "code": 0, "maxChar": 20000000, "date": "2024-12-31", "charNum": 3015, "key": "your_16_bit_key", "token": "your_generated_token", "msg": "success" }
2. 查询套餐信息 (/queryorder)
查询您当前账户的字符套餐余量和到期时间。
-
接口地址:/queryorder
-
请求方法:POST
-
请求头 (Headers):Authorization: 经过AES加密后的授权字符串。
-
请求参数 (data):user (string): 您的网站用户名。ts (string): 13位时间戳。sign (string): 签名,计算方式为 md5(user + ts)。
-
返回数据示例:
{ "code": 0, "maxChar": 20000000, "date": "2024-12-31", "charNum": 3015, "msg": "success" }
3. 微软TTS语音合成 (/mstts)
核心接口,用于将SSML文本合成为语音。
-
接口地址:/mstts
-
请求方法:POST
-
请求头 (Headers):Authorization: 经过AES加密后的授权字符串。
-
请求参数 (PostData, JSON格式):
- user (string): 您的网站用户名。
- ssml (string): 经过 Base64编码 的SSML文本。注意:单次请求的原文长度不能超过2000字符。
- ts (string): 13位时间戳。
- sign (string): 签名,计算方式为 md5(user + ts)。
-
返回数据示例:
{ "code": 0, "msg": "success", "base64audio": "UklGRiQ... (base64编码的mp3音频数据)", "charNum": 3515, "maxChar": 20000000 }
您只需将 base64audio 字段的内容进行Base64解码,即可得到mp3音频文件。
重要注意事项
-
启用重定向:所有接口请求都必须启用HTTP重定向(allow_redirects=True)。
-
并发限制:接口限制最高并发为 4次/秒。超过此限制服务器将返回 429 状态码。
-
SSML文档:关于如何编写SSML以控制语音情感、停顿、多角色发音等高级功能,请参考 。
API 快速测试工具
为了方便您在编码前快速验证接口的有效性,我们提供了API测试工具。您可以在页面顶部免费下载。
- 获取token:/gettoken
- 套餐查询: /queryOrder
- 微软TTS语音合成:/mstts
Python API 调用完整示例代码
以下是一个完整的Python示例,演示了从获取Token到最终合成语音的全过程。您需要安装 requests 和 pycryptodome 库。
pip install requests pycryptodome
import base64 import hashlib import json import os import requests from Crypto.Cipher import AES import time from Crypto.Util.Padding import pad, unpad base_url="http://47.96.88.233:2048" # AES加密,ECB模式 class AESCipher: def __init__(self, key): self.key = key.encode('utf-8') self.block_size = AES.block_size def encrypt(self, plain_text): cipher = AES.new(self.key, AES.MODE_ECB) padded_text = pad(plain_text.encode('utf-8'), self.block_size) return base64.b64encode(cipher.encrypt(padded_text)).decode('utf-8') def decrypt(self, encrypted_text): cipher = AES.new(self.key, AES.MODE_ECB) decrypted_text = unpad(cipher.decrypt(base64.b64decode(encrypted_text)), self.block_size) return decrypted_text.decode('utf-8') # 获取13位时间戳 def getts(): return str(int(time.time() * 1000)) # 获取sign def get_sign(user,ts): data=f'{user}{ts}' return hashlib.md5(data.encode('utf-8')).hexdigest() # Base64解码到文件 def base64_to_file(base64_string, file_path): with open(file_path, 'wb') as file: file.write(base64.b64decode(base64_string)) # Base64编码 def enbase64(original_string): return base64.b64encode(original_string.encode('utf-8')).decode('utf-8') # 获取token def get_token(user, psw, stype,key): ts = getts() sign = get_sign(user , ts) data = json.dumps({"user": user, "psw": psw, "type": stype,"key": key,"ts": ts,"sign": sign}) headers = {'Content-Type': 'application/json'} response = requests.post(base_url+'/gettoken',data=data,headers=headers,allow_redirects=True) return response.text # 查询订单 def query_order(user, key,token): ts = getts() sign = get_sign(user , ts) data = json.dumps({"user": user, "ts": ts, "sign": sign}) aes = AESCipher(key) auth = aes.encrypt('{"user":"'+user+'","token":"'+token+'","ts":"'+ts+'"}') headers = {'Content-Type': 'application/json', 'Authorization': auth} response = requests.post(base_url+'/queryorder',data=data,headers=headers,allow_redirects=True) response = requests.post(response.url, data=data, headers=headers) return response.text # 文本转语音 def mstts(user,ssml,key,token): ssml = ssml.replace('\r\n', '') ts = getts() sign = get_sign(user , ts) data = json.dumps({"user": user, "ssml":base64.b64encode(ssml.encode('utf-8')).decode('utf-8'),"ts": ts, "sign": sign}) aes = AESCipher(key) auth = aes.encrypt('{"user":"'+user+'","token":"'+token+'","ts":"'+ts+'"}') headers = {'Content-Type': 'application/json', 'Authorization': auth} response = requests.post(base_url+'/mstts',data=data,headers=headers, allow_redirects=True) response = requests.post(response.url, data=data, headers=headers) if response.status_code == 200: jo = response.json() if jo['code'] == 0: audiostr = jo['base64audio'] base64_to_file(audiostr, os.path.join(os.path.dirname(__file__), 'test.mp3')) return response.text else: return response.text return response.text # 示例使用 if __name__ == "__main__": #网站用户名(不要使用邮箱) user = "" #网站密码 psw = "" #0表示获取token,1表示更新key、token stype = "0" #自定义密钥,16位字符串,留空则随机生成(推荐随机生成) key = "" token ="" gtoken =json.loads(get_token(user, psw, stype,key)) if(gtoken['code'] == 0): token=gtoken['token'] key=gtoken['key'] print("get token",gtoken) if(token != ''): order_info = query_order(user, key,token) print("Order Info:", order_info) ssml = '''<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US"><voice name="en-US-AriaNeural"><mstts:express-as style="Cheerful">"That’s remarkable! You’re a genius!"</mstts:express-as>Mom said to her son.</voice><voice name="en-US-JennyNeural">Customize output by <prosody rate="-40.00%"> slowing-down the speed rate.</prosody></voice><voice name="en-US-GuyNeural">Add a break <break time="600ms" /> between words.</voice><voice name="en-GB-SoniaNeural">You can pronounce it <say-as interpret-as="spell">ASAP </say-as>or <sub alias="as soon as possible">ASAP</sub>.</voice><voice name="zh-CN-XiaoxiaoNeural"><s /><mstts:express-as style="chat">可以通过停顿里的高级功能“No break”,解决<phoneme alphabet="sapi" ph="fen 1 ci 2">分词</phoneme>引起的多余停顿问题。</mstts:express-as><s /><mstts:express-as style="chat">也可以合成多角色多情感的有声<prosody contour="(49%, -40%)">书</prosody>,例如:</mstts:express-as></voice><voice name="zh-CN-YunyeNeural">黛玉冷笑道:</voice><voice name="zh-CN-XiaoxiaoNeural"><s /><mstts:express-as style="disgruntled">“我说呢,亏了绊住,不然,早就飞了来了。”</mstts:express-as><s /> </voice><voice name="zh-CN-YunyeNeural">宝玉道:</voice><voice name="zh-CN-YunxiNeural">“只许和你玩,替你解闷。不过偶然到他那里,就说这些闲话。”</voice><voice name="zh-CN-XiaoxiaoNeural"><mstts:express-as style="angry">”好没意思的话!去不去,关我什么事儿?又没叫你替我解闷儿,还许你<mstts:ttsbreak strength="none" />从此<prosody contour="(24%, +49%) (59%, -2%)">不</prosody><prosody rate="-15.00%" contour="(24%, +49%) (59%, -2%)">理</prosody><prosody contour="(24%, +49%) (59%, -2%)">我呢</prosody>!”</mstts:express-as></voice><voice name="zh-CN-YunyeNeural"><s />说着,便赌气回房去了。</voice></speak>''' tts_result = mstts(user, ssml, key,token) print("TTS Result:", tts_result)




评论(0)