Initial_commit_SecMPS_v2
This commit is contained in:
594
owl_api_research.md
Normal file
594
owl_api_research.md
Normal file
@@ -0,0 +1,594 @@
|
||||
# Owl(GoWVP)开源视频监控管理平台 API 调研报告
|
||||
|
||||
> 调研目标:为 Vol.Pro 后端对接 Owl 提供技术方案依据
|
||||
> 仓库地址:https://github.com/gowvp/owl
|
||||
> 调研日期:2026-05-06
|
||||
|
||||
---
|
||||
|
||||
## 一、API 认证方式
|
||||
|
||||
Owl 采用 **JWT Token** 认证机制,所有业务 API(除登录、健康检查、Webhook 回调外)均需在请求头中携带 Token。
|
||||
|
||||
### 1.1 登录获取 Token
|
||||
|
||||
- **URL**: `POST /login`
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"data": "<RSA加密后的JSON字符串>"
|
||||
}
|
||||
```
|
||||
- 加密前内容示例:`{"username":"admin","password":"admin"}`
|
||||
- 公钥获取:`GET /login/key`,返回 Base64 编码的 RSA 公钥(PEM 格式)
|
||||
- **响应示例**:
|
||||
```json
|
||||
{
|
||||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"user": "admin"
|
||||
}
|
||||
```
|
||||
- **Token 有效期**: 3 天
|
||||
- **使用方式**: 请求头携带 `Authorization: Bearer <token>`
|
||||
|
||||
### 1.2 修改凭据
|
||||
|
||||
- **URL**: `PUT /users`
|
||||
- **说明**: 需先校验旧密码,同样使用 RSA 加密传输
|
||||
|
||||
---
|
||||
|
||||
## 二、设备管理 API
|
||||
|
||||
> 设备类型支持:`GB28181`、`ONVIF`、`RTMP`、`RTSP`
|
||||
|
||||
### 2.1 设备列表查询
|
||||
|
||||
- **URL**: `GET /devices`
|
||||
- **认证**: 需 JWT
|
||||
- **请求参数** (Query):
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `page` | int | 页码,默认 1 |
|
||||
| `size` | int | 每页大小 |
|
||||
| `key` | string | 关键词模糊搜索(名称/国标编号) |
|
||||
- **响应**:
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": "gb_34020000001320000001",
|
||||
"type": "GB28181",
|
||||
"device_id": "34020000001320000001",
|
||||
"name": "NVR-01",
|
||||
"transport": "UDP",
|
||||
"stream_mode": 1,
|
||||
"ip": "192.168.1.100",
|
||||
"port": 5060,
|
||||
"is_online": true,
|
||||
"registered_at": "2026-05-06T10:00:00Z",
|
||||
"keepalive_at": "2026-05-06T10:05:00Z",
|
||||
"keepalives": 30,
|
||||
"expires": 3600,
|
||||
"channels": 4,
|
||||
"address": "192.168.1.100:5060",
|
||||
"password": "",
|
||||
"username": "",
|
||||
"ext": {}
|
||||
}
|
||||
],
|
||||
"total": 100
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 设备详情
|
||||
|
||||
- **URL**: `GET /devices/:id`
|
||||
- **响应**: 单条 Device 对象(同上)
|
||||
|
||||
### 2.3 添加设备
|
||||
|
||||
- **URL**: `POST /devices`
|
||||
- **认证**: 需 JWT
|
||||
- **请求体**:
|
||||
```json
|
||||
// GB28181 设备
|
||||
{
|
||||
"type": "GB28181",
|
||||
"device_id": "34020000001320000001",
|
||||
"name": "摄像头1",
|
||||
"password": "123456"
|
||||
}
|
||||
|
||||
// ONVIF 设备
|
||||
{
|
||||
"type": "ONVIF",
|
||||
"ip": "192.168.1.100",
|
||||
"port": 80,
|
||||
"username": "admin",
|
||||
"password": "12345",
|
||||
"name": "ONVIF摄像头"
|
||||
}
|
||||
```
|
||||
- **说明**: GB28181 设备实际注册靠设备主动 SIP 注册,此接口用于预录入设备信息
|
||||
|
||||
### 2.4 修改设备
|
||||
|
||||
- **URL**: `PUT /devices/:id`
|
||||
- **请求体** (`EditDeviceInput`):
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `device_id` | string | 20 位国标编号 |
|
||||
| `name` | string | 设备名称 |
|
||||
| `password` | string | 注册密码 |
|
||||
| `stream_mode` | int | 0:UDP, 1:TCP_PASSIVE, 2:TCP_ACTIVE |
|
||||
| `username` | string | ONVIF 用户名 |
|
||||
| `ip` | string | ONVIF IP |
|
||||
| `port` | int | ONVIF 端口 |
|
||||
|
||||
### 2.5 删除设备
|
||||
|
||||
- **URL**: `DELETE /devices/:id`
|
||||
|
||||
### 2.6 查询设备目录(刷新通道)
|
||||
|
||||
- **URL**: `POST /devices/:id/catalog`
|
||||
- **说明**: 向 GB28181 设备发送 Catalog 查询指令,拉取通道列表
|
||||
- **响应**: `{"msg": "ok"}`(异步执行)
|
||||
|
||||
### 2.7 ONVIF 设备发现
|
||||
|
||||
- **URL**: `GET /onvif/discover`
|
||||
- **说明**: SSE 流式返回发现的 ONVIF 设备
|
||||
|
||||
---
|
||||
|
||||
## 三、通道管理 API
|
||||
|
||||
### 3.1 通道列表查询
|
||||
|
||||
- **URL**: `GET /channels`
|
||||
- **认证**: 需 JWT
|
||||
- **请求参数** (Query):
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `page` | int | 页码 |
|
||||
| `size` | int | 每页大小 |
|
||||
| `did` | string | 父设备 ID |
|
||||
| `device_id` | string | 国标编码 |
|
||||
| `key` | string | 名称/国标编码模糊搜索,ID 精确搜索 |
|
||||
| `is_online` | string | 是否在线过滤 |
|
||||
| `type` | string | 通道类型:GB28181/ONVIF/RTMP/RTSP |
|
||||
| `app` | string | 应用名 |
|
||||
| `stream` | string | 流 ID |
|
||||
- **响应**:
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": "gb_34020000001320000001_34020000001320000001",
|
||||
"did": "gb_34020000001320000001",
|
||||
"device_id": "34020000001320000001",
|
||||
"channel_id": "34020000001320000001",
|
||||
"name": "通道01",
|
||||
"ptztype": 1,
|
||||
"is_online": true,
|
||||
"is_playing": false,
|
||||
"type": "GB28181",
|
||||
"app": "rtp",
|
||||
"stream": "gb_34020000001320000001_34020000001320000001",
|
||||
"has_recording": true,
|
||||
"config": {}
|
||||
}
|
||||
],
|
||||
"total": 100
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 设备与通道关联列表
|
||||
|
||||
- **URL**: `GET /devices/channels`
|
||||
- **说明**: 返回设备列表,每个设备包含 `children`(通道数组),并按在线状态排序
|
||||
- **响应**:
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": "gb_xxx",
|
||||
"name": "NVR-01",
|
||||
"is_online": true,
|
||||
"children": [
|
||||
{
|
||||
"id": "gb_xxx_xxx",
|
||||
"name": "通道01",
|
||||
"is_online": true,
|
||||
"has_recording": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"total": 10
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 添加通道(RTMP/RTSP)
|
||||
|
||||
- **URL**: `POST /channels`
|
||||
- **请求体** (`AddChannelInput`):
|
||||
```json
|
||||
{
|
||||
"type": "RTMP",
|
||||
"name": "推流通道1",
|
||||
"device_id": "",
|
||||
"device_name": "",
|
||||
"app": "live",
|
||||
"stream": "stream01",
|
||||
"config": {
|
||||
"is_auth_disabled": false,
|
||||
"session": "",
|
||||
"media_server_id": "",
|
||||
"push_addr": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 修改通道
|
||||
|
||||
- **URL**: `PUT /channels/:id`
|
||||
- **请求体** (`EditChannelInput`):
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `device_id` | string | 国标编码 |
|
||||
| `name` | string | 通道名称 |
|
||||
| `ptztype` | int | 云台类型 |
|
||||
| `is_online` | bool | 是否在线 |
|
||||
| `ext` | object | 扩展属性 |
|
||||
| `app` | string | 应用名(RTMP/RTSP) |
|
||||
| `stream` | string | 流 ID |
|
||||
| `config` | StreamConfig | 流配置 |
|
||||
|
||||
### 3.5 删除通道
|
||||
|
||||
- **URL**: `DELETE /channels/:id`
|
||||
- **限制**: 仅允许删除 RTMP/RTSP 类型通道
|
||||
|
||||
---
|
||||
|
||||
## 四、实时流地址获取 API
|
||||
|
||||
### 4.1 获取播放地址
|
||||
|
||||
- **URL**: `POST /channels/:id/play`
|
||||
- **认证**: 需 JWT
|
||||
- **说明**: 根据通道类型自动处理拉流逻辑
|
||||
- **GB28181**: Owl 通过 SIP 邀请设备推流到 ZLM,自动开启 RTP Server
|
||||
- **RTMP**: 检查是否已推流,直接从 ZLM 获取播放地址
|
||||
- **RTSP**: 通过 ZLM 添加流代理(AddStreamProxy),再返回地址
|
||||
- **ONVIF**: 直接从 ZLM 获取播放地址
|
||||
- **响应** (`playOutput`):
|
||||
```json
|
||||
{
|
||||
"app": "rtp",
|
||||
"stream": "gb_34020000001320000001_34020000001320000001",
|
||||
"items": [
|
||||
{
|
||||
"label": "ZLM",
|
||||
"ws_flv": "ws://host:port/proxy/sms/rtp/gb_xxx.live.flv",
|
||||
"http_flv": "http://host:port/proxy/sms/rtp/gb_xxx.live.flv",
|
||||
"rtmp": "rtmp://host:port/rtp/gb_xxx",
|
||||
"rtsp": "rtsp://host:port/rtp/gb_xxx",
|
||||
"webrtc": "webrtc://host:port/proxy/sms/index/api/webrtc?app=rtp&stream=gb_xxx&type=play",
|
||||
"hls": "http://host:port/proxy/sms/rtp/gb_xxx/hls.fmp4.m3u8"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 停止播放
|
||||
|
||||
- **URL**: `POST /channels/:id/stop`
|
||||
- **说明**: 幂等操作,始终返回成功
|
||||
- GB28181: 发送 SIP BYE + 关闭 ZLM RTP Server
|
||||
- ONVIF/RTSP/RTMP: 调用 ZLM `close_streams` 关闭流
|
||||
- **响应**: `{"msg": "ok"}`
|
||||
|
||||
### 4.3 快照相关
|
||||
|
||||
- **刷新快照**: `POST /channels/:id/snapshot`
|
||||
- 请求体可指定 `within_seconds`(秒内有效则返回缓存)和 `url`(指定取流地址)
|
||||
- 响应: `{"link": "http://host/channels/:id/snapshot?token=xxx"}`
|
||||
- **获取快照图片**: `GET /channels/:id/snapshot?token=xxx`
|
||||
- 直接返回 JPEG 图片流
|
||||
|
||||
---
|
||||
|
||||
## 五、回放流地址获取 API(云录像)
|
||||
|
||||
Owl 的录像回放功能由 Owl 自身管理(非设备 SD 卡录像),底层依赖 ZLM 的 MP4 录制。
|
||||
|
||||
### 5.1 查询录像列表
|
||||
|
||||
- **URL**: `GET /recordings`
|
||||
- **认证**: 需 JWT
|
||||
- **请求参数** (Query):
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `page` | int | 页码 |
|
||||
| `size` | int | 每页大小 |
|
||||
| `cid` | string | 通道 ID |
|
||||
| `app` | string | 应用名 |
|
||||
| `stream` | string | 流 ID |
|
||||
| `start_ms` | int64 | 开始时间戳(毫秒) |
|
||||
| `end_ms` | int64 | 结束时间戳(毫秒) |
|
||||
- **响应**:
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"cid": "gb_xxx_xxx",
|
||||
"app": "rtp",
|
||||
"stream": "gb_xxx_xxx",
|
||||
"started_at": "2026-05-06T10:00:00Z",
|
||||
"ended_at": "2026-05-06T10:05:00Z",
|
||||
"duration": 300.5,
|
||||
"path": "/recordings/rtp/gb_xxx_xxx/20260506/xxx.mp4",
|
||||
"size": 10485760
|
||||
}
|
||||
],
|
||||
"total": 50
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 获取时间轴
|
||||
|
||||
- **URL**: `GET /recordings/timeline?cid=xxx&start_ms=xxx&end_ms=xxx`
|
||||
- **响应**:
|
||||
```json
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"start_ms": 1714982400000,
|
||||
"end_ms": 1714982700000,
|
||||
"duration": 300.5
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 5.3 获取月度统计
|
||||
|
||||
- **URL**: `GET /recordings/monthly?cid=xxx&year=2026&month=5`
|
||||
- **响应**:
|
||||
```json
|
||||
{
|
||||
"year": 2026,
|
||||
"month": 5,
|
||||
"days": 31,
|
||||
"has_video": "101010..." // 每天是否有录像,'1'有/'0'无
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 HLS 回放播放
|
||||
|
||||
- **URL**: `GET /recordings/channels/:cid/index.m3u8?start_ms=xxx&end_ms=xxx&token=xxx`
|
||||
- **说明**: 动态生成 m3u8 播放列表,将指定时间范围内的多个 MP4 片段拼接为 HLS (VOD)
|
||||
- **Content-Type**: `application/vnd.apple.mpegurl`
|
||||
|
||||
### 5.5 下载录像
|
||||
|
||||
- **URL**: `GET /recordings/:id/download`
|
||||
- **说明**: 返回 MP4 文件流,支持 HTTP Range 请求(边下载边播放)
|
||||
|
||||
### 5.6 静态文件播放
|
||||
|
||||
- **URL**: `GET /static/recordings/{path}?token=xxx`
|
||||
- **说明**: 直接访问 MP4/fMP4 文件,同样支持 Range 请求
|
||||
|
||||
---
|
||||
|
||||
## 六、云台控制 API
|
||||
|
||||
### 6.1 PTZ 控制
|
||||
|
||||
- **URL**: `POST /channels/:id/ptz/control`
|
||||
- **认证**: 需 JWT
|
||||
- **请求体** (`ptzControlInput`):
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `action` | string | 是 | 动作类型:`continuous` / `stop` / `absolute` / `relative` / `preset` |
|
||||
| `direction` | string | 否 | 方向(continuous 时用):`up` / `down` / `left` / `right` / `zoom_in` / `zoom_out` |
|
||||
| `speed` | float64 | 否 | 速度 0-1 |
|
||||
| `x` | float64 | 否 | X 轴位置(absolute/relative) |
|
||||
| `y` | float64 | 否 | Y 轴位置 |
|
||||
| `zoom` | float64 | 否 | 缩放值 |
|
||||
| `preset_id` | string | 否 | 预置位 ID |
|
||||
| `preset_op` | string | 否 | 预置位操作:`goto` / `set` / `remove` |
|
||||
- **当前实现限制**: 代码中**仅实现了 `continuous` 和 `stop`**,其他动作类型会返回错误
|
||||
- **响应**:
|
||||
```json
|
||||
{
|
||||
"msg": "PTZ 控制指令已发送"
|
||||
}
|
||||
```
|
||||
- **注意**: 目前代码中直接调用 GB28181 Server 的 PTZControl 方法,未区分协议类型(ONVIF PTZ 支持标记为 TODO)
|
||||
|
||||
---
|
||||
|
||||
## 七、设备状态查询 API
|
||||
|
||||
### 7.1 在线状态
|
||||
|
||||
Owl 没有单独的"设备状态查询"接口,设备状态包含在设备/通道列表查询中:
|
||||
|
||||
- **设备在线状态**: `GET /devices` 或 `GET /devices/:id` → `is_online`
|
||||
- **通道在线状态**: `GET /channels` 或 `GET /devices/channels` → `is_online`
|
||||
- **通道播放状态**: `is_playing`
|
||||
|
||||
### 7.2 设备模型关键状态字段
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `is_online` | 是否在线(SIP 注册成功且心跳正常) |
|
||||
| `registered_at` | 最近一次注册时间 |
|
||||
| `keepalive_at` | 最近一次心跳时间 |
|
||||
| `keepalives` | 心跳间隔(秒) |
|
||||
| `expires` | 注册有效期(秒) |
|
||||
| `address` | 设备网络地址(如 `192.168.1.100:5060`) |
|
||||
| `transport` | 信令传输协议(`UDP` / `TCP`) |
|
||||
| `channels` | 通道数量 |
|
||||
|
||||
### 7.3 注册与心跳机制(SIP 层)
|
||||
|
||||
- **注册**: GB28181 设备主动向 Owl 的 SIP 端口(默认 5060)发送 REGISTER 请求
|
||||
- Owl 支持 Digest 鉴权,密码可设备单独配置或使用全局默认密码
|
||||
- 注册成功后 Owl 自动查询 DeviceInfo 和 Catalog
|
||||
- **心跳**: 设备按 `Keepalives` 间隔发送 MESSAGE 心跳
|
||||
- Owl 通过 `keepalive_at` 和 `expires` 判断设备是否离线
|
||||
- 例如:设备侧超时 3 秒 × 3 次,则约 9+x 秒收不到心跳认为离线
|
||||
- **注销**: 设备发送 Expires=0 的 REGISTER 请求
|
||||
|
||||
> **重要**: 注册和心跳是 **SIP 协议层**自动完成的,没有对应的 HTTP API。Vol.Pro 只需通过 HTTP API 查询设备列表即可获知在线状态。
|
||||
|
||||
---
|
||||
|
||||
## 八、Owl 与 ZLMediaKit 联动机制
|
||||
|
||||
### 8.1 架构关系
|
||||
|
||||
```
|
||||
摄像机/NVR --(SIP/RTP)--> Owl --(HTTP API/Webhook)--> ZLMediaKit
|
||||
^
|
||||
| (反向代理播放)
|
||||
前端播放器 --(HTTP/WebSocket)---> Owl /proxy/sms/xxx
|
||||
```
|
||||
|
||||
### 8.2 Owl 配置 ZLM 的 Hook 回调
|
||||
|
||||
Owl 启动时会自动连接 ZLM,并通过 `SetServerConfig` 接口设置以下 Webhook 地址(前缀为 `http://{owl_host}:{owl_port}/webhook`):
|
||||
|
||||
| Hook 接口 | 方法 | 说明 |
|
||||
|-----------|------|------|
|
||||
| `/webhook/on_server_started` | POST | ZLM 启动时触发,Owl 将所有 RTMP 通道置为离线 |
|
||||
| `/webhook/on_server_keepalive` | POST | ZLM 定时保活(默认 10s),Owl 更新节点在线状态 |
|
||||
| `/webhook/on_publish` | POST | 推流鉴权(RTMP/RTSP/RTP),Owl 校验是否允许推流 |
|
||||
| `/webhook/on_play` | POST | 播放鉴权,Owl 更新通道播放状态为 playing |
|
||||
| `/webhook/on_stream_changed` | POST | 流注册/注销时触发,Owl 根据录像模式决定是否启动录制 |
|
||||
| `/webhook/on_stream_none_reader` | POST | 无人观看时触发,Owl 根据录像模式决定是否关闭流 |
|
||||
| `/webhook/on_stream_not_found` | POST | 播放不存在的流时触发,Owl 触发按需拉流(ONVIF/RTSP) |
|
||||
| `/webhook/on_rtp_server_timeout` | POST | RTP Server 超时未收到数据 |
|
||||
| `/webhook/on_record_mp4` | POST | MP4 切片录制完成,Owl 将录像信息入库 |
|
||||
|
||||
### 8.3 Owl 调用 ZLM 的 API
|
||||
|
||||
通过 `internal/core/sms/driver_zlm.go` 封装调用:
|
||||
|
||||
| ZLM API | Owl 封装方法 | 说明 |
|
||||
|---------|-------------|------|
|
||||
| `openRtpServer` | `OpenRTPServer` | 开启 RTP 收流端口(GB28181 用) |
|
||||
| `closeRtpServer` | `CloseRTPServer` | 关闭 RTP 端口 |
|
||||
| `close_streams` | `CloseStreams` | 强制关闭流 |
|
||||
| `addStreamProxy` | `AddStreamProxy` | 添加 RTSP 拉流代理 |
|
||||
| `getSnap` | `GetSnapshot` | 获取流截图 |
|
||||
| `startRecord` | `StartRecord` | 开始 MP4 录制 |
|
||||
| `stopRecord` | `StopRecord` | 停止 MP4 录制 |
|
||||
| `getServerConfig` | `GetServerConfig` | 获取配置(含端口信息) |
|
||||
| `setServerConfig` | `SetServerConfig` | 设置配置(含 Hook 地址) |
|
||||
| `restartServer` | `RestartServer` | 重启 ZLM(rtc 端口变更时) |
|
||||
|
||||
### 8.4 播放地址生成规则
|
||||
|
||||
Owl 通过反向代理 `/proxy/sms/*path` 将所有播放请求转发到 ZLM,前端无需直接访问 ZLM。
|
||||
|
||||
生成逻辑(`GetStreamLiveAddr`):
|
||||
|
||||
| 协议 | URL 格式示例 |
|
||||
|------|-------------|
|
||||
| **WS-FLV** | `ws://owl_host/proxy/sms/{app}/{stream}.live.flv` |
|
||||
| **HTTP-FLV** | `http://owl_host/proxy/sms/{app}/{stream}.live.flv` |
|
||||
| **HLS(fMP4)** | `http://owl_host/proxy/sms/{app}/{stream}/hls.fmp4.m3u8` |
|
||||
| **WebRTC** | `webrtc://owl_host/proxy/sms/index/api/webrtc?app={app}&stream={stream}&type=play` |
|
||||
| **RTMP** | `rtmp://owl_host:1935/{app}/{stream}` |
|
||||
| **RTSP** | `rtsp://owl_host:554/{app}/{stream}` |
|
||||
|
||||
### 8.5 联动流程示例(GB28181 实时播放)
|
||||
|
||||
1. 前端调用 `POST /channels/:id/play`
|
||||
2. Owl 向 ZLM 调用 `openRtpServer` 开启 UDP/TCP 收流端口
|
||||
3. Owl 通过 SIP 发送 INVITE 给设备,SDP 中携带 ZLM 的收流地址
|
||||
4. 设备通过 RTP 向 ZLM 推流
|
||||
5. ZLM 触发 `on_publish` → `on_stream_changed` Hook
|
||||
6. Owl 返回包含播放地址的 JSON 给前端
|
||||
7. 前端通过 `/proxy/sms/...` 播放流
|
||||
8. 无人观看时,ZLM 触发 `on_stream_none_reader`
|
||||
9. Owl 判断无需录像 → 返回 `Close: true` → ZLM 关闭流
|
||||
10. Owl 发送 SIP BYE 结束会话
|
||||
|
||||
---
|
||||
|
||||
## 九、其他相关 API
|
||||
|
||||
### 9.1 流媒体服务器管理
|
||||
|
||||
- `GET /media_servers` - 查询媒体服务器列表
|
||||
- `PUT /media_servers/:id` - 修改媒体服务器配置
|
||||
|
||||
### 9.2 推流管理
|
||||
|
||||
- `GET /stream_pushs` - 查询推流列表(含 RTMP 推流地址)
|
||||
- `POST /stream_pushs` - 添加推流
|
||||
- `PUT /stream_pushs/:id` - 修改推流
|
||||
- `DELETE /stream_pushs/:id` - 删除推流
|
||||
|
||||
### 9.3 事件/告警管理
|
||||
|
||||
- `GET /events` - 分页查询 AI 检测事件
|
||||
- `GET /events/:id` - 事件详情
|
||||
- `GET /events/image/*path` - 获取事件快照图片(无需认证)
|
||||
|
||||
### 9.4 配置管理
|
||||
|
||||
- `GET /configs/info` - 获取 SIP 等配置信息
|
||||
- `PUT /configs/info/sip` - 修改 SIP 配置
|
||||
|
||||
### 9.5 系统接口
|
||||
|
||||
- `GET /health` - 健康检查
|
||||
- `GET /app/metrics/api` - API 实时监控指标
|
||||
- `GET /app/version/check` - 检查新版本
|
||||
|
||||
---
|
||||
|
||||
## 十、Vol.Pro 对接建议
|
||||
|
||||
### 10.1 对接方式
|
||||
|
||||
Vol.Pro 后端直接通过 **HTTP REST API** 调用 Owl,无需处理 SIP 协议。
|
||||
|
||||
### 10.2 关键对接流程
|
||||
|
||||
```
|
||||
1. 登录 Owl → 获取 JWT Token(缓存)
|
||||
2. 定时同步设备列表 → GET /devices
|
||||
3. 定时同步通道列表 → GET /channels 或 GET /devices/channels
|
||||
4. 用户点击播放 → POST /channels/:id/play → 获取播放地址 → 前端播放
|
||||
5. 用户停止播放 → POST /channels/:id/stop
|
||||
6. 回放查询 → GET /recordings?cid=xxx&start_ms=xxx&end_ms=xxx
|
||||
7. 回放播放 → GET /recordings/channels/:cid/index.m3u8?start_ms=xxx&end_ms=xxx
|
||||
8. 云台控制 → POST /channels/:id/ptz/control
|
||||
```
|
||||
|
||||
### 10.3 注意事项
|
||||
|
||||
1. **Token 管理**: JWT 有效期 3 天,建议在 Vol.Pro 中缓存并处理过期刷新
|
||||
2. **播放地址代理**: 前端播放地址建议走 Owl 的 `/proxy/sms/...` 路径,无需暴露 ZLM 直接地址
|
||||
3. **按需拉流**: GB28181 实时播放是按需拉流,首次播放可能有 1-3 秒延迟(SIP 信令 + ZLM 准备)
|
||||
4. **录像模式**: 通道支持 `always` / `ai` / `none` 三种录像模式,通过 `POST /channels/:id/record_mode` 设置
|
||||
5. **PTZ 限制**: 当前 Owl 仅支持 `continuous`(持续移动)和 `stop`(停止),预置位等功能未完整实现
|
||||
6. **心跳与注册**: 不要尝试通过 HTTP 模拟设备注册,这是 SIP 层自动完成的
|
||||
7. **ONVIF PTZ**: README 中标记为"未支持"(`[ ] ONVIF PTZ control support`)
|
||||
|
||||
---
|
||||
|
||||
*报告整理完毕,供 Vol.Pro 后端架构设计参考。*
|
||||
Reference in New Issue
Block a user