构建智能摄像头场景
本文介绍智能摄像头场景的构建流程。
前提条件
智能摄像头场景中,设备端使用了 RTSA Lite SDK,客户端使用了 RTC SDK,点击如下链接查看相关开发环境要求:
构建流程
构建智能摄像头场景的基本流程如下:
- 建立呼叫:客户端和设备端建立音视频数据传输通道。
- 加入频道:设备端使用 RTSA Lite SDK 加入频道,客户端使用 RTC SDK 加入频道。
- 采集和发送数据:客户端和设备端分别采集数据并发送给对方。
- 接收数据:客户端和设备端分别接收对方的数据。
智能摄像头场景支持客户端和设备端双向呼叫、双向音频传输,本节以单向呼叫和传输为例,介绍客户端向设备端发送呼叫、设备端采集音视频并发送给客户端的基本流程。
如无特别说明,本节的设备端示例代码为 C 语言,客户端示例代码为 Java 语言。你也可以通过 RTSA Lite SDK 实现流程和 RTC SDK 实现流程文档查看其他语言的示例代码。
1. 建立呼叫
在呼叫建立过程中,客户端可以通过绑定的账号呼叫设备端,流程图如下:
你可以通过以下步骤在自己的业务后台实现呼叫:
- 注册账号。由客户端发起注册,一般会有账号、手机号、邮箱号等注册项。你的业务后台收到注册请求后,可以在后台数据库中存储满足要求的用户账号信息。
- 绑定设备。在你的业务后台中建立设备与账号的映射关系。每个智能摄像头设备都有唯一的设备序列号,设备开机配网后,会与业务后台维持长连接。因此,业务后台可以根据设备序列号找到这台设备。
- 发起呼叫。业务后台根据主叫方账号,从后台数据库中找到与其绑定的设备 ID。同时业务后台会分配此次通话的 RTC 频道 ID、主叫用户 ID、被叫用户 ID 和对应的 RTC Token,分别下发至客户端和设备端。这些参数都是后续客户端使用的声网 RTC SDK 和设备端使用的 RTSA Lite SDK 加入频道所需要的。
你需要在业务后台自行实现以下内容:
- 注册账号与绑定设备的相关逻辑。
- Token 生成器,用于生成 RTC Token。实现方法详见使用 RTC Token 鉴权。
2. 加入频道
设备端和客户端收到业务后台下发的 RTC 频道 ID、主叫用户 ID、被叫用户 ID、RTC Token 等参数后,分别调用如下方法加入频道:
-
设备端调用 RTSA Lite SDK 中的
agora_rtc_join_channel
加入 RTC 频道。Crval = agora_rtc_join_channel(g_conn_id, CHANNEL_NAME, CALLEE_UID, TOKEN, &channel_options);
if (rval < 0) {
printf("Failed to join channel \"%s\", reason: %s\n", CHANNEL_NAME, agora_rtc_err_2_str(rval));
return -1;
} -
客户端调用 RTC SDK 中的
joinChannel
加入 RTC 频道。JavaChannelMediaOptions options = new ChannelMediaOptions();
// 将用户角色设置为 BROADCASTER 。
options.clientRoleType = Constants.CLIENT_ROLE_BROADCASTER;
// 设置频道场景为 BROADCASTING。
options.channelProfile = Constants.CHANNEL_PROFILE_LIVE_BROADCASTING;
// 使用 RTC Token 加入频道。
// 你需要自行指定用户 ID,并确保其在频道内的唯一性。
mRtcEngine.joinChannel(token, channelName, 0, options);注意集成 RTC SDK 时,请确保频道场景设为直播,用户角色设为主播。
3. 采集和发送数据
成功加入频道后,设备端会收到 on_join_channel_success
回调,此时就可以调用 agora_rtc_send_audio_data
和 agora_rtc_send_video_data
方法发送音视频。详细使用步骤参考传输媒体流。
4. 接收数据
成功加入频道后,客户端会收到 onJoinChannelSuccess
回调并自动接收设备端的音视频。
在传输指定格式的音视频数据时,RTSA Lite SDK 与 RTC SDK 可以实现互通。详见与 RTC SDK 互通数据。
5. 其他设置
发送关键帧
设备端发送的数据可以为编码后的码流文件(比如 h.264 或 Opus)或 PCM 文件。在客户端出现解码错误或频道里加入新终端时,SDK 内部会请求发送关键帧。你需要在设备端通过 on_key_frame_gen_req
回调通知 App,App 需要根据回调立即指示编码器编码 I 帧并发送给客户端,否则可能出现长时间的卡顿、黑屏等问题。详见发送关键帧。
根据带宽调节目标码率
摄像头一般会支持多个清晰度档位,如标清、高清、超高清、4K 等,常见帧率包括 15 fps 和 25 fps。
你可以通过 agora_rtc_set_bwe_param
方法设置 BWE (bandwidth estimation) 参数。
BWE 参数表示网络带宽探测的边界,你可以根据场景要求,预测编码码率可能的最大最小波动范围并设置。
档位 | 分辨率 | 帧率 | 码率范围(kbps) |
---|---|---|---|
标清 | L1: 640 × 360 | 15 | [400,800] |
高清 | L2: 1280 × 720 | 15 | [1130,2260] |
超高清 | L3: 1920 × 1080 | 15 | [1130,4160] |
如上表中配置情况,可设置最小值 400 kbps,最大值 4160 kbps。初始值是带宽探测的初始回调值,实际设置介于最小值和最大值中间,一般设置为正常情况编码的码率。如果初始编码档位为上表的标清档,初始值可设为 500 kbps。
设备端会持续探测可用带宽,通过 on_target_bitrate_changed
回调告知 App 当前的可用带宽,设备端需要做码率跟随,避免超码率发送,引起卡顿等问题。示例处理方法如下:
// 配置 BWE
uint32_t min_bps = 400000;
uint32_t max_bps = 4160000;
uint32_t start_bps = 500000;
agora_rtc_set_bwe_param(min_bps, max_bps, start_bps);
// 通知设备端做码率跟随
static void __on_target_bitrate_changed(const char *channel, uint32_t target_bps)
{
// 当前码率按照 100 K 分档,向下取整
curTargetBitrate = target_bps/100000 * 100;
diffTargetBitrate = abs(curTargetBitRate - lastTargetBitrate);
// 如果探测带宽与设置的编码码率相差 100 K 以上,则重写调整编码参数
if ( (diffTargetBitrate >= 100 ) && (lowBitrateL1 < curTargetBitrate < highBitrateL3) )
{
if (lowBitrateL1 < curTargetBitrate < highBitrateL1)
{
curResolutionLevel = L1;
}
else if (lowBitrateL2 < curTargetBitrate < highBitrateL2)
{
curResolutionLevel = L3;
}
else
{}
// 调整编码分辨率
if (curResolutionLevel != lastResolutionLevel)
{
setEncodeResolution(curResolutionLevel);
}
// 设置编码码率
setEncodeBitrate(curTargetBitrate);
lastResolutionLevel = curResolutionLevel;
lastTargetBitrate = curTargetBitrate;
}
}
开发注意事项
在开发过程中,你需要注意如下事项:
-
RTC SDK、RTSA Lite SDK 和你的 Token 生成器必须使用相同的 App ID,否则无法互通。
-
对于 RTSA Lite SDK,两人互通需采用
on_audio_data
回调接收数据;3 人以上互通需要用on_mixed_audio_data
回调接收数据。