WebSocket合成
更新时间:
WebSocket 流式语音合成
服务概述
- 通过 WebSocket 长连接进行流式语音合成,客户端发送 JSON 文本帧,服务端返回任务初始化、音频分片、任务完成或错误事件。
- WebSocket 接口适用于需要在同一连接内连续发送多条合成请求、并按任务 ID 归并返回事件的实时语音场景。
服务申请
语音合成 API 采用全流程自助申请模式。在云上曲率官网(https://www.ilivedata.com/) 注册并激活账号后,在控制台创建语音合成项目,即可获得 appId 和服务密钥。
如需开通更多服务,可在管理控制台-总览页面开通其他服务。
接入流程
- 调用 Token 签发接口,使用 appId 和 secretKey 完成 auth 鉴权,获取 WebSocket Token。
- 使用返回的
wsUrl 拼接 token 参数建立 WebSocket 连接。
- 建连成功后,客户端通过 WebSocket 发送合成请求 JSON。
- 服务端通过 WebSocket 返回
init、audio、done、error 事件。
获取 WebSocket Token
请求 URL
https://tts.ilivedata.com/api/v1/speech/synthesis/ws-token
HTTP 请求头
请求头
值
描述
X-AppId
例:81900001
项目或应用的唯一标识符
X-TimeStamp
例:2024-07-01T07:59:59Z
请求的 UTC 时间戳。需要把时间戳按 W3C 标准格式化
Authorization
例:Njl86M/jY6zZaZoGhZdGO+GI/8+yGFECusGH1yQHUFE=
签名值
请求方法:GET
请求签名
当用户请求 Token 签发接口时,使用 appId 和 secretKey 对请求做签名。当 API 收到带签名信息的请求之后,将使用相同的算法验证签名。如果发现签名不一致,API 将会返回鉴权失败。
签名计算方法
签名计算规则请参考帮助中心的请求签名。Token 签发接口为 GET 请求,通常没有请求体,按 GET 无请求体场景计算签名。HTTPRequestURI 是请求 URI 的绝对路径,不包含请求串。
签名示例
GET
tts.ilivedata.com
/api/v1/speech/synthesis/ws-token
X-AppId:81900001
X-TimeStamp:2024-11-01T07:59:59Z
请求示例
curl -X GET 'https://tts.ilivedata.com/api/v1/speech/synthesis/ws-token' \
-H 'X-AppId: 81900001' \
-H 'X-TimeStamp: 2024-11-01T07:59:59Z' \
-H 'Authorization: {signature}'
响应示例
{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 60,
"expiresAt": 1782359144,
"wsUrl": "wss://tts.ilivedata.com/api/v1/speech/synthesis/ws"
}
响应字段说明
字段名
类型
描述
token
String
WebSocket JWT,签名算法为 RS256
expiresIn
Number
Token 有效期,单位秒。Token 需要在有效期内用于建立 WebSocket 连接
expiresAt
Number
Token 过期时间,Unix 秒
wsUrl
String
TTS WebSocket 连接地址,不含 token 参数
建立 WebSocket 连接
WebSocket 连接地址
wss://tts.ilivedata.com/api/v1/speech/synthesis/ws?token={token}
Token 只用于 WebSocket 握手鉴权。连接建立成功后,当前连接不会因为 Token 到期自动断开;如果连接断开后需要重连,应重新获取 Token。
TTS 服务会校验 JWT 的签名、过期时间、aud、iss、scope、path 和 appId。请求消息中的 appId 必须与 Token 中的 appId 一致。
WebSocket 请求参数
建连成功后,客户端通过 WebSocket 文本消息发送请求体 JSON。
顶层参数
参数
是否必需
类型
描述
appId
条件必需
Number
与 request.appId 二选一;服务端优先取顶层 appId
sessionId
可选
String
业务会话 ID;不传时同一 WebSocket 连接内复用连接级默认 sessionId
request
必需
Object
合成请求体,结构与 SynthesisRequest 一致
request
参数
是否必需
类型
描述
appId
条件必需
Number
与顶层 appId 二选一
text
必需
String
合成文本,去除首尾空白后不能为空
language
可选
String
文本内容所属语种,推荐传入此语言参数;不传则使用自动语种检测结果。支持语种请参考语种列表
voice
可选
VoiceSetting
合成声音相关配置
output
可选
OutputSetting
输出音频相关配置
VoiceSetting
参数
必需
类型
描述
name
可选
String
预置音色库或音色注册的音色名称
audio
可选
String
未指定音色名称时,可以通过此参数指定的音频文件进行音色克隆
emotion
可选
String
情感表达
OutputSetting
参数
必需
类型
描述
format
可选
String
选择输出合成音频格式,候选为 pcm、wav、mp3、opus,默认为 wav
请求体示例
{
"appId": 81900001,
"request": {
"appId": 81900001,
"text": "您好,这是一个 WebSocket 流式语音合成示例。",
"language": "zh-CN",
"voice": {
"name": "juvenile"
},
"output": {
"format": "mp3"
}
}
}
如果客户端需要自定义业务会话,可显式传入 sessionId:
{
"appId": 81900001,
"sessionId": "biz-session-001",
"request": {
"appId": 81900001,
"text": "同一个业务会话内的第一条消息。",
"voice": {
"name": "juvenile"
},
"output": {
"format": "mp3"
}
}
}
WebSocket 响应事件
init 事件
表示服务端已接受该任务,并返回任务标识信息。
字段名
类型
描述
event
String
固定为 init
taskId
String
任务 ID,由服务端生成
sessionId
String
会话 ID;客户端未传时由服务端按连接生成
status
String
固定为 init
taskStatus
Number
任务状态
{
"event": "init",
"taskId": "bj_ws_1b3d21549d3841d3b4400829403a4fff",
"sessionId": "bj_ws_5f45c8fa85814b159741c80620f705bf",
"status": "init",
"taskStatus": 1
}
audio 事件
表示一个音频分片。
字段名
类型
描述
event
String
固定为 audio
taskId
String
任务 ID
sessionId
String
会话 ID
seq
Number
音频分片序号
itemIndex
Number
文本分片索引
itemDone
Boolean
当前 itemIndex 是否完成
sampleRate
Number
当前音频分片采样率
durationMs
Number
当前音频分片时长,单位毫秒
audioBase64
String
音频二进制分片的 Base64 字符串
status
String
固定为 streaming
{
"event": "audio",
"taskId": "bj_ws_1b3d21549d3841d3b4400829403a4fff",
"sessionId": "bj_ws_5f45c8fa85814b159741c80620f705bf",
"seq": 12,
"itemIndex": 0,
"itemDone": false,
"sampleRate": 22050,
"durationMs": 120,
"audioBase64": "...",
"status": "streaming"
}
done 事件
表示任务完成,服务端已上传完整音频文件。
字段名
类型
描述
event
String
固定为 done
taskId
String
任务 ID
sessionId
String
会话 ID
status
String
固定为 done
url
String
上传后的音频文件访问地址
{
"event": "done",
"taskId": "bj_ws_1b3d21549d3841d3b4400829403a4fff",
"sessionId": "bj_ws_5f45c8fa85814b159741c80620f705bf",
"status": "done",
"url": "https://xxx.cos.accelerate.myqcloud.com/tts/.../bj_ws_1b3d21549d3841d3b4400829403a4fff.mp3"
}
error 事件
表示任务失败。
字段名
类型
描述
event
String
固定为 error
taskId
String
任务 ID,若请求未进入任务初始化阶段可能为空
sessionId
String
会话 ID,若请求未进入任务初始化阶段可能为空
status
String
固定为 error
errorCode
Number
错误码
errorMessage
String
错误信息
{
"event": "error",
"taskId": "bj_ws_1b3d21549d3841d3b4400829403a4fff",
"sessionId": "bj_ws_5f45c8fa85814b159741c80620f705bf",
"status": "error",
"errorCode": 3003,
"errorMessage": "Invalid voice name."
}
taskId 与 sessionId 规则
- 客户端不需要传
taskId。服务端会为每条消息生成新的唯一 taskId,并在 init、audio、done、error 事件中返回。
- 如果客户端传入
taskId,服务端会忽略该字段,仍然使用服务端生成的 taskId。
- 客户端不传
sessionId 时,服务端会在 WebSocket 建连时生成一个连接级默认 sessionId;同一连接内多条消息会返回相同 sessionId。
- 客户端显式传入
sessionId 时,服务端优先使用客户端传入的 sessionId。
断线处理说明
- WebSocket 断开后,客户端需要重新建立连接并重新发送合成请求。
- 服务端不会使用客户端传入的
taskId 做任务级恢复。
- 如果业务需要关联断线前后的请求,可由客户端传入同一个
sessionId 作为业务会话标识。
客户端处理建议
- Token 有有效期,建议获取后立即建立 WebSocket 连接。
- 收到
init 后可记录服务端返回的 taskId 和 sessionId,用于日志排查和业务侧事件归并。
audioBase64 需要 Base64 解码后再播放或缓存。
- 以
done 事件为准获取最终文件 URL。
- 若连接断开,需要重新建立 WebSocket 连接并重新发送请求;新的请求会生成新的
taskId。
WebSocket 流式语音合成
服务概述
- 通过 WebSocket 长连接进行流式语音合成,客户端发送 JSON 文本帧,服务端返回任务初始化、音频分片、任务完成或错误事件。
- WebSocket 接口适用于需要在同一连接内连续发送多条合成请求、并按任务 ID 归并返回事件的实时语音场景。
服务申请
语音合成 API 采用全流程自助申请模式。在云上曲率官网(https://www.ilivedata.com/) 注册并激活账号后,在控制台创建语音合成项目,即可获得 appId 和服务密钥。
如需开通更多服务,可在管理控制台-总览页面开通其他服务。
接入流程
- 调用 Token 签发接口,使用 appId 和 secretKey 完成 auth 鉴权,获取 WebSocket Token。
- 使用返回的
wsUrl拼接token参数建立 WebSocket 连接。 - 建连成功后,客户端通过 WebSocket 发送合成请求 JSON。
- 服务端通过 WebSocket 返回
init、audio、done、error事件。
获取 WebSocket Token
请求 URL
https://tts.ilivedata.com/api/v1/speech/synthesis/ws-token
HTTP 请求头
| 请求头 | 值 | 描述 |
|---|---|---|
| X-AppId | 例:81900001 | 项目或应用的唯一标识符 |
| X-TimeStamp | 例:2024-07-01T07:59:59Z | 请求的 UTC 时间戳。需要把时间戳按 W3C 标准格式化 |
| Authorization | 例:Njl86M/jY6zZaZoGhZdGO+GI/8+yGFECusGH1yQHUFE= | 签名值 |
请求方法:GET
请求签名
当用户请求 Token 签发接口时,使用 appId 和 secretKey 对请求做签名。当 API 收到带签名信息的请求之后,将使用相同的算法验证签名。如果发现签名不一致,API 将会返回鉴权失败。
签名计算方法
签名计算规则请参考帮助中心的请求签名。Token 签发接口为 GET 请求,通常没有请求体,按 GET 无请求体场景计算签名。HTTPRequestURI 是请求 URI 的绝对路径,不包含请求串。
签名示例
GET
tts.ilivedata.com
/api/v1/speech/synthesis/ws-token
X-AppId:81900001
X-TimeStamp:2024-11-01T07:59:59Z
请求示例
curl -X GET 'https://tts.ilivedata.com/api/v1/speech/synthesis/ws-token' \
-H 'X-AppId: 81900001' \
-H 'X-TimeStamp: 2024-11-01T07:59:59Z' \
-H 'Authorization: {signature}'
响应示例
{
"token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 60,
"expiresAt": 1782359144,
"wsUrl": "wss://tts.ilivedata.com/api/v1/speech/synthesis/ws"
}
响应字段说明
| 字段名 | 类型 | 描述 |
|---|---|---|
| token | String | WebSocket JWT,签名算法为 RS256 |
| expiresIn | Number | Token 有效期,单位秒。Token 需要在有效期内用于建立 WebSocket 连接 |
| expiresAt | Number | Token 过期时间,Unix 秒 |
| wsUrl | String | TTS WebSocket 连接地址,不含 token 参数 |
建立 WebSocket 连接
WebSocket 连接地址
wss://tts.ilivedata.com/api/v1/speech/synthesis/ws?token={token}
Token 只用于 WebSocket 握手鉴权。连接建立成功后,当前连接不会因为 Token 到期自动断开;如果连接断开后需要重连,应重新获取 Token。
TTS 服务会校验 JWT 的签名、过期时间、aud、iss、scope、path 和 appId。请求消息中的 appId 必须与 Token 中的 appId 一致。
WebSocket 请求参数
建连成功后,客户端通过 WebSocket 文本消息发送请求体 JSON。
顶层参数
| 参数 | 是否必需 | 类型 | 描述 |
|---|---|---|---|
| appId | 条件必需 | Number | 与 request.appId 二选一;服务端优先取顶层 appId |
| sessionId | 可选 | String | 业务会话 ID;不传时同一 WebSocket 连接内复用连接级默认 sessionId |
| request | 必需 | Object | 合成请求体,结构与 SynthesisRequest 一致 |
request
| 参数 | 是否必需 | 类型 | 描述 |
|---|---|---|---|
| appId | 条件必需 | Number | 与顶层 appId 二选一 |
| text | 必需 | String | 合成文本,去除首尾空白后不能为空 |
| language | 可选 | String | 文本内容所属语种,推荐传入此语言参数;不传则使用自动语种检测结果。支持语种请参考语种列表 |
| voice | 可选 | VoiceSetting | 合成声音相关配置 |
| output | 可选 | OutputSetting | 输出音频相关配置 |
VoiceSetting
| 参数 | 必需 | 类型 | 描述 |
|---|---|---|---|
| name | 可选 | String | 预置音色库或音色注册的音色名称 |
| audio | 可选 | String | 未指定音色名称时,可以通过此参数指定的音频文件进行音色克隆 |
| emotion | 可选 | String | 情感表达 |
OutputSetting
| 参数 | 必需 | 类型 | 描述 |
|---|---|---|---|
| format | 可选 | String | 选择输出合成音频格式,候选为 pcm、wav、mp3、opus,默认为 wav |
请求体示例
{
"appId": 81900001,
"request": {
"appId": 81900001,
"text": "您好,这是一个 WebSocket 流式语音合成示例。",
"language": "zh-CN",
"voice": {
"name": "juvenile"
},
"output": {
"format": "mp3"
}
}
}
如果客户端需要自定义业务会话,可显式传入 sessionId:
{
"appId": 81900001,
"sessionId": "biz-session-001",
"request": {
"appId": 81900001,
"text": "同一个业务会话内的第一条消息。",
"voice": {
"name": "juvenile"
},
"output": {
"format": "mp3"
}
}
}
WebSocket 响应事件
init 事件
表示服务端已接受该任务,并返回任务标识信息。
| 字段名 | 类型 | 描述 |
|---|---|---|
| event | String | 固定为 init |
| taskId | String | 任务 ID,由服务端生成 |
| sessionId | String | 会话 ID;客户端未传时由服务端按连接生成 |
| status | String | 固定为 init |
| taskStatus | Number | 任务状态 |
{
"event": "init",
"taskId": "bj_ws_1b3d21549d3841d3b4400829403a4fff",
"sessionId": "bj_ws_5f45c8fa85814b159741c80620f705bf",
"status": "init",
"taskStatus": 1
}
audio 事件
表示一个音频分片。
| 字段名 | 类型 | 描述 |
|---|---|---|
| event | String | 固定为 audio |
| taskId | String | 任务 ID |
| sessionId | String | 会话 ID |
| seq | Number | 音频分片序号 |
| itemIndex | Number | 文本分片索引 |
| itemDone | Boolean | 当前 itemIndex 是否完成 |
| sampleRate | Number | 当前音频分片采样率 |
| durationMs | Number | 当前音频分片时长,单位毫秒 |
| audioBase64 | String | 音频二进制分片的 Base64 字符串 |
| status | String | 固定为 streaming |
{
"event": "audio",
"taskId": "bj_ws_1b3d21549d3841d3b4400829403a4fff",
"sessionId": "bj_ws_5f45c8fa85814b159741c80620f705bf",
"seq": 12,
"itemIndex": 0,
"itemDone": false,
"sampleRate": 22050,
"durationMs": 120,
"audioBase64": "...",
"status": "streaming"
}
done 事件
表示任务完成,服务端已上传完整音频文件。
| 字段名 | 类型 | 描述 |
|---|---|---|
| event | String | 固定为 done |
| taskId | String | 任务 ID |
| sessionId | String | 会话 ID |
| status | String | 固定为 done |
| url | String | 上传后的音频文件访问地址 |
{
"event": "done",
"taskId": "bj_ws_1b3d21549d3841d3b4400829403a4fff",
"sessionId": "bj_ws_5f45c8fa85814b159741c80620f705bf",
"status": "done",
"url": "https://xxx.cos.accelerate.myqcloud.com/tts/.../bj_ws_1b3d21549d3841d3b4400829403a4fff.mp3"
}
error 事件
表示任务失败。
| 字段名 | 类型 | 描述 |
|---|---|---|
| event | String | 固定为 error |
| taskId | String | 任务 ID,若请求未进入任务初始化阶段可能为空 |
| sessionId | String | 会话 ID,若请求未进入任务初始化阶段可能为空 |
| status | String | 固定为 error |
| errorCode | Number | 错误码 |
| errorMessage | String | 错误信息 |
{
"event": "error",
"taskId": "bj_ws_1b3d21549d3841d3b4400829403a4fff",
"sessionId": "bj_ws_5f45c8fa85814b159741c80620f705bf",
"status": "error",
"errorCode": 3003,
"errorMessage": "Invalid voice name."
}
taskId 与 sessionId 规则
- 客户端不需要传
taskId。服务端会为每条消息生成新的唯一taskId,并在init、audio、done、error事件中返回。 - 如果客户端传入
taskId,服务端会忽略该字段,仍然使用服务端生成的taskId。 - 客户端不传
sessionId时,服务端会在 WebSocket 建连时生成一个连接级默认sessionId;同一连接内多条消息会返回相同sessionId。 - 客户端显式传入
sessionId时,服务端优先使用客户端传入的sessionId。
断线处理说明
- WebSocket 断开后,客户端需要重新建立连接并重新发送合成请求。
- 服务端不会使用客户端传入的
taskId做任务级恢复。 - 如果业务需要关联断线前后的请求,可由客户端传入同一个
sessionId作为业务会话标识。
客户端处理建议
- Token 有有效期,建议获取后立即建立 WebSocket 连接。
- 收到
init后可记录服务端返回的taskId和sessionId,用于日志排查和业务侧事件归并。 audioBase64需要 Base64 解码后再播放或缓存。- 以
done事件为准获取最终文件 URL。 - 若连接断开,需要重新建立 WebSocket 连接并重新发送请求;新的请求会生成新的
taskId。