SDK 下载链接
快速开始
// 1. 配置初始化参数VirtualHumanTtsParam param = new VirtualHumanTtsParam();param.appKey = "your_app_key";param.accessToken = "your_access_token";// virtualmanProjectId 与 assetVirtualmanKey 二选一必填,同时填写时 assetVirtualmanKey 优先param.virtualmanProjectId = "your_project_id";// param.assetVirtualmanKey = "your_asset_key";// 2. 初始化 SDK(建议在 Application.onCreate 中调用)VirtualHumanTts sdk = VirtualHumanTts.getInstance();sdk.init(getApplicationContext(), param);// 3. 注册回调sdk.setDataCallback(result -> {if ("SPEECH".equals(result.driverRspType)) {byte[] pcm = result.speechRsp.audio; // 播放音频}});sdk.setErrorCallback((code, msg) -> {Log.e("TTS", code + ": " + msg);});sdk.setEventCallback((code, msg) -> {if (code == VirtualHumanTts.EVENT_OPEN) {// 连接建立,可以开始发送}});// 4. (可选)设置本次请求的语音合成参数TtsSpeechParam sp = new TtsSpeechParam();sp.timbreKey = "zh_female_xxx";sp.setSpeed(1.0f);sdk.setSpeechParam(sp);// 5. 发送文本(三种驱动方式任选其一)String reqId = TtsUtils.uuid();// 方式一:流式文本驱动(send* 方法须在 EVENT_OPEN 之后调用)sdk.sendStreamText(reqId, 1, false, "你好,");sdk.sendStreamText(reqId, 2, true, "我是数智人。"); // isFinal=true 结束// 方式二:普通文本驱动sdk.sendText(reqId, "你好,我是数智人。");// 方式三:对话驱动sdk.sendChat(reqId, null, "今天天气怎么样?");// 6. 打断当前请求sdk.stop();// 7. Activity/Fragment 销毁时释放资源sdk.uninit();
VirtualHumanTts
SDK 主入口,单例。包路径:
com.tencent.virtualhuman_tts.VirtualHumanTtsgetInstance()
public static VirtualHumanTts getInstance()
获取单例实例。
init()
public synchronized void init(@NonNull Context context, VirtualHumanTtsParam param)
初始化 SDK,建立 WebSocket 连接。可重复调用,重新 init 会关闭旧连接并重置所有状态。
注意:
init() 内部建连是异步的,
send* 系列方法必须在收到 EVENT_OPEN 事件之后才能调用,否则会立即回调 ERROR_SOCKET。参数 | 说明 |
context | 必须传入 getApplicationContext(),用于网络状态监听和本地化消息文本 |
param |
若当前网络不可用,会立即通过
onError 回调 ERROR_NETWORK_UNAVAILABLE。
uninit()
public synchronized void uninit()
反初始化 SDK,释放所有资源。调用后 SDK 不可用,如需继续使用必须重新调用
init()。断开 WebSocket 连接
注销网络状态监听
取消所有待执行的重连任务
建议在 Activity / Fragment 销毁时调用。
reconnect()
public synchronized void reconnect()
手动触发单次重连。适用于
VirtualHumanTtsParam.autoReconnect 为 false 时,在 WebSocket 断开后主动发起重连。若当前 WebSocket 已连接,直接返回(no-op)
若当前网络不可用,通过
onError 回调 ERROR_NETWORK_UNAVAILABLE本接口不含重试逻辑,连接结果通过
EVENT_OPEN / ERROR_SOCKET 回调通知
setSpeechParam()
public void setSpeechParam(TtsSpeechParam speechParam)
设置本次请求的语音合成参数。每次新请求前调用一次即可,后续所有
send* 调用均会自动携带该参数。传 null 可清除参数,恢复使用项目默认配置。参数 | 说明 |
speechParam |
setDataCallback()
public void setDataCallback(OnResultListener listener)
注册数据回调。SDK 收到服务端下行消息时触发,回调在子线程执行,UI 操作请切换到主线程。可在
init() 前后任意时机注册;传 null 可注销回调。public interface OnResultListener {void onResult(TtsResult result);}
setErrorCallback()
public void setErrorCallback(OnErrorListener listener)
注册错误回调。回调在子线程执行。可在
init() 前后任意时机注册;传 null 可注销回调。public interface OnErrorListener {void onError(int code, String message);}
setEventCallback()
public void setEventCallback(OnEventListener listener)
注册统一事件回调,涵盖连接状态与音频生命周期,所有事件 code 均为 10xxx。回调在子线程执行。可在
init() 前后任意时机注册;传 null 可注销回调。public interface OnEventListener {void onEvent(int code, String message);}
sendStreamText()
流式文本驱动(STREAM_TEXT)。将一段文本拆分为多片依次发送,适合 LLM 流式输出场景。
public void sendStreamText(String reqId, int seq, boolean isFinal, String text)
参数 | 类型 | 说明 |
reqId | String | 本次请求唯一 ID,同一次请求所有分片保持相同,可用 TtsUtils.uuid() 生成 |
seq | int | 分片序号,从 1 开始递增 |
isFinal | boolean | 是否为最后一片,最后一片必须传 true |
text | String | 本片文本内容;最后一片可传空字符串 |
示例:
TtsSpeechParam sp = new TtsSpeechParam();sp.timbreKey = "zh_female_xxx";sp.setSpeed(1.2f);sdk.setSpeechParam(sp);String reqId = TtsUtils.uuid();sdk.sendStreamText(reqId, 1, false, "你好,");sdk.sendStreamText(reqId, 2, false, "我是数智人。");sdk.sendStreamText(reqId, 3, true, "");
sendText()
普通文本驱动(TEXT)。一次性发送完整文本,无需分片。
public void sendText(String reqId, String text)
参数 | 类型 | 说明 |
reqId | String | 本次请求唯一 ID |
text | String | 完整文本 |
示例:
sdk.setSpeechParam(null); // 使用项目默认配置sdk.sendText(TtsUtils.uuid(), "你好,我是数智人。");
sendChat()
对话驱动(CHAT)。接入大模型对话能力,支持多轮对话。
public void sendChat(String reqId, String streamId, String text)
参数 | 类型 | 说明 |
reqId | String | 本次请求唯一 ID |
streamId | String | 会话 ID;多轮对话保持同一 streamId,传 null 沿用当前会话 |
text | String | 用户输入文本 |
注意:
CHAT 驱动会同时触发
REPLY 类型和 SPEECH 类型的回调。REPLY 包含大模型回复文本,SPEECH 包含音频和口型数据。示例:
String sessionId = TtsUtils.uuid(); // 多轮对话中保持不变sdk.sendChat(TtsUtils.uuid(), sessionId, "今天天气怎么样?");sdk.sendChat(TtsUtils.uuid(), sessionId, "那明天呢?"); // 同一会话继续
stop()
public void stop()
打断当前请求。CHAT / TEXT / STREAM_TEXT 驱动均支持。向服务端发送
STOP_CHAT 指令,等待服务端回包中的 isFinal=true 结束本次请求。
VirtualHumanTtsParam
SDK 初始化参数。包路径:
com.tencent.virtualhuman_tts.VirtualHumanTtsParam字段 | 类型 | 默认值 | 说明 |
appKey | String | "" | APaaS AppKey(必填) |
accessToken | String | "" | APaaS AccessToken(必填) |
virtualmanProjectId | String | "" | 数智人项目 ID,与 assetVirtualmanKey 二选一必填 |
assetVirtualmanKey | String | "" | 形象资产 ID,与 virtualmanProjectId 二选一必填;两者同时填写时优先使用此字段 |
serverDomain | String | "gw.tvs.qq.com" | WebSocket 服务域名 |
disableTls | boolean | false | true 使用 ws://,false 使用 wss:// |
enableSubtitle | boolean | false | 是否开启字幕与音频对齐模式,见下方说明 |
autoReconnect | boolean | false | 是否开启自动重连,见下方说明 |
enableSubtitle 说明:值 | 行为 |
false(默认) | 直接透传原始数据, SpeechRsp.subtitleList、ThFeat、Action、Expression 等全量字段均正常返回 |
true | SDK 以子句为单位将字幕与 PCM 音频对齐后输出,整句文本填入 SpeechRsp.subtitle,对应音频同包返回;适合不自行处理口型数据、只需要文字字幕的场景 |
autoReconnect 说明:值 | 行为 |
false(默认) | |
true | 因网络异常或服务端正常关闭断开后,自动以 1 秒间隔最多重试 10 次;网络断开期间暂停重试,网络恢复后重置重试次数重新开始;业务错误(服务端返回错误码)不触发自动重连 |
TtsSpeechParam
所有字段默认
null,null 表示使用数智人项目配置的默认值。字段 | 类型 | 说明 | 约束 |
timbreKey | String | 音色值,通过「分页查询音色列表」接口获取 | — |
speed | Float | 语速(通过 getSpeed() / setSpeed() 访问) | [0.5, 2.0],1.0 为正常语速,越界或 null 使用项目默认 |
volume | Integer | 音量 | [-10, 10],0 为正常音量 |
emotionCategory | String | 情感分类,仅多情感音色生效 | 可选值参考音色列表接口 |
emotionIntensity | Integer | 情感强度, emotionCategory 不为空时生效 | [50, 200] |
smartActionEnabled | Boolean | 是否开启智能动作 | — |
subtitleType | Integer | 字幕返回模式: 0 按字(默认),1 按词 | — |
timbreLanguage | String | 音色语种,多语种音色合成时必填 | — |
注意:
SDK 内部固定使用 OPUS 音频格式并自动解压,
SpeechRsp.audio 始终为 PCM 数据,无需关心音频格式。示例:
TtsSpeechParam sp = new TtsSpeechParam();sp.timbreKey = "zh_female_xxx";sp.setSpeed(1.2f);sp.volume = 2;sp.emotionCategory = "happy";sp.emotionIntensity = 150;sp.smartActionEnabled = true;sdk.setSpeechParam(sp);
TtsResult
SDK 回调数据模型。包路径:
com.tencent.virtualhuman_tts.TtsResult顶层字段
字段 | 类型 | 说明 |
reqId | String | 与发送时传入的 reqId 一致 |
streamId | String | 会话 ID |
driverRspType | String | 响应类型: "REPLY" 或 "SPEECH" |
replyRsp | ReplyRsp | driverRspType == "REPLY" 时有效 |
speechRsp | SpeechRsp | driverRspType == "SPEECH" 时有效 |
ReplyRsp
大模型对话回复信息(仅 CHAT 驱动触发)。
字段 | 类型 | 说明 |
replyType | String | 回复语类型: cloudAiGpt / yunxiaowei / cloudAiWaiting / cloudAiTimeOut / sensitive / input / enhanceText / cloudAiThought |
replyPro | String | 播报内容(含 SSML 标签) |
replyDisplay | String | 展示内容(含富文本标签) |
interactionType | String | 交互类型 |
interactionContent | String | 交互内容 |
uninterrupt | boolean | true 表示当前播报不可打断 |
muted | boolean | true 表示当前播报关闭收音 |
seqNo | int | 子句序号 |
contentType | int | 内容类型: 0 未知,1 普通字符串,2 有序列表,3 无序列表,4 图片链接,5 HTTP 链接,6 表格,8 标题,9 SSML |
ttsSupport | boolean | 当前子句是否播报 |
isFinal | boolean | 是否为最后一句 |
isHighLight | boolean | 是否需要高亮展示 |
SpeechRsp
音频、口型、字幕等端渲染数据。
音频
字段 | 类型 | 说明 |
audio | byte[] | PCM 音频数据(16-bit 小端),无音频时为空数组;SDK 内部自动解压 OPUS,此字段始终为 PCM |
sampling | int | 采样率(Hz),如 16000 |
seqNo | int | 子句序号 |
isFinal | boolean | 整句结束标识, true 时本次请求完全结束 |
sentenceFinal | boolean | 流式子句结束标识 |
sentenceStart | boolean | 子句开始标识 |
字幕
字段 | 类型 | 说明 |
subtitleList | List\\<SubtitleInfo\\> | 字幕列表( enableSubtitle=false 时使用) |
subtitle | String | 对齐后的字幕文字( enableSubtitle=true 时由 SDK 填充) |
其他
字段 | 类型 | 说明 |
phn | List\\<PhnInfo\\> | 音素信息列表 |
word | List\\<WordInfo\\> | 分词信息列表 |
action | List\\<ActionInfo\\> | 动作信息列表 |
expression | List\\<ExpressionInfo\\> | 表情信息列表 |
子结构
说明:
所有时间字段单位为 0.1 微秒,除以 10000 换算为毫秒。
PhnInfo — 音素
字段 | 类型 | 说明 |
phn | String | 音素,如 "z4" |
start | String | 起始时间(0.1µs) |
end | String | 结束时间(0.1µs) |
WordInfo — 分词
字段 | 类型 | 说明 |
phn | String | 音素字符串 |
word | String | 对应单词/汉字 |
ActionInfo — 动作
字段 | 类型 | 说明 |
pos | String | 动作名称 |
start | String | 起始时间(0.1µs) |
SubtitleInfo — 字幕
字段 | 类型 | 说明 |
word | String | 单字/词 |
start | String | 起始时间(0.1µs) |
end | String | 结束时间(0.1µs) |
posStart | String | 在文本中的起始 Unicode 位置(左闭右开) |
posEnd | String | 在文本中的结束 Unicode 位置(左闭右开) |
ExpressionInfo — 表情
字段 | 类型 | 说明 |
name | String | 表情名称 |
start | String | 起始时间(0.1µs) |
end | String | 结束时间(0.1µs) |
loc | String | 对应文本的 Unicode 位置 |
flag | String | 位置标记: B 起始,I 中间,E 结束,S 单字完整表情 |
事件码
常量 | 值 | message 格式 | 说明 |
EVENT_OPEN | 10001 | 描述文本 | WebSocket 连接建立 |
EVENT_CLOSE | 10002 | 描述文本 | WebSocket 连接断开 |
AUDIO_EVENT_START | 10003 | reqId | 整段音频开始(首个子句开始时触发) |
AUDIO_EVENT_END | 10004 | reqId | 整段音频结束(isFinal=true 时触发) |
AUDIO_EVENT_SENTENCE_START | 10005 | "reqId#seq=N" | 子句开始(仅 enableSubtitle=false 时触发) |
AUDIO_EVENT_SENTENCE_END | 10006 | "reqId#seq=N" | 子句结束(仅 enableSubtitle=false 时触发) |
EVENT_RECONNECTING | 10007 | "attempt=N/10" | 正在自动重连,N 为当前第几次重试;重连成功后会收到 EVENT_OPEN |
错误码
常量 | 值 | 说明 |
ERROR_UNKNOWN | 20000 | 未知错误 |
ERROR_SOCKET | 20001 | WebSocket / 网络异常,或服务端返回业务错误 |
ERROR_SEQ_NO | 20002 | 流式文本第一片 seq 不为 1 |
ERROR_STREAM_NOT_FINISHED | 20003 | 上一次请求尚未结束,不允许并发发送 |
ERROR_NETWORK_UNAVAILABLE | 20004 | 网络不可用(init / reconnect 时网络未连通) |
ERROR_RECONNECT_FAILED | 20005 | 自动重连耗尽所有重试次数仍未成功 |