告警服务

  • Android

更新时间不可用

了解灵隼物联网云平台在不同平台上的告警服务方式,包括接入流程、关键配置和平台差异。

在智慧养老、家庭安防、智能看护等场景中,通常需要智能设备对异常的声音、画面进行告警,监护者可以实时了解监护对象是否有危险并及时应对。声网灵隼提供告警服务,你可以在设备端触发告警事件,在客户端进行查询。

为满足用户的多种业务需求,增加告警内容组合的灵活性,声网灵隼提供如下三种告警内容组合:

  • 纯告警消息
  • 带图片的告警消息
  • 带视频和视频封面图片的告警消息

本文介绍如何实现告警服务。

技术原理

参考如下数据流转图,了解声网灵隼的告警服务:

前提条件

  • 开通声网灵隼服务并创建一个产品。参考开通声网灵隼服务。
  • 如需实现推送和查看带视频和视频封面图片的告警消息,你需要先参考云存储服务开通并使用云存储服务。

实现流程

参考本节内容分别在设备端实现推送告警内容,在客户端实现查询告警内容。

设备端推送告警内容

根据实际需求,你可以在如下方式中任选一种:

  • 推送纯告警消息:调用 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。

参考如下示例代码,实现推送带视频和视频封面图片的告警消息:

C
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;
}

如需停止录制,参考如下示例代码:

C
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 方法同时查询告警消息、告警图片和告警视频,并通过 Android 的 onAlarmInfoQueryDone 回调或 iOS 中 queryById 的返回值获取查询结果。

  • 分别查询某项告警内容:

  • 告警消息:IAlarmMgr 类中的 queryByPage。

    • 告警图片:IAlarmMgr 类中的 queryImageById。
    • 告警视频:IAlarmMgr 类中的 queryVideoByTimestamp。

实现查询告警消息、告警图片、告警视频的流程如下:

  1. 查询告警消息:进入告警消息中心页面时,调用 queryByPage 方法,查询指定过滤条件下的告警消息列表。

  2. 查询告警图片:调用 queryImageById 方法,获取告警图片的 URL。拉取告警图片数据,并渲染告警消息列表。声网推荐在本地缓存告警消息对应的 image_id 和图片数据,以便在重复刷新页面数据时能更快地加载图片。

  3. 查询告警视频:在用户点击对应告警消息时,调用 queryVideoByTimestamp 方法,获取对应告警视频在云存储中的 URL,传入 HLS 播放器,从而在线播放告警视频。

    信息

    告警事件与云存储中的视频通过告警上报的时间戳建立映射关系。客户端通过告警上报的时间戳向灵隼服务器查询告警消息,灵隼服务器再根据客户端查询到的时间戳定位对应告警视频,并返回该视频在云存储中的 URL,最后传入 HLS 播放器。

声网灵隼提供使用 GSYPlayer 实现 HLS 播放功能的示例项目。声网灵隼对 GSYPlayer 做了部分定制开发,在 HLS 播放器中支持了 G711、G722、OPUS 等音频编码格式,以及数据加密能力。为保障数据安全、降低开发成本,声网推荐你直接使用示例项目的相关代码实现通过 GSYPlayer 播放告警视频。部分示例代码如下:

Java
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 参数来停止推送音视频帧。