告警服务
在智慧养老、家庭安防、智能看护等场景中,通常需要智能设备对异常的声音、画面进行告警,监护者可以实时了解监护对象是否有危险并及时应对。声网灵隼提供告警服务,你可以在设备端触发告警事件,在客户端进行查询。
为满足用户的多种业务需求,增加告警内容组合的灵活性,声网灵隼提供如下三种告警内容组合:
- 纯告警消息
- 带图片的告警消息
- 带视频和视频封面图片的告警消息
本文介绍如何实现告警服务。
技术原理
参考如下数据流转图,了解声网灵隼的告警服务:
前提条件
实现流程
参考本节内容分别在设备端实现推送告警内容,在客户端实现查询告警内容。
设备端推送告警内容
根据实际需求,你可以在如下方式中任选一种:
-
推送纯告警消息:调用
agora_iot_push_alarm_message
方法,并将image_id
参数设置为空字符串(注意不是空指针)。 -
推送带图片的告警消息:先调用
agora_iot_push_alarm_image
方法,再调用agora_iot_push_alarm_message
方法,并将agora_iot_push_alarm_image
方法中返回的image_id
填入agora_iot_push_alarm_message
方法的image_id
参数。 -
推送带视频和视频封面图片的告警消息:调用
agora_iot_push_alarm_image
、agora_iot_push_alarm_message
和agora_iot_cloud_record_start
方法,并自行记录record_id
及image_id
,方便后续实现告警事件的通知、查询、过滤等操作。信息每个告警视频默认会持续录制 30 秒。如果你有更长的录制需求,请联系 sales@shengwang.cn。
参考如下示例代码,实现推送带视频和视频封面图片的告警消息:
static unsigned long long start_alarm_record(agora_iot_handle_t handle)
{
unsigned long long video_record_id = 0;
int result = -1;
// 1. 开始录制告警视频
struct timeval tv;
if (gettimeofday (&tv, NULL) < 0) {
printf("#### query system time failure\n");
return 0;
}
unsigned long long begin_time = (unsigned long long)((uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000);
result = agora_iot_cloud_record_start(handle, begin_time, begin_time + 60 * 1000,
SEND_AUDIO_DATA_TYPE, SEND_VIDEO_DATA_TYPE, &video_record_id);
if (0 != result) {
printf("#### start recording failure: %d\n", result);
return 0;
}
// 2. 推送告警图片,作为告警视频的封面图片
agora_iot_file_info_t file_info = {
.name_suffix = "jpeg",
.buf = WARNING_JPEG,
.size = sizeof(WARNING_JPEG)
};
char *image_id = NULL;
result = agora_iot_push_alarm_image(handle, &file_info, &image_id);
if (0 != result) {
printf("#### push alarm image failure: %d\n", result);
}
// 3. 推送告警消息
result = agora_iot_push_alarm_message(handle, begin_time, "dev_nickname", AG_ALARM_TYPE_VAD,
"This is a alarm test", image_id);
if (image_id) {
free(image_id);
image_id = NULL;
}
if (0 != result) {
printf("#### push alarm message failure: %d\n", result);
agora_iot_cloud_record_stop(handle, video_record_id, begin_time);
return 0;
}
return video_record_id;
}
如需停止录制,参考如下示例代码:
static int stop_alarm_record(agora_iot_handle_t handle, unsigned long long video_record_id)
{
if (video_record_id <= 0) {
printf("#### improper video record ID\n");
return -1;
}
struct timeval tv;
if (gettimeofday (&tv, NULL) < 0) {
printf("#### query system time failure\n");
return -1;
}
unsigned long long end_time = (unsigned long long)((uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000);
return agora_iot_cloud_record_stop(handle, video_record_id, end_time);
}
客户端查询告警内容
为增加查询的灵活性,声网灵隼在 Android 和 iOS API 中提供如下两组查询告警内容的方法:
- 同时查询所有告警内容:你可以通过
IAlarmMgr
类中的queryById
方法同时查询告警消息、告警图片和告警视频,并通过 onAlarmInfoQueryDone 回调获取查询结果。 - 分别查询某项告警内容:
- 告警消息:
IAlarmMgr
类中的queryByPage
。 - 告警图片:
IAlarmMgr
类中的queryImageById
。 - 告警视频:
IAlarmMgr
类中的queryVideoByTimestamp
。
实现查询告警消息、告警图片、告警视频的流程如下:
-
查询告警消息:进入告警消息中心页面时,调用
queryByPage
方法,查询指定过滤条件下的告警消息列表。 -
查询告警图片:调用
queryImageById
方法,获取告警图片的 URL。拉取告警图片数据,并渲染告警消息列表。声网推荐在本地缓存告警消息对应的image_id
和图片数据,以便在重复刷新页面数据时能更快地加载图片。 -
查询告警视频:在用户点击对应告警消息时,调用
queryVideoByTimestamp
方法,获取对应告警视频在云存储中的 URL,传入 HLS 播放器,从而在线播放告警视频。
告警事件与云存储中的视频通过告警上报的时间戳建立映射关系。客户端通过告警上报的时间戳向灵隼服务器查询告警消息,灵隼服务器再根据客户端查询到的时间戳定位对应告警视频,并返回该视频在云存储中的 URL,最后传入 HLS 播放器。
声网灵隼提供使用 GSYPlayer
实现 HLS 播放功能的示例项目。声网灵隼对 GSYPlayer
做了部分定制开发,在 HLS 播放器中支持了 G711、G722、OPUS 等音频编码格式,以及数据加密能力。为保障数据安全、降低开发成本,声网推荐你直接使用示例项目的相关代码实现通过 GSYPlayer 播放告警视频。部分示例代码如下:
if (data instanceof IotAlarm) {
currentIotAlarm = (IotAlarm) data;
setGsyPlayerInfo(((IotAlarm) data).mVideoUrl, "");
boolean muted;
if (mIsOrientLandscape) {
muted = !(getBinding().cbChangeSoundFull.isChecked());
} else {
muted = !(getBinding().cbChangeSound.isChecked());
}
getBinding().gsyPlayer.setMute(muted);
getBinding().gsyPlayer.startPlay();
getBinding().ivPlaying.post(() -> {
getBinding().ivPlaying.setSelected(true);
if (previewMessageAdapter.oldPlayPosition == -1) {
changePlayItem(0);
}
});
isPlaying = true;
}
开发注意事项
在开发过程中,你需要注意如下事项:
agora_iot_push_alarm_message
方法中begin_time
参数的取值需大于或等于agora_iot_cloud_record_start
方法中begin_time
参数的值,且小于agora_iot_cloud_record_stop
方法中end_time
参数的值。- 调用
agora_iot_cloud_record_start
方法后,如果你未调用agora_iot_cloud_record_stop
方法,则 SDK 会根据agora_iot_cloud_record_start
方法中end_time
参数来停止推送音视频帧。