智能硬件团队第一次接音视频,控制台项目开好了,App ID 拿到了,后台也能生成 RTC Token,设备端日志里有入会成功,App 页面上有接听按钮和通话状态。真到联调时,点了呼叫没有声音,或者 App 端黑屏。
硬件项目比纯 App 多了不少变量。芯片平台、RTOS、麦克风、摄像头、I2S、ISP、编码器、Wi-Fi、功耗策略、设备在线状态,全都会影响第一路音视频通话。Demo 阶段一上来就做完整产品页,问题很容易被页面状态、业务权限和推送流程盖住。
首路 Demo 先证明一件事,设备和 App 进入同一个 RTC 频道,设备发出的音频或视频能被 App 收到,App 的语音也能回到设备播放。
声网智能硬件解决方案采用一条很适合硬件团队拆解的路径,设备端使用 RTSA Lite SDK 加入 RTC 频道,客户端使用 RTC SDK 加入同一频道,RTM SDK 1.x 承担设备端和客户端之间的可靠信令交互。业务后台负责分配频道、UID 和 RTC Token。儿童手表、看护屏、宠物摄像头、智能门铃,也能按这条路径跑第一版 Demo。

一. 开通项目时先固定环境
第一步放在控制台和项目配置上。测试环境、预发环境、生产环境要分开,设备端、App 端、业务后台使用同一个声网项目下的 App ID。后面签发 RTC Token、加入频道、查询质量和排查日志,都依赖这个基准。
Demo 初期为了省时间,团队会先用临时 Token 验证入会和收发流。进入正式项目后,RTC Token 要由业务服务端签发,设备端和 App 端都从服务端取 Token。这样才能控制频道权限、用户身份、设备权限和过期时间。固件里写死频道名,App 里临时拼 Token,第一天看着快,联调时会反复制造误判。
项目开通阶段要留下 App ID、项目证书状态、安全模式状态、测试设备的 deviceId、当前固件版本 firmwareVersion。别等设备寄到测试点以后,再回头问它连的是哪个项目。
二. 频道、UID 和 Token 由后台统一下发
很多首路通话失败都出在参数错配。Token 生成时用的是 demo_room_001,设备端入会时传的是 demo-room-001。设备 UID 和用户 UID 在同一个频道里重复。App 端拿了预发环境 Token,设备端连的是测试环境 App ID。Token 已经过期,设备端还在不停重试。
后台生成一次呼叫记录,至少写入 callId、channelId、deviceUid、userUid、rtcTokenExpireAt。设备端和 App 端只读取后台下发的参数,不各自生成频道名,不各自决定 UID。callId 用来串联业务日志,channelId 用来排查 RTC 媒体链路。
| 字段 | 记录内容 | 排查用途 |
|---|---|---|
appId |
声网项目的 App ID,测试、预发、生产分开 | 确认设备端、App 端、Token 生成器是否同源 |
callId |
一次呼叫对应一条业务记录 | 串联设备端、App 端、业务后台日志 |
channelId |
一次 RTC 会话对应一个频道 | 确认设备端和 App 端是否进入同一频道 |
deviceUid |
设备在 RTC 频道内的唯一身份 | 定位远端用户加入、发流、离线事件 |
userUid |
App 用户在 RTC 频道内的唯一身份 | 排查 App 入会、订阅、上行音频 |
rtcTokenExpireAt |
RTC Token 过期时间 | 定位入会失败、重连失败、长通话中断 |
这个规则很朴素,但在硬件联调里特别管用。设备寄给测试同学以后,固件版本、网络环境、账号状态都有可能变。只要 callId 和 channelId 能对上,问题还能回到同一条时间线里。
三. 设备端先跑单向上行
设备端是智能硬件 Demo 里变量最多的一侧。手机 App 上的 RTC SDK 已经很成熟,设备端还要处理麦克风、摄像头、I2S、ISP、编码器、RTOS 任务调度、内存队列和网络波动。第一步先让设备把一路音频或视频稳定发出去。
设备端调用 agora_rtc_init 完成初始化,再调用 agora_rtc_join_channel 加入频道。收到 on_join_channel_success 后,开始向 SDK 送媒体帧。音频通过 agora_rtc_send_audio_data 发送,视频通过 agora_rtc_send_video_data 发送。
这里要分清采集链路和传输链路。RTSA SDK 负责媒体流和信令传输,音视频采集、视频编解码由设备侧通过第三方或自研模块完成。设备端需要把 PCM、Opus、AAC、H.264、MJPEG 等符合互通要求的数据交给 RTSA Lite SDK。App 端收不到流时,不能只看设备是否入会成功,还要看采集有没有开始、编码器有没有输出、发帧接口有没有被调用。
设备端日志要写到第一帧。on_join_channel_success 回调时间、采集开始时间、第一帧编码完成时间、第一次调用发帧接口时间、发送队列深度,都要能查到。音频还要记录采样率、声道数、帧长和编码格式;视频还要记录分辨率、帧率、实际码率和 I 帧时间。
单向上行能跑稳,后面的 App 播放、双向语音、信令状态才有继续排查的基础。
四. App 端先做收流测试页
App 端第一版页面越薄越好。输入频道名,加入频道,显示远端设备是否入会,播放设备音频,渲染设备画面,展示错误码和网络状态。设备列表、家庭共享、呼叫记录、会员权益和复杂接听页都先放后面。
客户端使用 RTC SDK 加入频道。声网智能摄像头 Android 示例里,ChannelMediaOptions 的 clientRoleType 设置为 BROADCASTER,channelProfile 设置为 CHANNEL_PROFILE_LIVE_BROADCASTING,再调用 joinChannel(token, channelName, 0, options)。App 调试页要把频道场景、用户角色、Token、频道名、UID 显示出来,测试包不要只给一个连接中。
App 收不到设备音频时,记录 App 端 channelId、userUid、入会时间、远端 deviceUid 加入时间、远端音频发布事件、远端音频订阅事件、首个可播放音频时间和错误码。设备端再对照 on_join_channel_success、agora_rtc_send_audio_data 和第一帧发送时间。两边时间线对齐后,问题会落到参数、设备发帧、App 订阅或网络传输中的某一段。
我自己写这种联调文档时也容易嫌字段多,真到排查现场才知道,少一个时间戳就得多问三个人。
五. 单向通了再测双向语音
设备上行跑稳后,再打开 App 上行音频,让设备端接收并播放。双向语音会把外放、麦克风、采集任务、播放任务和回调处理放到同一个时间段。开发板上能听到声音,装进外壳后出现啸叫、闷声、回声,智能门铃、儿童手表、桌面玩具都会遇到。
RTSA Lite SDK 两人互通使用 on_audio_data 回调接收音频数据,3 人以上互通使用 on_mixed_audio_data 回调接收混音后的音频数据。第一版固定两人互通,记录 App 端开始说话时间、设备端收到音频回调时间、设备端开始播放时间、扬声器输出音量、麦克风采样率和声道数。
外放测试要覆盖近距离说话、远距离说话、最大音量、双方同时说话。手表戴在手上,门铃挂在墙上,玩具放在桌面,麦克风和扬声器的相对位置都会变化。只在裸板上听过一遍,到了结构件阶段大概率还要返工。
这种返工很烦,真的很烦。
六. 视频通话先盯关键帧和码率
摄像头和门铃的第一版视频 Demo 先用低分辨率。声网智能摄像头场景中的码率配置示例包含 640 × 360、15 fps、400-800 Kbps,1280 × 720、15 fps、1130-2260 Kbps,1920 × 1080、15 fps、1130-4160 Kbps。第一路验证用 640 × 360、15 fps,日志写入实际编码码率、I 帧时间和发送队列深度。
视频 Demo 出现黑屏、花屏、卡住不动,先查关键帧和目标码率。新加入的 App 端需要 I 帧才能开始解码,弱网环境下设备端还要跟随可用带宽调整编码码率。
声网智能摄像头场景里,客户端出现解码错误或频道里加入新终端时,SDK 内部会请求发送关键帧。设备端通过 on_key_frame_gen_req 回调通知 App,App 立即指示编码器编码 I 帧并发送给客户端。日志要记录 on_key_frame_gen_req 触发时间、I 帧生成时间、I 帧发送时间、App 端恢复画面时间。
带宽估计使用 agora_rtc_set_bwe_param 设置 BWE 参数。示例参数为 min_bps = 400000、max_bps = 4160000、start_bps = 500000。SDK 通过 on_target_bitrate_changed 回调返回当前可用带宽,设备端按目标码率调整编码分辨率和编码码率。画面持续卡顿时,要看 on_target_bitrate_changed 与实际编码码率是否跟上。
七. 信令不要省,Demo 也要有状态
音视频通了,呼叫流程还没有闭合。智能硬件还需要信令来处理设备在线、App 呼叫、设备接听、设备拒绝、任一端挂断、呼叫超时、设备忙碌和权限失效。这些状态不适合塞进音视频流里。
声网智能摄像头方案由 RTC SDK、RTSA Lite SDK 和 RTM SDK 1.x 共同搭建,其中 RTM SDK 1.x 用于可靠信令交互。第一版信令事件保留 device_online、call_invite、call_accept、call_reject、call_end、call_timeout。每个事件带上 callId、deviceId、channelId、timestamp。呼叫超时还要记录 timeoutMs、deviceOnlineState 和 App 前后台状态。
RTC 频道承担媒体传输,RTM 或业务信令承担状态同步。后面要做白名单、推送唤醒、未接提醒、云录制、多端同步,这条边界会省下不少排查成本。
八. 日志和质量监控从 Demo 开始接
智能硬件排查问题比纯 App 难。用户说听不到,可能是麦克风没采到、Token 过期、设备没联网、频道错了、App 没订阅、编码格式不对、云端没收到、扬声器静音。没有日志,只能靠猜。
Demo 阶段至少要有设备日志、服务端日志和 App 日志。设备日志记录采集、入会、发送、接收、重连和错误码;服务端日志记录 Token、频道、设备状态和呼叫状态;App 日志记录加入频道、远端流、播放状态和错误提示。
设备端日志保留 deviceId、firmwareVersion、chipModel、networkType、appId、channelId、deviceUid、rtcTokenExpireAt。App 和服务端日志保留 accountId、deviceId、callId、channelId、userUid、deviceUid、Token 签发时间、Token 过期时间、远端流订阅时间、挂断原因和错误码。
质量监控也要提前接入。首帧时间、入会成功率、断线重连次数、音频卡顿、视频卡顿、弱网下的恢复时间,都能帮团队判断第一版 Demo 到量产之间还差多少工作。
九. 从 Demo 到产品还要补业务能力
第一路音视频通话跑通后,产品化工作才开始。设备绑定和解绑要处理旧用户访问问题,家庭成员权限要处理多人管理问题,离线唤醒要处理设备不在线时的触达问题,云录制要处理保存、查看、删除和权限问题,隐私开关和未成年人保护要从产品设计阶段就进入方案。
不同硬件的重点也不同。儿童手表关注白名单、亲情号、弱网、功耗和定位状态。智能门铃关注离线唤醒、首帧时间、夜间画面、外放回声和陌生人权限。智能摄像头关注长期在线、码率自适应、多端查看、云录制和隐私遮蔽。AI 玩具和机器人还要接入 ASR、LLM、TTS、打断、降噪和内容安全。
声网在这条链路里承担实时音视频和实时互动底座。RTSA Lite SDK 面向设备端媒体流传输,RTC SDK 面向 App、Web、小程序等客户端音视频互通,RTM SDK 1.x 承担可靠信令交互。设备端音视频流稳定后,再接入对话式 AI 智能硬件方案,继续处理 ASR、LLM、TTS、打断编排和端侧日志。
正在做智能摄像头、门铃、儿童手表、AI 玩具、机器人等智能硬件,并计划把设备端音视频流接入 App、Web 或小程序的团队,联系声网专家团队,了解 RTSA Lite SDK、RTC SDK、RTM SDK 和对话式 AI 智能硬件方案的接入方式。