流式文本语音合成

最近更新时间:2024-12-04 14:44:20

我的收藏
说明
此接口为 API 2.0 版本,在参数风格、错误码等方面有区别于 API 3.0 版本,请知悉。
本接口服务采用 websocket 协议,将请求文本合成为音频,同步返回合成音频数据及相关文本信息,达到“边合成边播放”的效果。区别于实时语音合成,本接口支持流式文本输入,适用于大语言模型的逐字输入场景,极大地提升了交互体验。

在使用该接口前,需要 开通语音合成服务,并进入 API 密钥管理页面 新建密钥,生成 AppID、SecretID 和 SecretKey,用于 API 调用时生成签名,签名将用来进行接口鉴权。

接口要求

集成实时语音合成 API 时,需按照以下要求。
内容
说明
音色种类
支持中文、英文音色,音色 ID 详见 音色列表页。可通过接口参数 VoiceType 设置对应音色 ID
支持场景
通用、客服、情感、阅读、新闻等,详见 音色列表页
音频属性
采样率:8000Hz、16000Hz、24000Hz(部分支持,详见音色列表页)
采样精度:16bits
声道:单声道(mono)
音频格式
pcm、mp3
请求协议
wss 协议
请求地址
wss://tts.cloud.tencent.com/stream_wsv2?{请求参数}
接口鉴权
签名鉴权机制,详见 签名生成
响应格式
音频信息通过 binary 类型帧,返回原始二进制数据,可以边接收边播放;
文本信息通过 text 类型帧,返回 JSON 格式数据(如状态码、时间戳、服务器事件等)
并发限制
默认单账号限制并发
精品音色和标准音色:20路(与实时语音合成接口共用);
大模型音色:10路(与实时语音合成接口共用);
超自然大模型音色:5路(与实时语音合成接口共用);
一句话复刻音色:5路(与实时语音合成接口共用);
如您有提高并发限制的需求,请联系商务经理咨询或 购买并发
调用限制
1. 同一个流式会话中,总合成字数不超过 10000字
2. 输入流可持续发送合成文本,若超过 10分钟 没有文本发送,服务端将把已缓存文本正常合成完毕后关闭连接
3. 仅支持在输入流开启前,设置语速、音量、情感等参数
文本限制
1. 流式合成文本 不支持 SSML标记
2. 服务侧收到流式合成文本后缓存,并按照句子分割后合成,分割标点包括全角符号 。 ; ? ! 半角符号 ; ? ! 与换行符
3. 文本合成依赖句子的完整性,确保合成文本包含正确标点(尤其是文本末尾标点),否则文本可能长时间缓存而未合成

接口调用流程

接口调用流程分为三个阶段:签名握手阶段、合成阶段和结束阶段。三个阶段后台均会返回文本消息 text message(包括合成文本时间戳、服务器事件等),内容为 json 序列化字符串,以下是格式说明:
字段名
类型
描述
code
Integer
状态码,0代表正常,非0值表示发生错误
message
String
错误说明,发生错误时显示这个错误发生的具体原因,随着业务发展或体验优化,此文本可能会经常保持变更或更新
session_id
String
本次会话唯一 id,由客户端在握手阶段生成并赋值在调用参数中
request_id
String
本次会话唯一 id,由服务端自动生成,并随文本消息返回
message_id
String
本 message 唯一 id
result
Result
语音合成文本时间戳
ready
Integer
READY 事件:该字段返回1时表示服务端已初始化,客户端可以开始发送文本合成请求
final
Integer
FINAL 事件:该字段返回1时表示文本全部合成结束,客户端收到后需主动关闭 websocket 连接
heartbeat
Integer
HEARTBEAT 事件:该字段返回1时表示心跳报文,客户端收到后可忽略
其中合成结果 Result 结构体格式为:
字段名
类型
描述
subtitles
Subtitle Array
当前一段话的词列表,Subtitle 结构体格式为:
Text: String 类型,该字的内容。
BeginTime: Integer 类型,该字在整个音频流中的起始时间。
EndTime: Integer 类型,该字在整个音频流中的结束时间。
BeginIndex: Integer 类型,该字在整个文本中的开始位置,从0开始。
EndIndex: Integer 类型,该字在整个文本中的结束位置,从0开始。
Phoneme: String 类型,该字的音素(注意:此字段可能返回 null,表示取不到有效值)。

握手阶段

请求格式

握手阶段,客户端主动发起 websocket 连接请求,请求 URL 格式为:
wss://tts.cloud.tencent.com/stream_wsv2?{请求参数}
其中<appid>需替换为腾讯云注册账号的 AppID,可通过 API 密钥管理页面 获取,{请求参数}格式为:
key1=value2&key2=value2...(key 和 value 都需要进行 urlencode)
参数说明:
参数名称
必填
类型
描述
Action
String
调用接口名,取值为:TextToStreamAudioWSv2(注意大小写)
AppId
Integer
账号 AppId(请确保该字段数据类型为整型 int)
SecretId
String
腾讯云注册账号的密钥 SecretId,可通过 API 密钥管理页面 获取
Timestamp
Integer
当前 UNIX 时间戳,可记录发起 API 请求的时间。例如1529223702,如果与当前时间相差过大,会引起签名过期错误
Expired
Integer
签名的有效期,是一个符合 UNIX Epoch 时间戳规范的数值,单位为秒;Expired 必须大于 Timestamp 且 Expired-Timestamp 小于90天
SessionId
String
语音合成全局唯一标识,一个 websocket 连接对应一个,用户自己生成(推荐使用 uuid),最长128位。
VoiceType
Integer
音色 ID,支持中文、英文音色
包括标准音色与精品音色,精品音色拟真度更高,价格不同于标准音色,请参见 购买指南。完整的音色 ID 列表请参见 音色列表
若使用一句话版声音复刻,请填入固定值“200000000”。
FastVoiceType
String
一句话版声音复刻音色ID,使用一句话版声音复刻音色时需填写。
Volume
Float
音量大小,范围[-10,10],对应音量大小。
默认为0,代表正常音量,值越大音量越高。
Speed
Float
语速,范围:[-2,6],分别对应不同语速:
-2: 代表0.6倍
-1: 代表0.8倍
0: 代表1.0倍(默认)
1: 代表1.2倍
2: 代表1.5倍
6: 代表2.5倍
如果需要更细化的语速,可以保留小数点后 2 位,例如0.5/1.25/2.81等。
参数值与实际语速转换,可参考 代码示例
SampleRate
Integer
音频采样率:
24000:24k(部分音色支持,请参见 音色列表
16000:16k(默认)
8000:8k
Codec
String
返回音频格式:
pcm: 返回二进制 pcm 音频(默认)
mp3: 返回二进制 mp3 音频
EnableSubtitle
Boolean
是否开启时间戳功能,默认为false。
EmotionCategory
String
控制合成音频的情感,仅支持多情感音色使用。取值: neutral(中性)、sad(悲伤)、happy(高兴)、angry(生气)、fear(恐惧)、news(新闻)、story(故事)、radio(广播)、poetry(诗歌)、call(客服)、sajiao(撒娇)、disgusted(厌恶)、amaze(震惊)、peaceful(平静)、exciting(兴奋)、aojiao(傲娇)、jieshuo(解说)
示例值:neutral
EmotionIntensity
Integer
控制合成音频情感程度,取值范围为 [50,200],默认为 100;只有 EmotionCategory 不为空时生效。
SegmentRate
Integer
断句敏感阈值,取值范围:[0,1,2],默认值:0
该值越大越不容易断句,模型会更倾向于仅按照标点符号断句。此参数建议不要随意调整,可能会影响合成效果
Signature
String
接口签名参数

一、签名阶段

Signature 签名生成
1. 对除 Signature 之外的所有参数按字典序进行排序,拼接后得到请求参数为:
Action=TextToStreamAudioWSv2&AppId=130046****&Codec=pcm&EnableSubtitle=True&Expired=1688697305&SampleRate=16000&SecretId=*****XcaKs2w4vZw5zTCrHRM7dOwre9*****&SessionId=b78ae3ba-1ba5-11ee-a106-768645a5c72a&Speed=0&Timestamp=1688610905&VoiceType=101001&Volume=0
再拼接请求方法、域名地址,得到签名原文(注意大小写)。签名原文格式为:
请求方法(GET) + 域名地址(tts.cloud.tencent.com/stream_wsv2) + 请求参数(?Action=TextToStreamAudioWSv2&其他参数...)
最终,得到的签名原文为:
GETtts.cloud.tencent.com/stream_wsv2?Action=TextToStreamAudioWSv2&AppId=130046****&Codec=pcm&EnableSubtitle=True&Expired=1688697305&SampleRate=16000&SecretId=*****XcaKs2w4vZw5zTCrHRM7dOwre9*****&SessionId=b78ae3ba-1ba5-11ee-a106-768645a5c72a&Speed=0&Timestamp=1688610905&VoiceType=101001&Volume=0
2. 对签名原文使用 SecretKey 进行 HmacSha1 加密,之后再进行 base64 编码。例如对上一步的签名原文, SecretKey=*****SkqpeHgqmSz*****,使用 HmacSha1 算法进行加密并做 base64 编码处理:
Base64Encode(HmacSha1("GETtts.cloud.tencent.com/stream_wsv2?Action=TextToStreamAudioWSv2&AppId=130046****&Codec=pcm&EnableSubtitle=True&Expired=1688697305&SampleRate=16000&SecretId=*****XcaKs2w4vZw5zTCrHRM7dOwre9*****&SessionId=b78ae3ba-1ba5-11ee-a106-768645a5c72a&Speed=0&Timestamp=1688610905&VoiceType=101001&Volume=0", "*****SkqpeHgqmSz*****"))
得到 Signature 签名值为:
4Lv+k6y6v5VRT/iBFPU+Gyfeiy0=
3. 将 Signature 值进行 urlencode(必须进行 URL 编码,否则将导致鉴权失败偶现 )后拼接得到 URL 为:
wss://tts.cloud.tencent.com/stream_wsv2?Action=TextToStreamAudioWSv2&AppId=130046****&Codec=pcm&EnableSubtitle=True&Expired=1688697305&SampleRate=16000&SecretId=*****XcaKs2w4vZw5zTCrHRM7dOwre9*****&SessionId=b78ae3ba-1ba5-11ee-a106-768645a5c72a&Speed=0&Timestamp=1688610905&VoiceType=101001&Volume=0&Signature=4Lv%2Bk6y6v5VRT/iBFPU%2BGyfeiy0%3D

请求响应

客户端发起连接请求后,后台建立连接并进行签名校验,校验成功则返回 code 值为 0 的确认消息表示握手成功;如果校验失败,后台返回 code 为非 0 值的消息并断开连接。
{"code":0,"message":"success","session_id":"e042008c-1019-11ee-8b49-6c92bf65e6fe","request_id":"b028dfe6-d7af-4d25-b61d-dcae685aa81f","message_id":"f81c0771-5606-478e-9560-555a5717ea25","final":0,"result":{"subtitles":null}}

二、合成阶段

2.1 接收 READY 事件

握手成功之后,等待服务端发送 READY 事件(ready=1),即可进入合成阶段。客户端根据需要发送合成文本,服务端缓存文本,并根据标点符号判断,确定接收到完整句子后,调用合成引擎。
{"code":0,"message":"success","session_id":"da916680-31f8-11ef-997c-52540037edd7","request_id":"1bc1bab3-170d-4443-8685-238ce6bb6420","message_id":"b211e1d5-a742-4f65-8a11-af1f0757383e","final":0,"ready":1,"heartbeat":0,"result":{"subtitles":null}}

2.2 发送合成指令与合成文本

客户端根据需要发送合成指令(ACTION_SYNTHESIS)与合成文本,服务端缓存文本,并根据标点符号判断,确定接收到完整句子后,调用合成引擎。
{"session_id": "381665d8-31f6-11ef-894a-52540037edd7", "message_id": "3b46df26-31f6-11ef-894a-52540037edd7", "action": "ACTION_SYNTHESIS", "data": "\u5355\u662f\u5468\u56f4\u77ed\u77ed\u7684\u6ce5\u5899\u6839\u4e00\u5e26\uff0c\u5c31\u6709\u65e0\u9650\u8da3\u5473\u3002"}

2.3 接收合成结果

合成结果:客户端需要同步接收后台返回的二进制音频数据与文本数据。文本数据示例如下:
{"code":0,"message":"success","session_id":"659f1260-101a-11ee-959d-6c92bf65e6fe","request_id":"20ebf801-53ee-4a58-96ab-c63e0f16044a","message_id":"8d4a2f2b-3b15-445c-933b-74b6b44cd882","final":0,"result":{"subtitles":[{"Text":"欢","BeginTime":250,"EndTime":570,"BeginIndex":0,"EndIndex":1,"Phoneme":"huan1"},{"Text":"迎","BeginTime":570,"EndTime":770,"BeginIndex":1,"EndIndex":2,"Phoneme":"ying2"},{"Text":"使","BeginTime":770,"EndTime":1020,"BeginIndex":2,"EndIndex":3,"Phoneme":"shi3"},{"Text":"用","BeginTime":1020,"EndTime":1270,"BeginIndex":3,"EndIndex":4,"Phoneme":"yong4"}]}}
返回错误:合成过程中如果出现错误,后台返回 code 为非 0 值的消息并断开连接。
{"code":10001,"message":"参数不合法(Please check your parameter VoiceType)","session_id":"b6b10dc0-101a-11ee-9e72-6c92bf65e6fe","request_id":"a2edbe4f-c12f-48e6-8810-fda7a0992f79","message_id":"da63be2f-d44e-4f3b-a2d7-0b19a3748d23","final":0,"result":{"subtitles":null}}
心跳消息:合成过程中,服务端会定时发送 HEARTBEAT 事件(heartbeat=1),用于保持长连接,客户端收到后不用处理
{"code":0,"message":"success","session_id":"da916680-31f8-11ef-997c-52540037edd7","request_id":"1bc1bab3-170d-4443-8685-238ce6bb6420","message_id":"a985e1d5-a742-4f65-8a11-af1f07574237","final":0,"ready":0,"heartbeat":1,"result":{"subtitles":null}}

三、结束阶段

3.1 发送结束指令

全部文本发送完后,发送 结束指令(ACTION_COMPLETE),通知服务器所有文本已发送完成。
{"session_id": "da916680-31f8-11ef-997c-52540037edd7", "message_id": "de674bee-31f8-11ef-997c-52540037edd7", "action": "ACTION_COMPLETE", "data": ""}

3.2 接收 FINAL 事件

服务器:合成完所有请求文本之后,最终返回 FINAL 事件(final=1)
客户端:收到合成完成消息后,需主动关闭 websocket 连接
合成完成消息示例
{"code":0,"message":"success","session_id":"dbb8417e-101a-11ee-840e-6c92bf65e6fe","request_id":"99207183-3bda-42de-a1f4-6d8838122ad3","message_id":"d56a3fed-0dd6-4dc6-b434-416ae1b69f0f","final":1,"ready":0,"heartbeat":0,"result":{"subtitles":null}}

3.3 关闭 websocket 连接

客户端收到 FINAL 事件后,关闭 websocket 连接,实时合成结束。

四、调用流程示意图





五、指令、事件与格式

5.1 客户端指令

客户端根据场景需要,发送指令到服务端。
指令类型
指令
名称
data
描述
ACTION_SYNTHESIS
合成文本指令
合成文本
客户端收到 READY 事件后,可持续调用该指令发送合成文本。
两次合成指令发送间隔不超过 10 分钟
若发送超时,服务端将返回超时报错(错误码 10009,仅做通知,可忽略),并在将缓存文本正常合成完毕后通知客户端关闭连接。
ACTION_COMPLETE
合成结束指令
空字符串
客户端发送完所有文本后,发送该指令通知服务端文本发送完成。
ACTION_RESET
清空缓存指令
空字符串
合成服务接受客户端发送文本,缓存后并逐批进行合成。
服务侧接收到 RESET 指令后,将清空缓存中仍未合成的文本。
注:接收指令时,如有文本已经在合成过程中,该部分文本不会被影响。
指令格式
{
"session_id": "dbb8417e-101a-11ee-840e-6c92bf65e6fe", // 会话唯一id,客户端建立连接时传入
"message_id": "3b46df26-31f6-11ef-894a-52540037edd7", // 本次消息唯一id
"action": "ACTION_SYNTHESIS", // 指令类型
"data": "" // 指令数据
}

5.2 服务端事件

服务端将合成文本结果(如时间戳)、错误消息、服务器事件,通过文本消息方式返回客户端。
事件类型
final, ready, heartbeat 等,详情参见上面返回参数列表(该字段未来可能会扩展更多类型)
事件格式
{
"code": 0, // 错误码
"message": "success", // 错误信息
"session_id": "dbb8417e-101a-11ee-840e-6c92bf65e6fe", // 会话唯一id,客户端建立连接时传入
"request_id": "99207183-3bda-42de-a1f4-6d8838122ad3", // 会话唯一id,服务器生成,随消息返回
"message_id": "d56a3fed-0dd6-4dc6-b434-416ae1b69f0f", // 本次消息唯一id
"final": 1, // 事件类型
"ready": 0,
"heartbeat": 0,
"result": { // 服务器事件,该字段可忽略
"subtitles": null
}
}

开发者资源

SDK

SDK 调用示例

错误码

客户端错误

数值
说明
10001
参数不合法,具体详情参考 message 字段
10002
账号当前调用并发超限
10003
鉴权失败
10004
客户端数据上传超时
10005
客户端连接断开
10006
流式输入文本包含SSML
10007
流式输入文本超过最大长度限制
10008
流式输入文本通道已关闭
10009
流式输入文本超时未发送,服务端合成完毕后将正常关闭连接

服务端错误

数值
说明
20000
后台错误
20001
后台服务处理失败
20002
后台引擎合成失败
20003
后台引擎合成超时