AI音频控制命令
约 4478 字大约 15 分钟
2026-10-16
本页按 Topic、method 和方向定义完整契约。字段表与JSON中的可选扩展不等于当前全部启用,实际接入前请查支持范围;应用REST封装见应用接入。
audioStart · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 请求 |
| 对应应答 | requestAck |
| 触发与状态变化 | 串联每轮新 inputId;实时一次启动持续多轮。恢复暂停用新 inputId,不新建会话。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S02、S03、S11 |
成功ACK表示平台已具备接收本输入段的条件,设备必须等匹配ACK再发送音频。原生实时冷连接需先完成模型握手和首次恢复输入,串联首次启动需等ASR连接完成;不能仅将启动命令入队就返回成功。ACK不表示语音已经识别或回复已经播放。原生实时暂停后复用已就绪的同一模型连接;串联ASR仍按识别段创建连接,不承诺每轮均已预热。当前开发实现的首次就绪屏障为7秒、开始控制预算8秒,均在外层10秒请求期限内;失败释放连接,不重放音频,详见支持范围。
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| inputId | string | 必填 | 一次采集控制段ID,不等同于云端断句的utteranceId;连续采集允许产生多句,见来源定义 |
| firstPacketSeq | uint | UDP 必填,WebRTC 禁止 | 新输入段下一上行包序号,1~4294967295内的128倍数;平台只接纳不小于此值且严格递增的上行,暂停前的迟到包不进入新输入段。audioStop 不携带。 |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s02-22",
"method": "audioStart",
"sessionId": "s02-session",
"params": {
"inputId": "input-1",
"firstPacketSeq": 256
}
}对应S02-M08;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
audioStop · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 请求 |
| 对应应答 | requestAck |
| 触发与状态变化 | 串联提交该轮输入;实时只暂停,不把结束判断强加给供应商。重复请求不重复提交。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S02、S03 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| inputId | string | 必填 | 当前输入段 |
| lastPacketSeq | uint | UDP必填,WebRTC禁止 | 本输入段最后成功发送的UDP包序号(128倍数),本段未发音频为0,不把建连探测计为输入。平台最多等待250ms接纳尾包,先转发已接纳帧再停止模型输入。缺尾或中间跳号必须记录失败事实,不能清空队列后声称完整。 |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s02-23",
"method": "audioStop",
"sessionId": "s02-session",
"params": {
"inputId": "input-1",
"lastPacketSeq": 12800
}
}对应S02-M10;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
respCancel · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 请求 |
| 对应应答 | requestAck |
| 触发与状态变化 | 必须明确已创建的内容回复目标,尚未发声也可取消;只取消该回复和对应播放,不撤销已发生设备动作,也不停止持续收音。ACK受理与实际回复终态分开,见通用应答。 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 10秒;最多原token重试2次;事件形式不等待ACK |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S03 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 目标回复ID |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s03-52",
"method": "respCancel",
"sessionId": "s03-session",
"params": {
"respId": "reply-new"
}
}对应S03-M22;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
respAudioStart · SIG↓
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/down/signaling/{productID}/{deviceName} |
| 发送→接收 | 平台→设备 |
| 消息类型 | 事件 |
| 对应应答 | 未选安装确认时无应答;已选UDP安装确认时为反向同method回执,见下节 |
| 触发与状态变化 | 建立原回复媒体边界;已选安装确认时,真实源收到精确准入前不向音频发送队列送首帧 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 未选能力保持原行为;已选能力的首次安装窗口至多2秒,裁剪至原会话租约/业务截止,不因重投、接续或设备收到消息而重新计时 |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S02、S03 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 回复ID |
| trackId | string | 必填 | 下行音轨 |
| mediaRevision | uint | 必填 | 当前媒体代次 |
| udpNonce | string | UDP 必填,WebRTC 禁止 | 8字节下行回复 nonce 的16位十六进制表示;与上行及本会话全部其他回复不同。不是密钥,不允许退休回复复活。 |
| firstPacketSeq | uint | UDP 必填,WebRTC 禁止 | 平台为该回复预告的首个下行包序号;非零128倍数,重投不变。设备从此序号统计首包及中间缺口,并拒绝更早的迟到包。无音频回复仍预告下一可用序号,结束时 lastPacketSeq 为0。 |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s02-28",
"method": "respAudioStart",
"sessionId": "s02-session",
"eventSeq": 2,
"data": {
"respId": "reply-1",
"trackId": "speaker-1",
"mediaRevision": 1,
"udpNonce": "0000000000000001",
"firstPacketSeq": 128
}
}对应S02-M16;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
respAudioStart · SIG↑
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/up/signaling/{productID}/{deviceName} |
| 发送→接收 | 设备→平台 |
| 消息类型 | 可选安装事实回执;不是新请求或播放完成事件 |
| 对应应答 | 无;不发送requestAck或ACK-of-ACK |
| 触发与状态变化 | 设备已声明features中的udpReplyStartReceipt,平台在本会话selected中明确选择true;设备安装原nonce/序号/回复边界并获得本地实际PCM Ready后,沿原Start token确认 |
| 前置条件 | 仅AI UDP;当前授权、物理连接、会话/轨/媒体代次及原回复均匹配,不能借该回执启动新会话或重授未声明对应能力的端权限 |
| 超时与重试 | 原首次安装窗口内仅原字节有限重投;不刷新平台截止,不等待二次ACK |
| 幂等与迟到 | 同原精确回执只读幂等;外来或更改字段、取消后、已到期、断连及永久移交后的旧回执不得恢复输出 |
| 失败 | 未完成安装不得伪造200。真实安装门到期用sessionError(scope=response,code=504,reason=mediaFailed)及respDone(failed)关闭该回复,不据此结束仍有效的主会话 |
| 适用场景 | S02-M27;S03的AI UDP回复复用同一可选子流程 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 与原Start相同的回复ID,1~128字符 |
| trackId | string | 必填 | 与原Start相同的输出轨ID,1~128字符 |
| mediaRevision | uint | 必填 | 与原Start相同的正安全整数媒体代次 |
顶层仅msgToken/method/sessionId/code/data,code固定200;msgToken及sessionId沿原Start,不新生成token。data严格仅上述三个字段,禁止params、eventSeq、messageSeq、udpNonce、firstPacketSeq及“已播放完成”等自报字段。平台还要核持久事实和当前设备出处,再向原模型流投递私有准入;回执本身不授予媒体权限。两秒仅约束首次安装,不裁断已安装的长回复。设备软件PCM Ready、网络首帧、连续两个有声解码帧及实体扬声器播放是不同观察点。
报文实例
{
"msgToken": "s02-28",
"method": "respAudioStart",
"sessionId": "s02-session",
"code": 200,
"data": {
"respId": "reply-1",
"trackId": "speaker-1",
"mediaRevision": 1
}
}respAudioDone · SIG↓
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/down/signaling/{productID}/{deviceName} |
| 发送→接收 | 平台→设备 |
| 消息类型 | 事件 |
| 对应应答 | — |
| 触发与状态变化 | 平台已结束该回复网络音频发送,不是设备播放完成 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 不等待ACK;重复按公共规则丢弃/重放 |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S02 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 回复ID |
| trackId | string | 必填 | 下行音轨 |
| mediaRevision | uint | 必填 | 当前媒体代次 |
| lastPacketSeq | uint | UDP 必填,WebRTC 禁止 | 该回复实际发出的最后一包序号(128倍数);未发送音频为0。设备还需等待尾包和实际播放排空,不得收到本事件就截断队列。 |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s02-32",
"method": "respAudioDone",
"sessionId": "s02-session",
"eventSeq": 4,
"data": {
"respId": "reply-1",
"trackId": "speaker-1",
"mediaRevision": 1,
"lastPacketSeq": 12800
}
}对应S02-M20;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
统一信令 UDP 回复与输入边界
实现核对发现:原16字节包头没有 respId,单靠 MQTT 事件序号无法识别跨回复迟到包。因此仅统一信令通道使用以上条件字段,未声明对应能力的设备现行协议不变。完整包仍为 01 00 | payloadLength:u16BE | nonce:8bytes | sequence:u32BE | AES-128-CTR(payload),IV仍为完整包头;每包只承载一帧 Opus(最多1275字节)。新通道两个方向从128开始,每包递增128,给单包最多80个AES块预留不相交计数区间;禁止回绕。
sessionCreated.media.udp.nonce仍是16字节初始头;其中8字节 nonce 只用于上行和建连探测。探测使用编码静音包的原字节回显,不启动麦克风/扬声器,不把探测成功称为实际人声解码或 AEC 验收。respAudioStart.udpNonce与firstPacketSeq原子分配,只覆盖当前回复的下行头与起点;上行持续保持原 nonce 和序号,不因回复切换而重置。模型产生的每帧必须携带其固定 respId,不能在发送时换成“当前回复”。- 媒体可能先于 MQTT 到达:设备最多暂存16个未知回复包(约20KB),收到合法开始信令后才能解码;已退休 nonce 的包立即丢弃,即使其序号更大。最多保留512个回复标识,耗尽则新建会话,不淘汰历史来允许旧回复复活。
- 同一回复的重复开始、结束及取消不产生额外驱动副作用;
audioSpeechInterrupted清该回复播放队列,但不停止全双工上行。恢复输入需新 inputId 和 firstPacketSeq,并清空暂停前的采集积压。 - 结束通知到达后最多等250ms尾包;超时明确记录
missingTail验证失败事实,不能报告音频完整。随后仍等待当前播放代次真实排空。报文先后不等于实际播放先后。 - 设备从
firstPacketSeq到lastPacketSeq核对128步长序列,首包或中间包缺失都不能报告observedComplete;零音频回复以lastPacketSeq=0区分。该事实仅证明设备观察到完整序号与解码计数,不是 AES-CTR 的密码学完整性认证,也不代表扬声器真实播放完成。未声明对应能力的设备报文不变。 - CTR 包格式不提供消息认证;不能将 nonce/序号检查称为认证加密。通道参数只在已鉴权信令下发,套接字绑定已授权对端;安全边界与后续传输加固另行评估。
以上是统一信令实现中的契约调整,整体联调与发布状态见支持范围,不是未声明对应能力的设备行为变更或硬件验收。
audioSpeechInterrupted · SIG↓
网络发送结束不代表设备播放排空。本事件允许在同一回复的respAudioDone及respDone(completed)之后到达:设备只清理该respId仍在播放的缓冲,已排空则幂等忽略,不停止新回复或持续上行,也不把已经完成的内容终态改为取消。该规则只属于统一信令协议,不改变现行/ai设备行为。
| 项目 | 契约 |
|---|---|
| Topic/接口 | $thing/down/signaling/{productID}/{deviceName} |
| 发送→接收 | 平台→设备 |
| 消息类型 | 事件 |
| 对应应答 | — |
| 触发与状态变化 | 目标回复被打断;设备按 respId 清旧播放队列,持续上行不停止 |
| 前置条件 | 会话/参与端有效,满足方法语义;结束/失败事件允许清理非终态会话 |
| 超时与重试 | 不等待ACK;重复按公共规则丢弃/重放 |
| 幂等与迟到 | 遵循公共约定;终态不复活;旧sessionId/媒体代次拒绝或丢弃,不影响新资源 |
| 失败 | 请求按对应应答方法返回实际code和data.reason;异步失败单独事件,不以成功字段包装错误 |
| 适用场景 | S03 |
正文字段
| 字段 | 类型 | 必填条件 | 枚举/默认及含义 |
|---|---|---|---|
| respId | string | 必填 | 回复ID |
| trackId | string | 必填 | 下行音轨 |
| mediaRevision | uint | 必填 | 当前媒体代次 |
所有成功字段表以外的共通错误负载为 data.reason:string;条件不满足时不要求成功字段。未声明可选字段缺省为“未提供”,无隐式开启能力。
报文实例
{
"msgToken": "s03-45",
"method": "audioSpeechInterrupted",
"sessionId": "s03-session",
"eventSeq": 4,
"data": {
"respId": "reply-old",
"trackId": "speaker-1",
"mediaRevision": 1
}
}对应S03-M15;完整应答和异常在该场景或S11。设备Topic中的productID/deviceName来自认证,不从正文取身份。
更新日志
2026/10/16 16:04
查看所有更新日志
fe3a7-docs(AI与音视频): 按场景整理完整接入流程与命令契约于
