MQTT+UDP 音频接入
约 1350 字大约 5 分钟
2026-10-17
适用于音频设备:MQTT 传控制与内容,UDP 传 Opus 音频。先完成 MQTT 基础接入。本篇的控制流程限定 signaling/message;/ai 入口的建连流程见 UDP 音频通道协议,包头共用但控制规则不能混用。
准备与分工
平台配置 AI 模型和设备使用权限;设备实现 Opus、UDP、AES-CTR、真实采集与播放。主要组合为16kHz、单声道、20ms;最终只用 sessionCreated.data.selected.audioParams。24kHz/60ms 需要实际能力交集和平台适配,不靠设备猜测。模型链路串联/实时与设备半双工/全双工是两条轴;实时也可半双工,全双工必须具备并如实声明 AEC。
从创建到连通
| 顺序 | 发什么/做什么 | 等什么才能继续 | 精确契约 |
|---|---|---|---|
| 1 | 声明实际 udp、音频及模式,创建会话 | requestAck;sessionCreated.code=200 | 能力与创建 |
| 2 | 读取 data.media.udp;发有效短静音探测 | 实际探测应答;不能把静音给模型或扬声器 | UDP 探测与媒体边界 |
| 3 | 上报 mediaState(connected) | 平台独立确认后 sessionEstablished | mediaState |
| 4 | audioStart 带本次输入序号起点 | requestAck 后上行真实语音 | audioStart |
| 5 | 安装 respAudioStart 回复边界 | 被选定安装确认时才回同 token 事实;实际 PCM Ready 后接收 | 回复边界与回执 |
| 6 | 实际解码播放;按模式停止/持续输入 | 网络 Done 和本地播放状态分别记录 | 串联语音、实时语音 |
| 7 | 本地先停,再 sessionEnd | sessionEnded;重复终态幂等释放 | 结束 |
关键报文怎么取值
{
"msgToken": "s02-19",
"method": "sessionCreated",
"sessionId": "s02-session",
"code": 200,
"data": {
"state": "negotiating",
"selected": {
"transport": "udp",
"interactionMode": "halfDuplex",
"udpReplyStartReceipt": true,
"audioParams": {
"format": "opus",
"sampleRate": 16000,
"channels": 1,
"frameDuration": 20
}
},
"tracks": [
{
"trackId": "mic-1",
"kind": "audio",
"sourceId": "mic",
"direction": "sendonly",
"codec": "opus",
"state": "requested"
},
{
"trackId": "speaker-1",
"kind": "audio",
"sourceId": "speaker",
"direction": "recvonly",
"codec": "opus",
"state": "requested"
}
],
"media": {
"udp": {
"server": "<media-host>",
"port": 0,
"key": "<redacted-key>",
"nonce": "<redacted-nonce>"
}
}
}
}示例 server、port=0、key、nonce 是不可连接占位符,替换为本次创建应答,不能硬编码。顶层 sessionId 用于控制和内容;不要将其塞进 UDP 包。tracks 的方向相对设备。完整逐条 JSON 可直接看 串联完整序列。
16 字节包头与防旧音频
0:version(1) | 1:reserved(1) | 2:payload_len(2,BE) | 4:nonce(8) | 12:sequence(4,BE) | 16:ciphertext(N)包头同时是 AES-CTR 初始 counter;详细算法及包长见 UDP 包格式。媒体头 version=1 不代表 MQTT 增加 version 字段。AES-CTR 本身不提供消息认证,不能将其当作 DTLS-SRTP 的等价安全通道;媒体仅接受本会话被授权端点和合法边界。
signaling/message 适配层上下行序号独立,每包步进128(为 CTR counter 留空间),不接受重复/迟到序号,不在同一密钥下回绕。输入用 firstPacketSeq/lastPacketSeq 屏障,回复以 respId 对应的独立 udpNonce 和首包序号隔离;不能把 /ai 的普通递增策略套到这里。取消先清本地旧回复队列,迟到旧 nonce 音频直接丢弃;换通道换密钥,不能只改 mediaRevision。完整字段见 音频控制。
判断成功与排障
探测成功只证明包能往返,不证明已授权开麦,更不证明听到了回复。至少验证真实输入被识别、下行两个连续非静音解码帧、本地播放启停和结束后不再采集。排查按“MQTT 应答→探测→mediaState→建立事件→输入水位→回复边界→解密解码”顺序,不把 respAudioDone 写成设备播放完成。异常使用 失败与恢复流程;软件模拟不等于实体 AEC 验收。
更新日志
2026/10/17 03:27
查看所有更新日志
d04e1-docs(AI与音视频): 按公共主线与场景分支整合接入手册于
