通过 WebSocket 长连接实时合成 Sambert 语音,支持流式音频输出与字/音素级时间戳
本文介绍通过 WebSocket 连接访问 Sambert 实时语音合成服务的交互流程、服务端点和请求头。
DashScope SDK 目前仅支持 Java 和 Python。使用其他编程语言时,可通过 WebSocket 连接与服务进行通信。
用户指南: 关于模型介绍和选型建议请参见语音合成。
WebSocket 服务端点固定为:
请求头中需添加如下信息:
客户端事件和服务端事件的详细说明,请参见客户端事件和服务端事件。
按时间顺序,客户端与服务端的交互流程如下:
服务端返回两种类型的消息:
task-started 事件
result-generated 事件(含时间戳示例)
task-finished 事件
task-failed 事件
客户端只需发送一条 JSON 消息:
run-task header 字段说明
Python 生成 UUID 示例:
run-task payload 参数说明
收到
建立 WebSocket 连接需要 TLS 握手,有一定延迟开销。对于需要高频合成的场景,建议:
服务端点
WebSocket 服务端点固定为:wss://dashscope.aliyuncs.com/api-ws/v1/inference
URL 必须使用
wss:// 协议,且固定不变。Authorization 在请求头中设置(参见请求头)。请求头
请求头中需添加如下信息:
| 参数 | 类型 | 是否必选 | 说明 |
|---|---|---|---|
| Authorization | string | 是 | 鉴权令牌,格式为 Bearer <your_api_key>,将 <your_api_key> 替换为实际的 API Key。 |
| user-agent | string | 否 | 客户端标识,便于服务端追踪来源。 |
| X-DashScope-WorkSpace | string | 否 | 千问云业务空间 ID。 |
| X-DashScope-DataInspection | string | 否 | 是否启用数据合规检测功能。默认不传或设为 enable。如非必要,请勿启用该参数。 |
Authorization 鉴权在 WebSocket 握手阶段验证。如果 API Key 无效或缺失,握手将失败并返回 HTTP 401/403 错误。
交互流程
客户端事件和服务端事件的详细说明,请参见客户端事件和服务端事件。
按时间顺序,客户端与服务端的交互流程如下:
- 建立连接:客户端与服务端建立 WebSocket 连接。
- 开启任务:客户端发送 run-task 事件以开启任务。Sambert 在 run-task 中一次性发送全部待合成文本。
- 等待确认:客户端收到服务端返回的 task-started 事件,标志着任务已成功开启。
- 接收音频:客户端通过
binary通道接收服务端持续返回的音频流,同时收到 result-generated 事件(携带时间戳等附加信息)。 - 任务结束:客户端收到服务端返回的 task-finished 事件,标志着任务结束。
- 关闭连接:客户端关闭 WebSocket 连接。
Sambert 不支持流式输入(streaming 为
out 而非 duplex),所有待合成文本必须在 run-task 事件中一次性发送。不支持 continue-task 和 finish-task 指令。前提条件
- 已获取 DashScope API Key 并配置为环境变量
DASHSCOPE_API_KEY。 - 网络环境支持访问
dashscope.aliyuncs.com(国内访问)。
约束
- WebSocket 连接建立后,需先发送
run-task指令,服务端才会开始合成并推送音频。 - 一次 WebSocket 连接只对应一次合成任务(一个
task_id)。任务完成(task-finished)后可复用同一连接发起新任务;任务失败(task-failed)后连接将被关闭,需重新建立连接。 - 待合成文本长度上限:一次
run-task请求不超过 10,000 个字符(含标点)。
二、异步监听服务器返回的消息
服务端返回两种类型的消息:
- 二进制消息:音频数据流,客户端直接写入文件或播放缓冲区。
- 文本消息(JSON):事件通知,包含以下类型:
| 字段 | 类型 | 说明 |
|---|---|---|
header | Object | 消息头 |
header.event | String | 事件类型:task-started、result-generated、task-finished、task-failed |
header.task_id | String | 任务 ID,与发送 run-task 时的 task_id 一致 |
output.sentence 字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
begin_time | Integer | 句子开始时间(毫秒) |
end_time | Integer | 句子结束时间(毫秒) |
words | Array | 字级别时间戳列表(开启 word_timestamp_enabled 后返回) |
words 中每个元素的字段:
| 字段 | 类型 | 说明 |
|---|---|---|
text | String | 汉字文本 |
begin_time | Integer | 开始时间(毫秒) |
end_time | Integer | 结束时间(毫秒) |
phonemes | Array | 音素级时间戳列表(开启 phoneme_timestamp_enabled 后返回) |
phonemes 中每个元素的字段:
| 字段 | 类型 | 说明 |
|---|---|---|
begin_time | Integer | 开始时间(毫秒) |
end_time | Integer | 结束时间(毫秒) |
text | String | 音素文本 |
tone | Integer | 声调(1–4,0 表示轻声) |
task-failed 错误字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
header.error_code | String | 错误码,如 CLIENT_ERROR、SERVER_ERROR 等 |
header.error_message | String | 错误详情描述 |
三、给服务器发送消息
客户端只需发送一条 JSON 消息:run-task 指令。
消息结构
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
header.action | String | 是 | 固定值 run-task |
header.task_id | String | 是 | 任务 ID,格式为随机 UUID,同一连接内不可重复 |
header.streaming | String | 是 | 固定值 out,表示流式输出 |
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
task_group | String | 是 | 固定值 audio |
task | String | 是 | 固定值 tts |
function | String | 是 | 固定值 SpeechSynthesizer |
model | String | 是 | 模型名称,详见模型列表 |
input.text | String | 是 | 待合成文本,最长 10,000 个字符 |
parameters.text_type | String | 否 | 文本类型。PlainText(默认):纯文本;SSML:SSML 标记语言 |
parameters.format | String | 否 | 音频格式。支持 pcm、wav、mp3(默认 pcm) |
parameters.sample_rate | Integer | 否 | 采样率(Hz)。默认值由模型决定,常见值为 16000、48000 |
parameters.volume | Integer | 否 | 音量,范围 0–100,默认 50 |
parameters.rate | Float | 否 | 语速,范围 0.5–2.0,默认 1.0(1.0 为正常语速) |
parameters.pitch | Float | 否 | 音调,范围 0.5–2.0,默认 1.0(1.0 为正常音调) |
parameters.word_timestamp_enabled | Boolean | 否 | 是否返回字级别时间戳,默认 false |
parameters.phoneme_timestamp_enabled | Boolean | 否 | 是否返回音素级别时间戳,默认 false |
四、关闭 WebSocket 连接
收到 task-finished 事件后,客户端可选择:
- 关闭连接:调用 WebSocket 关闭接口(推荐在不再需要合成时关闭)。
- 复用连接:使用新的
task_id发送下一个run-task指令,继续合成新文本,无需重新建立连接(节省握手开销)。
task-failed 事件后,连接由服务端关闭,客户端需要重新建立连接。
关于建连开销和连接复用
建立 WebSocket 连接需要 TLS 握手,有一定延迟开销。对于需要高频合成的场景,建议:
- 维持长连接,通过切换
task_id复用同一连接。 - 对连接进行池化管理,避免频繁断连重连。
示例代码
错误码
通用错误码请参阅错误信息。
WebSocket 特有错误通过 task-failed 事件返回,错误码位于 header.error_code,错误信息位于 header.error_message。
常见问题
Q:连接建立后没有收到任何音频数据?
A:请确认已发送 run-task 指令,且指令格式正确。检查 payload.input.text 是否非空,model 是否为有效的模型名称。
Q:task-failed 错误码为 CLIENT_ERROR,错误信息包含 timeout?
A:连接建立后需在较短时间内(通常 23 秒内)发送 run-task 指令,否则服务端会超时并关闭连接。
Q:能否在同一连接内合成多段文本?
A:可以。收到 task-finished 后,使用不同的 task_id 再次发送 run-task 指令即可。注意 task-failed 后连接已关闭,需重新建连。
模型列表
中文音色(48 kHz)
| 音色名 | model 参数 | 时间戳支持 | 适用场景 | 特色 | 默认采样率(Hz) |
|---|---|---|---|---|---|
| 广告男声 | sambert-zhinan-v1 | 是 | 广告配音 | 磁性、自信 | 48000 |
| 温柔女声 | sambert-zhiqi-v1 | 是 | 情感类内容 | 柔和、亲切 | 48000 |
| 舌尖男声 | sambert-zhichu-v1 | 是 | 通用 | 清晰、标准 | 48000 |
| 新闻男声 | sambert-zhide-v1 | 是 | 新闻播报 | 沉稳、权威 | 48000 |
| 标准女声 | sambert-zhijia-v1 | 是 | 通用 | 标准、清晰 | 48000 |
| 新闻女声 | sambert-zhiru-v1 | 是 | 新闻播报 | 专业、流畅 | 48000 |
| 资讯女声 | sambert-zhiqian-v1 | 是 | 资讯播报 | 干练、利落 | 48000 |
| 磁性男声 | sambert-zhixiang-v1 | 是 | 有声读物 | 磁性、浑厚 | 48000 |
| 萝莉女声 | sambert-zhiwei-v1 | 是 | 动漫、娱乐 | 活泼、可爱 | 48000 |
中文音色(16 kHz)
| 音色名 | model 参数 | 时间戳支持 | 适用场景 | 语言 | 默认采样率(Hz) |
|---|---|---|---|---|---|
| — | sambert-zhihao-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhijing-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhiming-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhimo-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhina-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhishu-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhistella-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhiting-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhixiao-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhiya-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhiye-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhiying-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhiyuan-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhiyue-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhigui-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhishuo-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhimiao-emo-v1 | 是 | 情感类 | 中文 | 16000 |
| — | sambert-zhimao-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhilun-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhifei-v1 | 是 | 通用 | 中文 | 16000 |
| — | sambert-zhida-v1 | 是 | 通用 | 中文 | 16000 |
多语种音色(16 kHz)
| 音色名 | model 参数 | 时间戳支持 | 语言 | 默认采样率(Hz) |
|---|---|---|---|---|
| — | sambert-camila-v1 | 否 | 西班牙语 | 16000 |
| — | sambert-perla-v1 | 否 | 意大利语 | 16000 |
| — | sambert-indah-v1 | 否 | 印尼语 | 16000 |
| — | sambert-clara-v1 | 否 | 法语 | 16000 |
| — | sambert-hanna-v1 | 否 | 德语 | 16000 |
英语音色(美式,16 kHz)
| 音色名 | model 参数 | 时间戳支持 | 语言 | 默认采样率(Hz) |
|---|---|---|---|---|
| — | sambert-beth-v1 | 是 | 英语(美式) | 16000 |
| — | sambert-betty-v1 | 是 | 英语(美式) | 16000 |
| — | sambert-cally-v1 | 是 | 英语(美式) | 16000 |
| — | sambert-cindy-v1 | 是 | 英语(美式) | 16000 |
| — | sambert-eva-v1 | 是 | 英语(美式) | 16000 |
| — | sambert-donna-v1 | 是 | 英语(美式) | 16000 |
| — | sambert-brian-v1 | 是 | 英语(美式) | 16000 |
泰语音色(16 kHz)
| 音色名 | model 参数 | 时间戳支持 | 语言 | 默认采样率(Hz) |
|---|---|---|---|---|
| — | sambert-waan-v1 | 否 | 泰语 | 16000 |

