控制协议文档

最近更新时间:2024-10-10 16:40:52

我的收藏

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, 可以区分是哪个发送者发出来的命令
XXXCommand
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
要播报的文本,可以带动作标签
播报命令发送后, 数智人会回复播报的状态指令。



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

回复指令: 播报开始(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,
"isSentence":false
}
}
参数说明:
参数名称
必选
类型
描述
actorName
String
演员名称, 现在数智人只有一个演员,统一填写 "xiaowei"
text
String
要播报的文本,可以带动作标签
sequenceNumber
Int
流式请求分片的序号
isFinal
Bool
是否最后一个流式分片
isSmartAction
Bool
是否开启智能动作
isSentence
Bool
true 表示为完整子句,不需要服务端分句处理。false 表示需要在服务端分句。
流式播报命令发送后, 数智人会回复播报的状态指令。

当isSentence为true时,数智人还会回复子句级别的状态,如 speakSentenceStartCommand,speakSentenceNextCommand 和speakSentenceOverCommand。



当 isSentence 为 false 时,数智人回复的状态指令与非流式相同。



注意:
1. 流式播报命令 streamSpeakCommand 的多个子句的 traceId 需要保持一致,sessionId 也需要保持一致。当一个流式播报结束后(isFinal 为true),需要更换 traceId。
2. 当 isSentence 为 true 时,每个子句都会有 speakSentenceStartCommand, speakSentenceNextCommandspeakSentenceOverCommand
3. 当 isSentence 为 true 时,当一个子句被服务端处理完成,就会发送对应的speakSentenceNextCommand,因此会发生后面子句的 speakSentenceNextCommand 早于前面子句的 speakSentenceStartCommand 的情形。如果希望控制发送速度,可以等收到之前发送子句对于的 speakSentenceNextCommand 回复后,再发送下一个子句。
4. 流式播报命令中不能在播报文本中插入动作标签,只能使用 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为空时无效)