体验中心
体验中国电信星辰大模型效果
协议类型:WebSocket(WS)
| 环境 | 地址 |
|---|---|
| 公网 | wss://api-maas.teleai.com.cn/aipaas/voice/v1/tts/supernaturalrt |
/aipaas/voice/v1/tts/supernaturalrtWebSocketapplication/json服务接口调用时需要严格遵循服务鉴权规则,采用请求头携带鉴权信息,在建立 WebSocket 连接时通过 Header 传递:
Authorization: <鉴权信息>
| 请求头 | 必填 | 说明 |
|---|---|---|
Content-Type |
是 | 内容类型,固定application/json |
X-APP-ID |
是 | 控制台 → 应用管理 → AppID |
Device-Uuid |
否 | 设备uuid |
Authorization |
是 | 鉴权信息 |
Query 参数:
| 参数 | 必填 | 说明 |
|---|---|---|
app_id |
否 | 由客户端传入,便于排查问题 |
超自然流式语音合成提供将输入文本合成为语音二进制数据的功能。
关于非必填字段的处理原则(根据具体场景灵活选择):
null 或 "" 等隐式空值,除非文档明确允许。查阅文档看是否定义了空值处理方式。数值类型:不传字段(传 0 可能被误认为有效值);字符串类型:不传字段,若必须传空,先确认接口是否支持 "";布尔类型:不传字段(避免误解 false 为有意赋值)。volume 默认为 50);有特殊需求时主动传递新值。| 日期 | 版本 | 修订内容 |
|---|---|---|
| 2025-11-04 | v3.2.0 | 修改功能介绍;修改状态码;入参新增speech_rate 字段;出参注明 status 和 status_msg 下线时间 |
| 2025-08-11 | v3.0 | 修改部分字段说明 |
| 2025-03-18 | v1.6.5.8 | 初始化 API 文档 |
客户端通过 WebSocket 连接发送 JSON 消息,请求报文为 Json Object:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
req_id |
string | 是 | 请求全局唯一 ID,记录该值便于排查问题 |
text |
string | 是 | 待合成的文本,需要为 UTF-8 编码 |
format |
string | 否 | 音频编码格式,支持 PCM 格式,默认值:PCM |
sample_rate |
int | 否 | 音频采样率,支持 24000Hz、22050Hz、16000 Hz 和 8000 Hz,默认值:24000 |
voice |
string | 否 | 说话人,支持音色cixingnan、songchinan、surennan、cixingnan2、zhubonan、kefunan、zhuchinan、jilunan2、surennv、xianliaonv、mansunv、kefunv1、huoponv、ruyanv、xinwennv、kefunv2、luolinv、huoponv2、qingtiannv、cixingnan3、gaojinv、gushinan2、jilunan1、kejinan1、kejinan2、pingdannv、tuokouxiu、xuanyinan、sarah,默认音色为 cixingnan |
speech_rate |
float | 否 | 语速,取值范围:[0.5, 2.0],默认值:1.0 |
volume |
int | 否 | 音量,取值范围:[0, 100],默认值:50 |
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
status |
int | 是 | 状态码,与code 相同(注:2025 年 11 月 30 日后不再返回此字段) |
status_msg |
string | 是 | 状态说明,与message 相同(注:2025 年 11 月 30 日后不再返回此字段) |
code |
int | 是 | 状态码,见服务码说明 |
message |
string | 是 | 状态说明,见服务码说明 |
sid |
string | 否 | 会话全局唯一 id,用于记录本次会话 |
result |
object | 否 | 合成结果 |
result| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
audio |
string | 否 | 合成音频数据,经过 base64 编码 |
audio_len |
int | 否 | 合成音频长度,单位:ms |
is_end |
boolean | 否 | 标志位:true 最后一个合成片段;false 中间合成片段 |
客户端发起请求,服务端确认请求有效。其中在请求消息中进行参数设置:
{
"req_id": "3a87fe9793c9-4ebd-95d4-4ce2-a80c054b",
"text": "今天是周一,天气挺好的。"
}
客户端发起开始检测请求后,服务端建立连接,并进行签名校验以及参数解析,校验成功并且解析成功,则返回对应的消息表示握手成功;如果校验失败或解析失败,服务端返回对应的消息并断开连接。
{
"code": 10000,
"message": "Success",
"status": 10000,
"status_msg": "Success",
"sid": "4eHgiLCBhbGdvcml"
}
服务端返回合成的语音二进制数据。客户端接收到服务端发送的确认合成请求有效的响应后,开始循环接收语音数据。
{
"code": 10000,
"message": "Success",
"status": 10000,
"status_msg": "Success",
"result": {
"audio": "//6YYmNiDlSUXjZlDP8yADQAQ1E2ANKJOaTqFGUgIwDQAKAA==",
"audio_len": 2500,
"is_end": false
}
}
语音合成完毕,服务端发送合成完毕事件通知:
{
"code": 10000,
"message": "Success",
"status": 10000,
"status_msg": "Success",
"result": {
"audio": "//6YYmNiDlSUXjZlDP8yADQAQ1E2ANKJOaTqFGUgIwDQAKAA==",
"audio_len": 2500,
"is_end": true
}
}
| WS CODE | 说明 | 错误描述信息 | 解决方法 |
|---|---|---|---|
101 |
成功 | {"message":"success"} |
成功,开始语音合成 |
4001 |
签名校验失败,授权失败 | {"message":"check sign fail"} |
联系商务,更新授权 |
4002 |
并发请求过多 | {"message":"Too many requests."} |
联系商务,增加并发 |
| 状态码 | 说明 | 描述 | 解决方法 |
|---|---|---|---|
10000 |
Success | 成功 | 执行下一步操作 |
10301 |
Parameter error | 参数错误 | 检查请求体是否符合接口协议 |
10304 |
Parse request body fail | 请求格式错误 | 查看请求的 URL body 格式是否正确,参考接口文档 |
10503 |
Server connection time out | 服务连接超时 | 联系技术人员 |
10903 |
Synthesis failed | 合成失败 | 联系技术人员 |
通用状态码请参考【状态码】中的【网关认证】。
import argparse
import asyncio
import websockets
import json
import base64
import logging
import time
# 配置日志,设置日志级别为INFO,并指定日志格式
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger()
async def uws_call(args):
# 获取命令行参数中的URL
url = args.url
# 记录开始时间
start_time = time.time()
logger.info(f"开始建立websocket连接,获取当前时间:{start_time}")
header = {
"Content-Type": "application/json",
'X-APP-ID': args.X_APP_ID,
'Authorization': args.Authorization
}
# 建立WebSocket连接
async with websockets.connect(url, extra_headers=header) as websocket:
logger.info("=================================请求参数start_json===============================")
# 构建请求参数
start_json = {
'req_id': 'test001',
'text': 'yourText'
}
logger.info(f"请求参数:{start_json}")
# 发送请求参数
await websocket.send(json.dumps(start_json))
try:
# 接收响应
resp_str = await websocket.recv()
resp_data = json.loads(resp_str)
if resp_data['status'] == 10000:
logger.info('Received initial response: %s', resp_str)
# 记录连接建立(即收到第一个响应)的时间
connection_established_time = time.time()
logger.info('WebSocket connection established in %.2f seconds',
connection_established_time - start_time)
is_end = False
# 打开文件以写入音频数据
with open("test.pcm", "wb") as f:
while not is_end:
# 接收音频数据
resp_audio_str = await websocket.recv()
resp_audio_data = json.loads(resp_audio_str)
if resp_audio_data['status'] != 10000:
logger.error('Received non-success status: %s', resp_audio_data)
break
if 'result' in resp_audio_data:
synth_info = resp_audio_data['result']
logger.info('Received synthesis info: %s', synth_info)
# 解码音频数据并写入文件
audio_wav = base64.b64decode(synth_info['audio'])
f.write(audio_wav)
is_end = synth_info['is_end']
else:
logger.error('No result in response: %s', resp_audio_data)
break
# 计算整个交互的耗时(从尝试连接到接收完所有消息)
total_duration = time.time() - start_time
logger.info('Total interaction duration: %.2f seconds', total_duration)
except websockets.exceptions.ConnectionClosed as e:
logger.error('WebSocket connection closed: %s', e)
# 如果连接关闭了,我们仍然可以记录到目前为止的耗时
logger.info('Duration until connection closed: %.2f seconds', time.time() - start_time)
except Exception as e:
logger.error('An error occurred: %s', e)
# 如果发生错误,我们同样记录到目前为止的耗时
logger.info('Duration until error occurred: %.2f seconds', time.time() - start_time)
finally:
# 关闭WebSocket连接
await websocket.close()
def main(args):
# 运行异步函数
asyncio.get_event_loop().run_until_complete(uws_call(args))
if __name__ == '__main__':
# 解析命令行参数
parser = argparse.ArgumentParser()
parser.add_argument('--url', type=str, default='wss://api-maas.teleai.com.cn/aipaas/voice/v1/tts/supernaturalrt')
parser.add_argument('--X_APP_ID', type=str, default='yourAppId')
parser.add_argument('--Device_Uuid', type=str, default='yourDeviceUuid')
parser.add_argument('--Authorization', type=str, default='yourAuthorization')
args = parser.parse_args()
# 调用主函数
main(args)
import com.alibaba.fastjson.JSONObject;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
/**
* 为保证示例可以正常运行,请确认maven中是否存在以下依赖:
* <dependency>
* <groupId>org.java-websocket</groupId>
* <artifactId>Java-WebSocket</artifactId>
* <version>1.5.3</version>
* </dependency>
* <dependency>
* <groupId>com.alibaba</groupId>
* <artifactId>fastjson</artifactId>
* <version>2.0.49</version>
* </dependency>
*/
public class WebSocketExample extends WebSocketClient {
public WebSocketExample(URI serverUri, Map headers) {
super(serverUri, headers);
}
public static void main(String[] args) {
try {
// 创建WebSocket客户端
URI uri = new URI("wss://api-maas.teleai.com.cn/aipaas/voice/v1/tts/supernaturalrt");
Map headers = new HashMap();
// 调用鉴权
headers.put("X-APP-ID", "yourAppId");
headers.put("Authorization", "yourAuthorization");
WebSocketExample client = new WebSocketExample(uri, headers);
client.connect();
// 等待一段时间后关闭连接
Thread.sleep(5000);
client.close();
} catch (URISyntaxException | InterruptedException e) {
e.printStackTrace();
System.out.println("WebSocket error: " + e.getMessage());
}
}
@Override
public void onOpen(ServerHandshake handshakedata) {
System.out.println("WebSocket connection opened");
// 发送消息
try {
// 初始化连接消息
JSONObject initSend = new JSONObject();
initSend.put("req_id", "test001");
initSend.put("text", "yourText");
send(initSend.toJSONString());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onMessage(String message) {
System.out.println("Received message: " + message);
}
@Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("WebSocket connection closed: " + reason);
}
@Override
public void onError(Exception ex) {
System.err.println("WebSocket error: " + ex.getMessage());
}
}