公共约定与数据类型
约 3439 字大约 11 分钟
2026-10-16
本页按 Topic、method 和方向定义完整契约。字段表与JSON中的可选扩展不等于当前全部启用,实际接入前请查支持范围;应用REST封装见应用接入。
路由与信封
| 缩写 | 传输位置 |
|---|---|
| SIG↑ / SIG↓ | $thing/up/signaling/{productID}/{deviceName} / $thing/down/signaling/{productID}/{deviceName} |
| MSG↑ / MSG↓ | $thing/up/message/{productID}/{deviceName} / $thing/down/message/{productID}/{deviceName} |
| APP↑ | POST /api/v1/im/interaction/commands,登录态鉴权 |
| APP↓ | 逻辑事件 interaction.event,当前经鉴权REST events拉取,内容事件为interaction.message;不能依此假定WebSocket推送已装配 |
| ACT↑ / ACT↓ | $thing/up/action/{productID}/{deviceName} / $thing/down/action/{productID}/{deviceName} |
| PROP↑ / PROP↓ | $thing/up/property/{productID}/{deviceName} / $thing/down/property/{productID}/{deviceName} |
| INTERNAL | 内部MCP/RPC示意,不是设备可发布接口 |
上下行的 deviceName/productID 均取鉴权上下文;客户端不能用payload里的身份换设备。信令和消息信封没有协议版本字段。以下规则仅定义对应Topic/API,不重定义物模型或内部RPC信封。
| 字段 | 类型 | 必填条件与含义 |
|---|---|---|
| msgToken | string | 所有消息必填,非空;请求与应答同值,独立事件新值 |
| method | string | 必填;命令索引中的方法;未知方法不产生副作用 |
| sessionId | string | 会话建立后必填;capabilityReport及其requestAck应答、sessionCreate请求、失败创建、异步投递、无会话设备控制不携带 |
| params | object | 请求必填,不论上下行;不能与data同时出现 |
| data | object | 应答/事件必填;错误时只有错误负载,不强制成功字段 |
| code | integer | 应答必填,200成功;sessionError异步错误也必填;其他纯事件不携带 |
| eventSeq | uint | 平台会话信令事件/有副作用的下行请求必填;按会话及目标端从1递增;请求应答可不带 |
| messageSeq | uint | 会话内容下行事件必填,独立于eventSeq递增;异步投递不使用 |
| target | object | 仅APP发起open/messageSend/device.action/device.propertyControl必填,含productID/deviceName;其他请求以sessionId绑定目标 |
应答或事件方法如何区分:带code是对应请求应答,否则是独立状态事件;sessionError是明确例外。应答关联键为认证主体+路由族+原请求method+msgToken,映射方法见命令章节;不能拿另一接收者的通知充当ACK。sessionInvite的Accept/Reject沿用邀请token,并等待requestAck并用data.requestMethod区分sessionAccept/sessionReject,不与邀请处理缓存混为一条请求。
已明确选定AI UDP安装确认时,设备对下行respAudioStart事件发送同method/同token的200反向事实回执;这是另一明确例外,不是新的params请求。仅允许其专用严格data正文且不带序号,不再回应requestAck。未选时该事件仍无回执,完整约束见安装确认。
所有方法正文表均描述params或data内字段;顶层字段只在本页定义。JSON示例的编号、解释、超时均是文档元信息,不放入线上payload。占位SDP、port=0、密钥、地址和文件引用不能直接连接。
类型表
信令/内容信封上限65536字节,UTF-8编码,根对象且只有一份JSON,不允许尾随第二个对象、重复键、无效Unicode或未知顶层字段。解析嵌套深度限制为32;顶层可选字段显式null不能冒充省略。msgToken/sessionId为1~128字节,method为1~64字节;标识符不允许控制字符。请求的params与应答/事件的data必须二选一,不能照搬包含两者的“信封字段示意”作为实际报文。各方法正文也执行严格字段与类型校验。
未注明的可选字段缺省为未声明,不推断支持;无默认值的必填字段缺失返回400。uint为非负安全整数,已发事件序号和实际媒体revision从1起;未发生操作的expectedRevision/快照水位可为0,transport=none的mediaRevision固定0;contentIndex从0起;Unix毫秒用int64,在JS端不得超过安全整数。字符串ID不转数字。
| 类型 | 成员与规则 |
|---|---|
| purpose | aiConversation / faceTranslation / humanCall / ipcLiveView / ipcTalk / recordPlayback / aiVision / liveBroadcast / mediaPlayback |
| Audio | format:string=opus;sampleRate:int、channels:int、frameDuration:int(毫秒)必填;主要16k/mono/20ms,24k/60ms须能力交集,平台适配器重采样/拆帧 |
| Camera | cameraId:string、codecs:string[]、maxPublishers:正整数,均必填;maxPublishers是摄像头源发布容量,不是观看者权限 |
| Track | trackId:string、kind:audio/video/subtitle、sourceId:string、direction:sendonly/recvonly/sendrecv、codec:string、state:requested/active/paused/stopped,均必填;方向相对收到定义的端 |
| Selection | transport:none/udp/webrtc必填;interactionMode:halfDuplex/fullDuplex在aiConversation或aiVision含音频时必填;audioParams:Audio在UDP必填;udpReplyStartReceipt仅AI UDP明确选定时为true,未选省略;inputModalities/outputModalities:string[]在aiVision、none模式或文件模态必填;其他情况沿用已协商媒体轨对应模态 |
| Media | udp对象:server:string、port:int、key:string、nonce:string必填;真实port为1–65535,key为16字节AES密钥hex,nonce为16字节初始头hex,来源按已验证UDP实现;示例故意不可用 |
| WebRTC | iceMode:string固定complete、sdp:string非空完整SDP,均必填;不定义trickle ICE;示例不是合法可连接SDP |
| reason | 非空稳定错误/结束原因字符串;下表列基本值,设备未知值按通用失败显示,不能当成功 |
subtitle是逻辑内容轨,不通过RTP送JSON;translationResult经message承载。视频sourceId=cameraId,参与者音轨sourceId可指成员。轨ID只在会话内唯一,不能当硬件ID;源引用跨观看会话由平台映射和鉴权,不让设备猜测。
应答、幂等与顺序
- 普通控制应答10秒;邀请30秒,expiresAt更早则优先;SDP/连通阶段15秒。邀请过期不得接受迟到Accept;会话结束后不接受新轨。
- APP HTTP校验失败直接4xx;通过验证返回202和原msgToken(只代表受理),最终结果由interaction.result返回,默认10秒;open只等待邀请已发出的结果,接通/结束另由interaction.state通知,不能阻塞HTTP等待用户接听。
- 请求超时最多同token重试2次,每次间隔10秒;邀请答复不延长expiresAt。相同token且内容相同重放结果;同token不同内容409。失败、成功及终态均需幂等。
- 会话内去重记录保存到结束后至少10分钟;未分配会话的创建/能力请求保存10分钟;deliveryId去重保存到expiresAt后至少24小时。设备动作复用其物模型幂等边界,不能用换token重试写操作。
- eventSeq与messageSeq分别按通道维护。绝对状态可用更高序号覆盖旧值;增量文本缺口不能直接拼接,等待最终Done的完整文本;messageSeq只排序内容,不排序UDP。会话控制不缓存后跨新会话执行。
- MQTT控制按QoS1设计(允许重复),retained=false;端点仍须按token和序号去重。终态重复是幂等,无副作用。跨Topic/UDP/WebRTC无严格顺序保证。
- 请求超时不证明远端未执行;状态未知时先阻止新增危险操作并回查/结束会话,不伪造成功。工具写操作回执未知不得播报成功。
状态与失败
| code / reason | 处理与资源影响 |
|---|---|
| 400 invalidParams/invalidState/unsupportedMethod | 参数、方法或状态非法;无新副作用 |
| 403 permissionDenied/participantConsentMissing/privacyEnabled | 不下发媒体凭据;已撤权先断转发/取帧 |
| 404 sessionNotFound/resourceNotFound/responseNotFound | 不新建隐式会话/轨/回复 |
| 409 tokenConflict/resourceBusy/staleRevision/sessionExpired | 不改变已有资源归属,不复活终态 |
| 422 unsupportedCapability/visionModelUnavailable | 不静默降级模型、模态或接听策略 |
| 500 internalError | 脱敏报告,按影响范围结束或保留会话 |
| 502 mediaNegotiationFailed/upstreamUnavailable | 关闭失败代次资源;明确retryable |
| 504 controlTimeout/modelTimeout | 控制结果未知与模型本轮失败分开处理 |
错误应答保留原应答method、msgToken、实际code,data.reason必填;有已分配sessionId时保留。sessionError是新token异步事件,带retryable;不可恢复再发sessionEnded。所有错误的具体JSON和分支见S11。
ended是唯一会话终态;拒接/超时/失败以reason区分。sessionEnded应答与终态通知可合并为带code/eventSeq的一条,也允许独立终态通知;接收端按sessionId幂等清理。processorState(failed)只影响该处理器,不将主通话标failed。
媒体代次与清理
设备/应用各自Peer的mediaRevision从1起递增,属于(sessionId,参与端)而非全会话共享计数。平台串行化每端重协商,旧revision不再收发;完整SDP交换成功后,两侧ICE/DTLS连通且所需参与端mediaState确认后才established。15秒未恢复结束会话,不无限保留租约。
UDP只有音频:16字节明文头,第0字节媒体协议版本、第1字节保留、第2–3字节长度、第4–11字节nonce区、第12–15字节大端序号,后接AES-CTR Opus。统一信令不改该包头或额外塞入sessionId/respId;会话由已授权端点/密钥绑定。上下行序号独立,不接受重复/迟到序号;重建UDP通道必须新密钥/nonce并销毁旧通道,不能仅用mediaRevision区分旧包。
统一信令适配层的UDP连通探测用相同包格式的短静音Opus帧,平台确认合法上行后下发静音应答;仅negotiating阶段作为探测,不交模型或扬声器。该探测逻辑扩展契约,须确认支持,不改变已运行协议。WebRTC媒体用DTLS-SRTP,媒体轨/SDP的mid映射由平台维护。
结束立即停止模型输入与取帧、撤销订阅/访问令牌、关闭Peer/UDP通道、释放焦点和计费资源。实际硬件停机需设备确认;失联先停止服务端转发并标unknown。音频发送完成、状态通知和物理播放完成分别记录。
完整场景扩展规则
扩展命令是S12–S20的字段规范,不是额外版本。能力上报controlCapabilities包含operations(支持的方法及operation,如floorControl.acquire)、sourceTypes、maxVideoTracks、fullDuplexTransports。每个控制先与平台能力求交集;未上报就不能调用,也不凭硬件有摄像头推断支持屏幕分享/录制。应用端也必须经已鉴权端注册上报同类能力,入口为interaction.control(command=capabilityReport),参数复用capabilityReport,响应正文取其requestAck.data.result,不信任应用自报身份。
人际呼叫使用targetParty、callType、callPolicy;服务端分配callGroupId和每端独立sessionId,sessionCreated/Invite均返回组ID。所有端均无权限时创建失败;并发接听平台原子选中胜出端,其他腿终止。应用的interaction.open保留原target作为呼叫路由对象;终端邀请与接听见S17,不将同一用户多个登录端视为同一媒体Peer。
Track可含sourceType,定义见扩展命令;Screen与systemAudio分别授权。WebRTC fullDuplex仅在双方能力明确允许时启用;aiVision带音频时也必须显式上报supportedInteractionModes并返回选定模式,不默认开启fullDuplex;仅图像/视频输入而没有语音时不携带该字段。云端采样和帧长适配不改变设备RTP时钟。
输入及工具扩展另见命令08:413 payloadTooLarge、409 inputBusy/toolCallExpired。interaction.control包装capabilityReport时允许无sessionId;其他已会话命令必须有sessionId。
额外错误:409 alreadyAnswered/floorBusy/staleRevision/endpointChanged;416 seekOutOfRange;422 unsupportedOperation/unsupportedSource;403 recordingConsentMissing/priorityDenied;错误仍使用data.reason。Snapshot以水位恢复控制状态,不重播已消费语音或重发设备写操作。会话结束后允许录制ready/failed的产物状态,但不接受媒体或新的控制请求。
睡眠不是长期后台录音许可。设备要继续后台媒体必须同时具备操作系统权限、产品策略和有效用户授权;否则本地停采集。断网15秒恢复策略默认不变,超时后重新创建;任意修改恢复窗口必须双方明确协商,不能单端无限续租。
回复关闭与异常范围
所有AI路径均以respDone关闭每个respId;成功、取消、失败只选一个终态。S02/S03/S04/S09/S20的回复子流程都适用,文本Done、音频Done与工具Result不能替代。会话突然结束时sessionEnded封闭该会话所有未终结回复(本地标取消,不伪造completed),后续内容丢弃。sessionError(scope=response/input/tool)只影响指定对象,不因此结束主会话。
transport=none不分配UDP密钥或Peer,sessionCreated后模型上下文可用才发sessionEstablished(mediaRevision=0)。其空轨不是连接失败;text/file能力必须求交集。新建媒体轨必须创建另一媒体会话,不允许向none会话塞入RTP。
通用应答与应用复用
上行受理确认统一为requestAck,仅覆盖该页列出的十类上行,含无code的主动trackState事实;data.requestMethod+原token关联,data.result按原上行类型解析。成功失败均不带事件水位。业务完成仍用各自状态/终态事件,带code控制回执不再ACK。
应用的interaction.mediaOffer/mediaState/trackControl是同一业务命令在已鉴权API上的适配入口,params直接引用设备规范;服务器复用校验及状态机,但分别检查用户/设备权限与自身Peer。详见公共流程与复用。
更新日志
2026/10/16 16:04
查看所有更新日志
fe3a7-docs(AI与音视频): 按场景整理完整接入流程与命令契约于
