AI与音视频快速接入
约 1437 字大约 5 分钟
2026-10-16
先用无媒体的文字会话验证身份、能力、请求关联和回复生命周期,再增加音频或视频。下面是一条独立完整的signaling/message接入,不需先调用/ai。
1. 平台和设备准备
- 平台配置产品与设备、绑定主人及可用智能体/分身,启用统一信令和对应模型适配。文字示例使用支持文字输入的串联模型,不选择仅音频的原生Realtime模型。
- 获取部署方提供的MQTT地址、TLS信任和设备三元组,按设备身份及MQTT认证连接。不得在消息中自报企业或用户替代认证。
- 在发布请求前订阅两个下行Topic:
$thing/down/signaling/{productID}/{deviceName}与$thing/down/message/{productID}/{deviceName}。使用实际产品和设备替换两个路径变量,不发布retained消息。 - 为本次连接建立请求表和独立事件水位。
msgToken及inputId用不超过128字节的非空唯一字符串,ID不转成数字。
下列每个JSON都是单独一条MQTT负载;session-demo必须替换为本次平台返回的sessionId,不能硬编码跨重连复用。
2. 能力上报
设备发到上行signaling:
{"msgToken":"cap-text-1","method":"capabilityReport","params":{"revision":1,"purposes":["aiConversation"],"transports":["none"],"features":[],"inputModalities":["text"],"outputModalities":["text"]}}平台在下行signaling确认。只在成功后继续;错误处理见本页末尾。
{"msgToken":"cap-text-1","method":"requestAck","code":200,"data":{"requestMethod":"capabilityReport","result":{"acceptedRevision":1}}}3. 创建与建立
设备发上行signaling:
{"msgToken":"create-text-1","method":"sessionCreate","params":{"purpose":"aiConversation","transport":"none","tracks":[],"inputModalities":["text"],"outputModalities":["text"]}}平台返回下行signaling,保存实际sessionId和选定参数:
{"msgToken":"create-text-1","method":"sessionCreated","sessionId":"session-demo","code":200,"data":{"state":"negotiating","selected":{"transport":"none","inputModalities":["text"],"outputModalities":["text"]},"tracks":[]}}等待建立事件,不能把创建成功当建立完成。none不会分配UDP或Peer,也不发送mediaOffer/mediaState。
{"msgToken":"established-text-1","method":"sessionEstablished","sessionId":"session-demo","eventSeq":1,"data":{"state":"established","mediaRevision":0}}4. 发送输入与接收回复
设备发上行message。同一输入重试保持token、inputId和正文不变。
{"msgToken":"input-text-1","method":"inputSend","sessionId":"session-demo","params":{"inputId":"input-1","contents":[{"type":"text","text":"你好,请简短介绍一下自己。"}],"outputModalities":["text"]}}下行message确认受理,但不是模型完成:
{"msgToken":"input-text-1","method":"requestAck","sessionId":"session-demo","code":200,"data":{"requestMethod":"inputSend","result":{"inputId":"input-1","state":"accepted"}}}随后下行message创建回复,按inputId关联此次输入,保存平台返回的respId:
{"msgToken":"reply-event-1","method":"respCreated","sessionId":"session-demo","messageSeq":1,"data":{"respId":"reply-1","inputId":"input-1"}}平台可能发送若干respTextDelta,最终完整文本以respTextDone为准。以下是示意内容,不是要求模型输出固定句子。
{"msgToken":"reply-event-2","method":"respTextDone","sessionId":"session-demo","messageSeq":2,"data":{"respId":"reply-1","contentIndex":0,"text":"你好,我是你的智能助手。"}}只有回复终态才结束本次生成;没有音频时也需要处理它:
{"msgToken":"reply-event-3","method":"respDone","sessionId":"session-demo","messageSeq":3,"data":{"respId":"reply-1","status":"completed","contentCount":1}}保持会话,用新token和inputId重复步骤4就是下一轮;不重新sessionCreate。失败或取消也须处理对应respDone,不只监听文字。
5. 结束与本地清理
设备先停止本地业务,再发上行signaling:
{"msgToken":"end-text-1","method":"sessionEnd","sessionId":"session-demo","params":{"reason":"userHangup"}}平台下行signaling返回终态:
{"msgToken":"end-text-1","method":"sessionEnded","sessionId":"session-demo","code":200,"data":{"state":"ended","reason":"userHangup"}}关闭请求表、所有未完成回复和该会话媒体;保留必要去重终态。迟到文字不能显示成下一会话的回复。平台也可主动发送独立终态事件,设备必须同样清理。
6. 错误、重试与取消
错误信封沿用原token、应答方法和已分配sessionId。例如不支持输入:
{"msgToken":"input-text-1","method":"requestAck","sessionId":"session-demo","code":422,"data":{"requestMethod":"inputSend","reason":"inputUnsupported"}}请求默认10秒;最多原token重试两次,不换token重做写操作。超时不证明远端未执行;失败不要求存在成功字段。具体错误码见公共约定。
定向取消发上行signaling,目标取实际respCreated,不使用“当前回复”猜测:
{"msgToken":"cancel-text-1","method":"respCancel","sessionId":"session-demo","params":{"respId":"reply-1"}}None会话成功ACK携带原respId及实际cancelled/alreadyFinished状态;随后处理回复终态。取消不能回滚已经执行的设备动作。未知回复可返回404,而不是自动取消另一个回复。
7. 增加音视频
- UDP:使用S02串联或S03实时的能力和创建正文;等媒体建立再启用输入。必须实现128步长序号、输入屏障、每回复nonce和音频尾包,见AI音频命令。
- WebRTC AI:按S20实际采集完整SDP,收到
mediaAnswer安装远端描述,ICE/DTLS实际连通后上报mediaState,等sessionEstablished才发业务输入。完整流程不使用trickle ICE。 - 摄像头/人际通话:从场景手册选对应用途;不要把AI模式或预览许可当成人际麦克风许可。
- 附件:先按附件上传取得ready引用,再提交
inputSend。任意URL和Base64不是有效contentRef。
接入完成应至少验证两轮、失败请求、定向取消、重复请求和结束后迟到消息;音视频还须检查实际解码与停止,不只检查握手成功。
更新日志
2026/10/16 16:04
查看所有更新日志
fe3a7-docs(AI与音视频): 按场景整理完整接入流程与命令契约于
