端渲染 Windows SDK 控制协议文档

最近更新时间:2025-06-03 10:40:22

我的收藏

1. 控制协议说明

腾讯端渲染 Windows SDK 包含了多个独立的工具程序,有 ASR 语音识别,浮层播放器,浮层网页等部分,集成商也可以在此基础上自行开发应用程序,集成数智人的功能。

1.1 连接方式

多个应用程序之间,通过 UDP 协议进行通讯。通讯方式为星型方式通讯,每个应用均与主控连接。主控负责统计各应用的状态,和中转和分发指令。

发送给主控的命令, 除了心跳命令,其他的都会被转发到其他活跃的应用,类似于广播。





1.2 连接端口

主控启动后,会监听 2个 UDP 端口 54200 和 54300。

54300 端口为 UDP 直接通讯端口,命令字直接通过 UDP 数据包进行发送。 命令格式支持 Json 和 Protobuf 二进制数据。

54200 端口为 KCP over UDP 通讯端口,由于 UDP 为不可靠连接,在通讯过程中可能会丢包,所以引入了 KCP 协议,KCP 协议工作在 UDP 协议上层, 实现了包确认机制和流量控制,保证通讯过程中不丢包。命令格式支持 Json 和 Protobuf 二进制数据。

详细资料可访问: Github 链接

两个端口发送的数据是一样的, 在实现时二选一即可。

一般局域网内应用,采用 UDP 协议已经可以满足日常需求。集成商可根据项目需求和研发周期自行评估使用。

2. 命令通用格式

发送和接收的命令报文数据,支持 Json 和 Protobuf 二进制两种。

主控会自动检测命令的格式,主控回复的命令报文格式和最后一次心跳包使用的报文格式相同。

其中 Json 字符串需要经过 utf8 编码,所有变量为小驼峰形式,符合 proto3 json 的标准,详情请参见标准说明

协议数据包的通用结构示例如下:
{
"traceId":"8b0fa692a958407c84bed9a0ab52777c",
"sessionId":"622598dbbe8c4c5eaad2c3856c818d87",
"senderRole": "UnrealEngine",
"senderId": "unreal_engine_01",
"speakCommand":{
"actorName":"xiaowei",
"text":"你好呀"
}
}
其中第一层的参数结构如下:
参数名称
必选
类型
描述
traceId
String
追踪单个命令的 ID,必须保证每次调用,都传入不同的字符串,不能传空, 长度必须为32位
sessionId
String
追踪整个 Session 的 ID,可以每次调用传入相同的字符串,不能传空, 长度必须为32位。
senderRole
String
发送者角色,可以区分是那个角色的应用发出来的命令
senderId
String
发送者 ID, 可以区分是哪个发送者发出来的命令
speakCommand
Object
具体的命令参数,后面会详细介绍每个命令
为了书写简洁,后面的命令会省略 traceID 和 sessionID 字段,在正式使用的时候需要填写的。

3. 心跳和状态报告

UDP 协议是无连接的,主控通过心跳判断对方是否存活。每个应用均需要发送心跳给主控, 主控会定时返回状态报告,告知主控存活,并告知所有连接的节点状态。

3.1 心跳

所有连接主控的节点,都需要每隔1秒给主控发送一次心跳。 超过3秒未发送心跳,主控认为该连接节点下线。 可以通过 -CleanClientDuration=XX 来设置心跳检测的时间。设置为 -1 可以禁止节点下线。

心跳格式为:
{
"heartbeat":{
"extendedInfoJson": "{}"
}
}
参数结构如下:
参数名称
必选
类型
描述
extendedInfoJson
String
节点的额外信息,信息会被主控存储并附加在状态报告中发送给其他节点。
主控收到心跳后,会认为该节点为活跃状态,其他节点发送的命令会被转发给活跃的节点。

3.2 过滤器

因为通讯方式类似广播,我们会收到所有节点发送的信息, 但有时我们并不关心某些命令,可以使用过滤器功能,过滤掉某些命令,只处理希望收到的数据。

过滤器通过心跳命令设置, 在发送心跳命令时,添加过滤器参数。
{
"heartbeat":{
"onlyReceiveMessageList":[1012, 1013],
"onlyReceiveSenderRoleList": ["UnrealEngine"],
"onlyReceiveSenderIdList":["unreal_engine_01"]
}
}
参数结构如下:
参数名称
必选
类型
描述
onlyReceiveMessageList
List<int>
仅接收列表里的命令
onlyReceiveSenderRoleList
List<String>
仅接收某些角色发送的命令
onlyReceiveSenderIdList
List<String>
仅接收某个发送者发送的命令
这3个过滤器可以组合使用, 如果都不使用的话, 就会收到所有的命令。

其中,每个命令的 ID, 会标在下面的命令介绍中, 也可以参考 proto 文件。

3.3 状态报告

主控每间隔 1 秒会向所有活跃的节点发送状态报告,各节点通过状态报告判断主控存活,也可以通过状态报告判断其他节点的存活状态。
{
"statusReport":{
"nodeInfoList":[
{
"nodeRole": "UnrealEngine",
"nodeId":"unreal_engine_01",
"ip":"127.0.0.1",
"port":52108,
"dataType":"NODE_DATA_TYPE_JSON",
"extendedInfoJson":"{}"
}
]
}
}
收到的状态报告,其中 nodeInfoList 为活跃节点的信息,包括节点的 IP 地址,端口, 还有心跳包里上报的信息。

4. 播报对话命令

4.1 播报命令(1010 - speakCommand)

播报命令用来控制数智人播报对应的文本,可以配合动作。
{
"speakCommand":{
"actorName":"xiaowei",
"text":"你好呀,<insert-action type=\\"left_side1\\"/> 我正在做动作"
}
}
参数说明:
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,统一填写 "xiaowei"
text
String
要播报的文本,可以带动作标签
isSmartAction
Bool
是否开启智能动作
播报命令发送后, 数智人会回复播报的状态指令。



如需要插入动作,请获取动作名称列表, 并在播报文本中插入动作标签。 动作标签格式为:
<insert-action type="2hands_forward2" />你好啊</insert-action>

回复指令: 完成回复(1021 - replyFinishCommand)

用户可以在数智人平台配置进行播报内容的替换。
收到此命令表示数智人平台干预了播报内容。不是每次播报都会收到此命令,如果是原样播报则没有此命令。
如果回复内容过长,会被拆分,可能会收到多条命令。
{
"replyFinishCommand": {
"actorName": "xiaowei",
"nlpResult": "{\\"Header\\":{\\"RequestID\\":\\"191cd2024a9446968a1360443bcf6434\\",\\"SessionID\\":\\"bjed97692a17150632309977895\\",\\"Code\\":0,\\"Message\\":\\"\\"},\\"Payload\\":{\\"ReplyType\\":\\"enhanceText\\",\\"ReplyPro\\":\\"你好呀,请问有什么问题要问我吗?\\",\\"ReplyDisplay\\":\\"你好呀,请问有什么问题要问我吗?\\",\\"InteractionType\\":\\"\\",\\"InteractionContent\\":\\"\\",\\"Uninterrupt\\":true,\\"Muted\\":false,\\"SeqNo\\":1,\\"ContentType\\":0,\\"TtsSupport\\":true,\\"IsFinal\\":true,\\"IsHighLight\\":true}}"
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,一定是 "xiaowei"
nlpResult
String
对话平台返回的结果,详情见 4.4 节 关于 nlpResult 的介绍

回复指令: 播报开始(1012 - speakStartCommand)

表示开始说话。
{
"speakStartCommand":{
"actorName":"xiaowei"
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,一定是 "xiaowei"

回复指令:播报内容(1015 - speakContentCommand)

表示正在说话的内容,并带了说话的时间戳, 可以方便显示字幕。 如果文本很长,会收到多条播报内容指令。
{
"speakContentCommand":{
"actorName":"xiaowei",
"ttsResult":"[{\\"Word\\":\\"你好\\",\\"T1\\":\\"300000\\",\\"T2\\":\\"4100000\\"},{\\"Word\\":\\"呀\\",\\"T1\\":\\"4100000\\",\\"T2\\":\\"7000000\\"}]"
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,一定是 "xiaowei"
ttsResult
String
TTS 的结果,也是个 json 字符串, 其中 T1 为开始时间, T2 为结束时间

回复指令: 播报结束(1013 - speakFinishCommand)

表示播报结束。
{
"speakFinishCommand":{
"actorName":"xiaowei"
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,一定是 "xiaowei"

4.2 流式播报命令(1011 - streamSpeakCommand)

流式播报命令用来控制数智人流式播报对应的文本。
{
"streamSpeakCommand":{
"actorName":"xiaowei",
"text":"大家好,",
"sequenceNumber":1,
"isFinal":false,
"isSmartAction":true
}
}
参数说明:
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,统一填写 "xiaowei"
text
String
要播报的文本,可以带动作标签
sequenceNumber
Int
流式请求分片的序号
isFinal
Bool
是否最后一个流式分片
isSmartAction
Bool
是否开启智能动作
isSentence
Bool
是否开启流式子句,只有开启流式子句才会收到 speakSentenceStartCommand 等指令。
流式播报命令发送后, 数智人会回复播报的状态指令。回复的播报状态,请-通过 TVH.on("package", callback) 进行监听。
数智人平台会对流式文本请求进行重新组句等操作,并将结果通过replyFinishCommand返回,和3.1节中非流式文本请求一致。
重新组句后的子句个数和发送的文本请求数不一定相等,每个子句都会对应一个replyFinishCommand。数智人还会回复子句级别的状态,如 speakSentenceStartCommand和 speakSentenceOverCommand。




注意:
1. 流式播报命令 streamSpeakCommand 的多个子句的 traceId 需要保持一致,sessionId 也需要保持一致。当一个流式播报结束后(isFinal 为 true),需要更换 traceId。
2. 重组后的每个子句都有speakSentenceStartCommandspeakSentenceOverCommand
3. 流式播报命令中不能在播报文本中插入动作标签,只能使用 isSmartAction: true 开启智能动作。

回复指令: 播报子句开始(1016 - speakSentenceStartCommand)

表示播报子句开始。
{
"speakSentenceStartCommand":{
"actorName":"xiaowei",
"sequenceNumber":1
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,一定是 "xiaowei"
sequenceNumber
Int
流式请求分片的序号

回复指令: 播报子句结束(1017 - speakSentenceOverCommand)

表示播报子句结束。
{
"speakSentenceOverCommand":{
"actorName":"xiaowei",
"sequenceNumber":1
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,一定是 "xiaowei"
sequenceNumber
Int
流式请求分片的序号

回复指令: 可以发送下一个流式请求(1018 - speakSentenceNextCommand)

表示可以发送下一个流式请求,在需要进行发送速度控制时使用。
{
"speakSentenceNextCommand":{
"actorName":"xiaowei",
"sequenceNumber":1
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,一定是 "xiaowei"
sequenceNumber
Int
流式请求分片的序号

4.3 停止播报指令 (1030 - stopSpeakCommand)

停止播报指令用来在播报过程中停止播报。
{
"stopSpeakCommand":{
"actorName":"xiaowei"
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,一定是 "xiaowei"
发送停止播报指令后,会收到停止完成的指令。 同时之前播报指令也会返回播报完成的指令。





4.4 请求对话指令(1020 - answerCommand)

请求对话指令,用来让数智人回答问题, 问题可以在平台配置。
{
"answerCommand":{
"actorName":"xiaowei",
"text":"请介绍下你自己",
"newRound":true
}
}

参数说明:
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,统一填写 "xiaowei"
text
String
要问的问题文本,为纯文本
newRound
Bool
是否新一轮对话, 每一轮对话有自己的上下文。 如果需要新开一轮对话, 请传 true.
第一次发送对话请求时, 一定要传 true.
发送请求对话指令后, 会收到对话结果指令和播报相关的指令。




回复指令: 问答完成指令(1021 - answerFinishCommand)

{
"answerFinishCommand": {
"actorName": "xiaowei",
"nlpResult": "{\\"Header\\":{\\"RequestID\\":\\"191cd2024a9446968a1360443bcf6434\\",\\"SessionID\\":\\"bjed97692a17150632309977895\\",\\"Code\\":0,\\"Message\\":\\"\\"},\\"Payload\\":{\\"ReplyType\\":\\"yunxiaowei\\",\\"ReplyPro\\":\\"你好呀,请问有什么问题要问我吗?\\",\\"ReplyDisplay\\":\\"你好呀,请问有什么问题要问我吗?\\",\\"InteractionType\\":\\"\\",\\"InteractionContent\\":\\"\\",\\"Uninterrupt\\":true,\\"Muted\\":false,\\"SeqNo\\":1,\\"ContentType\\":0,\\"TtsSupport\\":true,\\"IsFinal\\":true,\\"IsHighLight\\":true}}"
}
}
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,统一填写 "xiaowei"
nlpResult
String
问答回复的结果
回复的问答结果是在对话平台配置的, 可以配置额外的指令。

其中 nlpResult 数据格式:
{
"Header": {
"RequestID": "191cd2024a9446968a1360443bcf6434",
"SessionID": "bjed97692a17150632309977895",
"Code": 0,
"Message": ""
},
"Payload": {
"ReplyType": "yunxiaowei",
"ReplyPro": "你好呀,请问有什么问题要问我吗?",
"ReplyDisplay": "你好呀,请问有什么问题要问我吗?",
"InteractionType": "",
"InteractionContent": "",
"Uninterrupt": true,
"Muted": false,
"SeqNo": 1,
"ContentType": 0,
"TtsSupport": true,
"IsFinal": true,
"IsHighLight": true
}
}
参数名称
必选
类型
描述
ReplyType
String
回复语类型
cloudAiGpt:腾讯云大模型对话
yunxiaowei:云小微客服
cloudAiWaiting: 首包超时等待话术
cloudAiTimeOut: 超时未返回话术,会话结束
sensitive:敏感内容固定话术
input:纯文本输入或流式文本输入的内容
enhanceText:纯文本驱动匹配上了话术管理中的内容
ReplyPro
String
用于播报的内容,含 ssml 标签和动作
ReplyDisplay
String
用于展示在端上的内容,含富文本标签
InteractionType
String
特殊消息类型
InteractionContent
String
特殊消息内容,用于下发弹窗、图片等非文本类的特殊消息
Uninterrupt
String
当前播报句是否可打断
Muted
String
播报当前句时是否关闭收音
SeqNo
Number
子句序号,大模型正常文本 SeqNo 从 1 开始,兜底话术从 0 开始
ContentType
Number
区分内容类型
0:未知
1:普通字符串
2:有序列表
3:无序列表
4:图片链接
5:http链接
6:表格
7:代码块
TtsSupport
String
当前子句是否播报
IsFinal
String
是否为最后一句
IsHighLight
String
是否需要高亮展示

5. ASR 命令

5.1 开始和停止 ASR (2000 - asrControlCommand)

控制 ASR 程序启动或停止收音。
{
"asrControlCommand":{
"enableAsr": true
}
}
参数说明:
参数名称
必选
类型
描述
enableAsr
bool
启动或停止 ASR 收音

5.2 监听指令:语音识别结果 (2002 - asrResultUpdateCommand)

ASR 程序会持续发出语音的识别结果,包括中间结果。
{
"asrResultUpdateCommand":{
"text": "今天天气不错",
"sentenceComplete": false
}
}
参数说明:
参数名称
必选
类型
描述
text
String
识别的文本
sentenceComplete
bool
是否是一个完整的句子

6. 多模客户端 命令

6.1 预览窗口保持在屏幕顶层 (2003 - bodyAnalysisWindowStayOnTopCommand)

如果需要多模检测客户端程序预览窗口保持在屏幕顶层,在浏览器/播放器/游戏窗口全屏后,需要通过此对动作检测窗口置顶。
{
"bodyAnalysisWindowStayOnTopCommand":{
"stayOnTop": true
}
}
参数说明:
参数名称
必选
类型
描述
stayOnTop
bool
动作检测窗口保持在屏幕顶层

6.2 监听指令:人脸和手势识别更新 (2004 - bodyAnalysisResultUpdateCommand)

多模客户端程序检测到人脸和手势的变更后,会通过此命令更新识别结果。
{
"bodyAnalysisResultUpdateCommand":{
"faceCount": 1,
"faceRect": {
"x": 100.0,
"y": 100.0,
"width": 60.0,
"height": 60.0
},
"gestureName": "label_ok",
"probability": 0.9,
"gestureRect": {
"x": 300.0,
"y": 50.0,
"width": 40.0,
"height": 40.0
}
}
}
参数说明:
参数名称
必选
类型
描述
faceCount
int
人脸张数
faceRect
Object
选中人脸的位置(face_count为0时无效)
gestureName
String
识别的手势名
probability
Float
识别手势的置信度
gestureRect
Object
手势的位置(gesture_name为空时无效)