Files
SecMPS/owl_api_research.md
2026-05-15 23:22:48 +08:00

18 KiB
Raw Permalink Blame History

OwlGoWVP开源视频监控管理平台 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
  • 请求参数:
    {
      "data": "<RSA加密后的JSON字符串>"
    }
    
    • 加密前内容示例:{"username":"admin","password":"admin"}
    • 公钥获取:GET /login/key,返回 Base64 编码的 RSA 公钥PEM 格式)
  • 响应示例:
    {
      "token": "eyJhbGciOiJIUzI1NiIs...",
      "user": "admin"
    }
    
  • Token 有效期: 3 天
  • 使用方式: 请求头携带 Authorization: Bearer <token>

1.2 修改凭据

  • URL: PUT /users
  • 说明: 需先校验旧密码,同样使用 RSA 加密传输

二、设备管理 API

设备类型支持:GB28181ONVIFRTMPRTSP

2.1 设备列表查询

  • URL: GET /devices
  • 认证: 需 JWT
  • 请求参数 (Query):
    参数 类型 说明
    page int 页码,默认 1
    size int 每页大小
    key string 关键词模糊搜索(名称/国标编号)
  • 响应:
    {
      "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
  • 请求体:
    // 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
  • 响应:
    {
      "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(通道数组),并按在线状态排序
  • 响应:
    {
      "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):
    {
      "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):
    {
      "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 结束时间戳(毫秒)
  • 响应:
    {
      "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
  • 响应:
    {
      "items": [
        {
          "id": 1,
          "start_ms": 1714982400000,
          "end_ms": 1714982700000,
          "duration": 300.5
        }
      ]
    }
    

5.3 获取月度统计

  • URL: GET /recordings/monthly?cid=xxx&year=2026&month=5
  • 响应:
    {
      "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
  • 当前实现限制: 代码中仅实现了 continuousstop,其他动作类型会返回错误
  • 响应:
    {
      "msg": "PTZ 控制指令已发送"
    }
    
  • 注意: 目前代码中直接调用 GB28181 Server 的 PTZControl 方法未区分协议类型ONVIF PTZ 支持标记为 TODO

七、设备状态查询 API

7.1 在线状态

Owl 没有单独的"设备状态查询"接口,设备状态包含在设备/通道列表查询中:

  • 设备在线状态: GET /devicesGET /devices/:idis_online
  • 通道在线状态: GET /channelsGET /devices/channelsis_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_atexpires 判断设备是否离线
    • 例如:设备侧超时 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 定时保活(默认 10sOwl 更新节点在线状态
/webhook/on_publish POST 推流鉴权RTMP/RTSP/RTPOwl 校验是否允许推流
/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 重启 ZLMrtc 端口变更时)

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_publishon_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 后端架构设计参考。