# 告警服务 (/zh-CN/solutions/iot-apaas/build/customize-and-extend/alarm)

> For AI agents: see the complete documentation index at [llms.txt](/llms.txt).

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

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

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

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

## 技术原理 [#技术原理]

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

![告警服务技术原理](https://web-cdn.agora.io/docs-files/1668593163542)

## 前提条件 [#前提条件]

- 开通声网灵隼服务并创建一个产品。参考[开通声网灵隼服务](/zh-CN/solutions/iot-apaas/build/setup-and-access/enable-service)。
- 如需实现推送和查看带视频和视频封面图片的告警消息，你需要先参考[云存储服务](/zh-CN/solutions/iot-apaas/build/customize-and-extend/cloud-storage)开通并使用云存储服务。

## 实现流程 [#实现流程]

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

### 设备端推送告警内容 [#设备端推送告警内容]

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

 - 推送纯告警消息：调用 `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`，方便后续实现告警事件的通知、查询、过滤等操作。

   :::info[信息]
   每个告警视频默认会持续录制 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 播放器，从而在线播放告警视频。

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

声网灵隼提供使用 `GSYPlayer` 实现 HLS 播放功能的[示例项目](/zh-CN/solutions/iot-apaas/reference/downloads#示例项目)。声网灵隼对 `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` 参数来停止推送音视频帧。
<_PlatformProcessedMarker close="true" />

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

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

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

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

## 技术原理 [#技术原理-1]

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

![告警服务技术原理](https://web-cdn.agora.io/docs-files/1668593163542)

## 前提条件 [#前提条件-1]

- 开通声网灵隼服务并创建一个产品。参考[开通声网灵隼服务](/zh-CN/solutions/iot-apaas/build/setup-and-access/enable-service)。
- 如需实现推送和查看带视频和视频封面图片的告警消息，你需要先参考[云存储服务](/zh-CN/solutions/iot-apaas/build/customize-and-extend/cloud-storage)开通并使用云存储服务。

## 实现流程 [#实现流程-1]

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

### 设备端推送告警内容 [#设备端推送告警内容-1]

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

 - 推送纯告警消息：调用 `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`，方便后续实现告警事件的通知、查询、过滤等操作。

   :::info[信息]
   每个告警视频默认会持续录制 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);
}
```

### 客户端查询告警内容 [#客户端查询告警内容-1]

为增加查询的灵活性，声网灵隼在 Android 和 iOS API 中提供如下两组查询告警内容的方法：

- 同时查询所有告警内容：你可以通过 `IAlarmMgr` 类中的 `queryById` 方法同时查询告警消息、告警图片和告警视频，并通过 Android 的 `onAlarmInfoQueryDone` 回调或 iOS 中 `queryById` 的返回值获取查询结果。
- 分别查询某项告警内容：

- 告警消息：`IAlarmMgr` 类中的 `queryByParam`。
  - 告警图片：`IAlarmMgr` 类中的 `queryAlarmImage`。
  - 告警视频：`IAlarmMgr` 类中的 `queryAlarmVideoUrl`。

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

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

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

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

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

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

```swift
lazy var player:SJVideoPlayer = {

      let player = SJVideoPlayer()
      return player

 }()

func creatIjk(mediaUrl: String){

     let ijkVC : SJIJKMediaPlaybackController = SJIJKMediaPlaybackController()
     let options = IJKFFOptions.byDefault()
     ijkVC.options = options
     player.playbackController = ijkVC

     guard let url = URL(string: mediaUrl) else {
         return
     }

     player.urlAsset = SJVideoPlayerURLAsset(url: url)

 }
```

## 开发注意事项 [#开发注意事项-1]

在开发过程中，你需要注意如下事项：

- `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` 参数来停止推送音视频帧。
<_PlatformProcessedMarker close="true" />

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

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

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

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

## 技术原理 [#技术原理-2]

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

![告警服务技术原理](https://web-cdn.agora.io/docs-files/1668593163542)

## 前提条件 [#前提条件-2]

- 开通声网灵隼服务并创建一个产品。参考[开通声网灵隼服务](/zh-CN/solutions/iot-apaas/build/setup-and-access/enable-service)。
- 如需实现推送和查看带视频和视频封面图片的告警消息，你需要先参考[云存储服务](/zh-CN/solutions/iot-apaas/build/customize-and-extend/cloud-storage)开通并使用云存储服务。

## 实现流程 [#实现流程-2]

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

### 设备端推送告警内容 [#设备端推送告警内容-2]

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

 - 推送纯告警消息：调用 `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`，方便后续实现告警事件的通知、查询、过滤等操作。

   :::info[信息]
   每个告警视频默认会持续录制 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);
}
```

### 客户端查询告警内容 [#客户端查询告警内容-2]

为增加查询的灵活性，声网灵隼在 Android 和 iOS API 中提供如下两组查询告警内容的方法：

- 同时查询所有告警内容：你可以通过 `IAlarmMgr` 类中的 `queryById` 方法同时查询告警消息、告警图片和告警视频，并通过 Android 的 `onAlarmInfoQueryDone` 回调或 iOS 中 `queryById` 的返回值获取查询结果。
- 分别查询某项告警内容：

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

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

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

## 开发注意事项 [#开发注意事项-2]

在开发过程中，你需要注意如下事项：

- `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` 参数来停止推送音视频帧。
<_PlatformProcessedMarker close="true" />
</_PlatformTabsGroup>
