1. 认证与 Token 管理
所有管理 API(除登录接口外)均需在请求头中携带 JWT:Authorization: Bearer <token>。
管理员通过 POST /api/admin/login 获取 JWT;移动端用户通过 POST /api/mobile/login 获取 JWT。
root,密码由环境变量 ADMIN_INIT_PASSWORD 指定(默认 admin123)。1.1 管理员登录
使用管理员用户名和密码获取 JWT Token。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | String | 是 | 用户名(如 root) |
| password | String | 是 | 密码 |
curl -X POST http://127.0.0.1:3002/api/admin/login \
-H "Content-Type: application/json" \
-d '{"username":"root","password":"admin123"}'
响应示例
{
"code": 0,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
1.2 全局播放/推流 Token
1.3 修改登录密码(需 JWT)
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/change-pwd -H "Content-Type: application/json" -d '{"new_password":"new_password"}'1.4 流专属 Token 管理(独立于 JWT)
流专属 Token 用于 ZLM 播放/推流鉴权,通过以下接口管理,需携带管理员 JWT。
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/stream-token -H "Content-Type: application/json" -d '{"app":"live","stream":"test","type":"play","token":"my_token","expire_seconds":3600}'curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/stream-token?app=live&stream=test&type=play"curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/stream-token -H "Content-Type: application/json" -d '{"app":"live","stream":"test","type":"play"}'curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/stream-tokens2. ZLM 节点管理
2.1 获取节点列表
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/zlm-servers2.2 更新节点
curl -H "Authorization: Bearer <token>" -X PUT http://127.0.0.1:3002/api/zlm-servers/my-node-01 -H "Content-Type: application/json" -d '{"api_base":"http://new-api:9080","secret":"new-secret","http_fmp4_base":"http://192.168.28.252:9080/","static_base":"http://192.168.28.252:9080/","media_ip":"192.168.28.252"}'2.3 删除节点
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/zlm-servers -H "Content-Type: application/json" -d '{"id":"my-node-01"}'2.4 获取单个节点详情
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/zlm-servers/my-node-012.5 轮询获取在线节点
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/zlm/round-robin3. 流媒体列表
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/zlm-media-list?node_id=my-node-01"4. 实时播放
4.1 开启直播
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/start-live -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001"}'4.2 停止直播
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/stop-live -H "Content-Type: application/json" -d '{"stream":"34020000001320000001_34020000001310000001"}'5. 录像回放
5.1 开启回放
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/start-playback -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001","start_time":"2026-06-01T10:00:00","end_time":"2026-06-01T11:00:00"}'6. 云端录像管理
6.1 查询云端录像
返回的录像记录包含 node_id 字段,记录该录像文件所在的 ZLM 节点 ID。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| channel_id | String | 否 | 通道ID |
| app | String | 否 | 应用名 |
| start | String | 是 | 开始时间(支持多种格式) |
| end | String | 是 | 结束时间 |
| page | Integer | 否 | 页码,默认1 |
| page_size | Integer | 否 | 每页条数,默认20 |
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/records -H "Content-Type: application/json" -d '{"channel_id":"34020000001310000001","app":"rtp","start":"2026-06-01 00:00:00","end":"2026-06-04 00:00:00","page":1,"page_size":10}'
响应示例
{
"code": 0,
"data": {
"records": [
{
"channel_id": "34020000001310000001",
"app": "rtp",
"start_time": "2026-07-21 09:02:06",
"end_time": "2026-07-21 09:02:30",
"file_path": "/etc/m/www/record/rtp/.../2026-07-21-17-02-06-0.mp4",
"file_size": 3615230,
"play_url": "http://192.168.28.252:9080/record/rtp/.../2026-07-21-17-02-06-0.mp4",
"node_id": "1",
"s3_url": null
}
],
"total": 290,
"page": 1,
"page_size": 10
}
}
6.2 删除云端录像 DEPRECATED
cleanup_media),它会自动清理本地文件、数据库记录和 Redis S3 缓存,保证数据一致性。仅删除数据库元数据,不影响本地文件。
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/records -H "Content-Type: application/json" -d '{"items":[{"channel_id":"34020000001310000001","app":"rtp","start_time":"2026-06-03T06:47:16","file_path":"/etc/.../xx.mp4"}]}'
7. 告警管理
7.1 查询告警记录
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/alarms?device_id=34020000001320000001&channel_id=34020000001310000001&start_time=2026-06-06%2000:00:00&end_time=2026-06-07%2000:00:00"7.2 删除告警记录
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/alarms -H "Content-Type: application/json" -d '{"items":[{"device_id":"34020000001320000001","channel_id":"34020000001310000001","alarm_time":"2026-06-06T12:30:00"}]}'8. 设备管理
8.1 获取所有设备列表(不分页)
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/devices8.1.1 添加设备
在平台中注册一个新设备(NVR 或摄像头)。设备信息存储在 Redis 中,初始状态为离线(ip 和 port 为空),待设备主动注册或平台发起连接后更新。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | String | 是 | 20 位国标设备编码(唯一) |
| password | String | 否 | 设备注册密码(不填则使用全局配置) |
| name | String | 否 | 设备自定义名称(便于识别) |
请求示例
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/devices \
-H "Content-Type: application/json" \
-d '{"device_id":"34020000001320000001","password":"123456","name":"NVR-主楼"}'
成功响应
{
"code": 0,
"msg": "device added successfully"
}
错误响应
| HTTP 状态码 | 响应内容 | 说明 |
|---|---|---|
| 400 | {"code":-1,"msg":"device_id required"} | 缺少设备ID |
| 409 | {"code":-1,"msg":"device already exists"} | 设备ID已存在 |
| 500 | {"code":-1,"msg":"internal error"} | Redis 操作失败 |
version=2016,传输协议为 tcp(推荐),同时创建空通道列表 device:{id}:channels = [],并加入全局集合 all_devices。设备上线后,ip 和 port 字段会被自动更新。
8.2 分页获取设备列表 NEW v0.8.0+
基于 Redis SSCAN 的游标分页,适用于设备数量超过数千的场景。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| cursor | Integer | 否 | 游标,首次传 0,后续使用上一次返回的 next_cursor |
| count | Integer | 否 | 每页条数,默认 200 |
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/devices-paginated?cursor=0&count=200"
8.3 搜索设备 NEW v0.8.0+
智能判断:全数字按 ID 前缀匹配,否则按名称模糊匹配。
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/devices/search?keyword=340200000013"
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/devices/search?keyword=前门"
8.4 获取设备通道列表
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/device-channels?device_id=34020000001320000001"8.5 获取设备详细信息
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/device-info?device_id=34020000001320000001"8.6 刷新设备通道
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/refresh-device-channels -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001"}'8.7 修改设备配置
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/device-config -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","name":"新名称","check_ssrc":"true","password":"新密码","transport":"tcp"}'8.8 删除设备
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/devices -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001"}'8.9 查询设备状态历史 NEW v0.8.0+
查询指定设备的历史在线/离线状态变化记录,数据来源于定时任务同步的 device_status_log 表。按时间倒序排列。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | String | 是 | 20位国标设备编码 |
| page | Integer | 否 | 页码,默认 1 |
| page_size | Integer | 否 | 每页条数,默认 20,最大 200 |
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/device-status-history?device_id=34020000001320000002&page_size=10"
成功响应
{
"code": 0,
"data": {
"items": [
{ "device_id": "34020000001320000002", "status": "ON", "ts": "2026-07-30T11:36:22.015" },
{ "device_id": "34020000001320000002", "status": "OFF", "ts": "2026-07-30T11:33:22.016" }
],
"total": 2,
"page": 1,
"page_size": 10
}
}
items 为空。9. 通道配置
9.1 查询单个通道配置
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/channel-config?device_id=34020000001320000001&channel_id=34020000001310000001"9.2 修改单个通道配置
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/channel-config -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001","substream":"true"}'9.3 批量修改通道配置
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/channel-configs/batch -H "Content-Type: application/json" -d '{"channels":[...]}'10. 通道绑定
10.1 获取绑定列表
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/channels10.2 绑定通道
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/channels -H "Content-Type: application/json" -d '{"id":"34020000001310000001","stream":"test","app":"live"}'10.3 删除绑定
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/channels -H "Content-Type: application/json" -d '{"stream":"test","app":"live"}'10.4 批量解绑
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/channels/batch -H "Content-Type: application/json" -d '{"items":[{"app":"live","stream":"test1"},{"app":"live","stream":"test2"}]}'10.5 清空所有绑定
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/channels/clear10.6 获取全部设备通道(不分页)
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/all-channels10.7 分页获取全部设备通道 NEW
| 参数 | 类型 | 说明 |
|---|---|---|
| cursor | Integer | 游标,首次0,下次使用返回的 next_cursor |
| count | Integer | 每页条数,默认200 |
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/all-channels-paginated?cursor=0&count=200"
10.8 通道自定义名称管理 NEW v0.8.0+
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| channel_id | String | 是 | 通道编码 |
| name | String | 是 | 自定义名称 |
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/channel-name -H "Content-Type: application/json" -d '{"channel_id":"34020000001310000001","name":"一楼大厅"}'
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/channel-name -H "Content-Type: application/json" -d '{"channel_id":"34020000001310000001"}'curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/channel-names"11. 截图管理
11.1 请求设备截图
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/snapshot -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001"}'11.2 查询截图缓存
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/snapshot-query?device_id=34020000001320000001"12. 云台控制
通过 POST /api/ptz 接口向设备发送云台控制指令。指令以十六进制字符串形式传递,支持持续按住和单次操作两种模式。
发送云台控制命令。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | String | 是 | 设备 ID |
| channel_id | String | 否 | 通道 ID,不填则使用设备 ID |
| ptz_cmd | String | 是 | 云台控制码(十六进制字符串),见下表 |
请求示例
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/ptz \
-H "Content-Type: application/json" \
-d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001","ptz_cmd":"A50F01084C4C4095"}'
响应示例
{"code": 0}
云台控制码
| 类型 | 操作 | Cmd 字符串(十六进制) |
|---|---|---|
| 方向控制(持续按住时触发) | 上 | A50F01084C4C4095 |
| 下 | A50F01044C4C4091 | |
| 左 | A50F01024C4C408F | |
| 右 | A50F01014F4F4094 | |
| 单次操作(点击触发) | 放大 | A50F01424C000043 |
| 缩小 | A50F01444C004445 | |
| 停止 | A50F0100000000B5 |
13. 预置位管理
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/presets?device_id=34020000001320000001&channel_id=34020000001310000001"curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/presets/query -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001"}'14. 语音广播与对讲
14.1 单向语音广播
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/audio-broadcast -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001","stream":"webrtc_stream_id"}'curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/audio-broadcast-stop -H "Content-Type: application/json" -d '{"stream_id":"talk_..."}'14.2 双向语音对讲
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/audio-talk -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001","stream":"webrtc_stream_id"}'curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/audio-talk-stop -H "Content-Type: application/json" -d '{"stream_id":"talk_..."}'15. 平台信息
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/platform-info16. 目录与业务分组管理 NEW v0.8.0+
16.1 设置行政区域名称
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | String | 是 | 行政区划代码 |
| name | String | 是 | 名称 |
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/admin-region-name -H "Content-Type: application/json" -d '{"code":"340200","name":"芜湖市"}'
16.2 删除行政区域名称
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/admin-region-name -H "Content-Type: application/json" -d '{"code":"340200"}'16.3 查询行政区域名称
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/admin-region-names?code=340200"16.4 设置业务分组/虚拟组织名称
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | String | 是 | 业务分组编码 |
| name | String | 是 | 名称 |
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/biz-group-name -H "Content-Type: application/json" -d '{"code":"34020000000021600001","name":"重点区域"}'
16.5 删除业务分组名称
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/biz-group-name -H "Content-Type: application/json" -d '{"code":"34020000000021600001"}'16.6 查询业务分组名称
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/biz-group-names?code=34020000000021600001"16.7 设置通道业务分组
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| channel_id | String | 是 | 通道编码 |
| group_code | String | 是 | 业务分组编码 |
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/channel-biz-group -H "Content-Type: application/json" -d '{"channel_id":"34020000001310000001","group_code":"34020000000021600001"}'
16.8 删除通道业务分组
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/channel-biz-group -H "Content-Type: application/json" -d '{"channel_id":"34020000001310000001"}'16.9 查询通道业务分组
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/channel-biz-groups?channel_id=34020000001310000001"17. 流代理管理
17.1 拉流代理
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/stream-proxies| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| vhost | String | 否 | 默认 __defaultVhost__ |
| app | String | 否 | 默认 live |
| stream | String | 是 | 流ID |
| url | String | 是 | 拉流地址 |
| on_demand | Boolean | 否 | 是否按需 |
| zlm_node | String | 否 | 指定ZLM节点 |
| enable_mp4 | Boolean | 否 | 是否开启MP4录制 |
| auto_close | Boolean | 否 | 按需拉流无人观看自动关闭 |
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/stream-proxies -H "Content-Type: application/json" -d '{"stream":"test","url":"rtsp://192.168.1.100:554/stream","on_demand":true,"enable_mp4":true}'
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/stream-proxies -H "Content-Type: application/json" -d '{"key":"__defaultVhost__/live/test"}'17.2 推流代理
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/stream-pusher-proxiescurl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/stream-pusher-proxies -H "Content-Type: application/json" -d '{"schema":"rtmp","vhost":"__defaultVhost__","app":"live","stream":"test","dst_url":"rtmp://target/live/stream"}'curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/stream-pusher-proxies -H "Content-Type: application/json" -d '{"key":"rtmp/__defaultVhost__/live/test"}'18. 录制控制
18.1 开始录制
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| app | String | 是 | 应用名 |
| stream | String | 是 | 流ID |
| type | Int | 是 | 0=HLS,1=MP4 |
| customized_path | String | 否 | 保存目录 |
| max_second | Int | 否 | 切片时长 |
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/start-record -H "Content-Type: application/json" -d '{"app":"live","stream":"camera01","type":1,"max_second":300}'
18.2 停止录制
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/stop-record -H "Content-Type: application/json" -d '{"app":"live","stream":"camera01","type":1}'18.3 查询录制状态
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/is-recording -H "Content-Type: application/json" -d '{"app":"live","stream":"camera01","type":1}'19. 级联管理
用于管理下级平台与上级平台的级联连接,支持 UDP 和 TCP 两种传输方式
19.1 获取级联列表
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/servers
响应示例
{
"code": 0,
"data": [
{
"id": "182.92.251.233:6060",
"device_id": "34020000002000000004",
"realm": "3402000000",
"sip_server": "182.92.251.233:6060",
"local_addr": "0.0.0.0:5070",
"transport": "TCP",
}
]
}
19.2 添加级联服务器
添加一个上级平台级联配置。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | String | 是 | 下级设备 ID(用于 SIP 认证用户名) |
| realm | String | 是 | SIP 域 |
| password | String | 是 | 认证密码 |
| sip_server | String | 是 | 上级服务器地址(IP:端口) |
| local_addr | String | 是 | 本地监听地址(IP:端口),TCP 模式下为 TCP 监听端口 |
| transport | String | 是 | 传输协议:"UDP" 或 "TCP" |
| version | String | 否 | GB/T 28181 协议版本,默认 "2022" |
| server_id | String | 否 | 上级平台 ID,不传时使用 device_id |
UDP 模式示例
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/servers \
-H "Content-Type: application/json" \
-d '{
"device_id": "34020000002000000004",
"realm": "3402000000",
"password": "password123",
"sip_server": "182.92.251.233:6060",
"local_addr": "0.0.0.0:5070",
"transport": "UDP",
"version": "2022"
}'
TCP 模式示例
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/servers \
-H "Content-Type: application/json" \
-d '{
"device_id": "34020000002000000004",
"realm": "3402000000",
"password": "password123",
"sip_server": "182.92.251.233:6060",
"local_addr": "0.0.0.0:5070",
"transport": "TCP",
"version": "2022",
}'
成功响应
{"code": 0, "msg": "server added"}
常见错误
| HTTP 状态码 | 响应体 | 说明 |
|---|---|---|
| 400 | {"code":-1,"msg":"invalid tcp_source_addr"} | tcp_source_addr 格式错误 |
| 500 | {"code":-1,"msg":"TCP source port must not equal listening port"} | 源端口与监听端口相同 |
19.3 删除级联服务器
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/servers \
-H "Content-Type: application/json" \
-d '{"id":"182.92.251.233:6060"}'
删除时请同时手动清理服务器上对应的 iptables 规则(如果添加了)。
20. 系统备份与恢复 NEW v0.8.0+
20.1 备份系统配置
导出所有代理配置、目录管理数据、通道绑定关系。
curl -H "Authorization: Bearer <token>" -X POST http://localhost:3002/api/backup/system -o backup.json20.2 恢复系统配置
| 参数 | 类型 | 说明 |
|---|---|---|
| clear_before | Boolean | 是否清空现有数据再恢复,默认false |
| stream_proxies | Array | 拉流代理数组(可选) |
| stream_pusher_proxies | Array | 推流代理数组(可选) |
| admin_region_names | Object | 行政区域名称(可选) |
| biz_group_names | Object | 业务分组名称(可选) |
| channel_biz_group | Object | 通道业务分组绑定(可选) |
| channel_bindings | Object | 正向通道绑定(可选) |
| channel_bindings_rev | Object | 反向通道绑定(可选) |
| channel_names | Object | 通道自定义名称(可选) |
curl -H "Authorization: Bearer <token>" -X POST http://localhost:3002/api/restore/system -H "Content-Type: application/json" -d @backup.json
21. ZLM Webhook 回调
无需认证。
| 端点 | 用途 |
|---|---|
| /hook/on_record_mp4 | 录像完成,写入数据库并通知 mgr-server |
| /hook/on_stream_changed | 流状态变化 |
| /hook/on_play | 播放鉴权 |
| /hook/on_publish | 推流鉴权 |
| /hook/on_stream_none_reader | 无人观看自动关闭 |
| /hook/on_stream_not_found | 触发自动拉流 |
| /hook/on_rtp_server_timeout | RTP超时清理 |
| /hook/on_server_started | 恢复流代理 |
22. 通用错误码
| 状态码/错误码 | 含义 |
|---|---|
| 401 | 认证失败(缺少或无效 JWT) |
| 403 | 权限不足(JWT 有效但无对应权限) |
| 422 | 请求体格式错误 |
| 500 | 服务器内部错误 |
| code: -1 | 业务错误 |
| code: 0 | 成功 |
23. 定时任务管理 v0.8.0+
支持截图、录制、会话清理、设备状态同步,以及 定时清理录像 (cleanup_media) 和 定时清理截图 (cleanup_snapshot)。
内部执行接口:使用
X-Internal-Token 头,仅供 scheduler-server 调用。调度器扫描间隔:30 秒。
23.1 创建定时任务
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| action | String | 是 | snapshot, record, cleanup_sessions, sync_device_status, cleanup_media, cleanup_snapshot |
| cron_expr | String | 是 | Cron 表达式(UTC) |
| device_id | String | 条件 | 国标设备ID(snapshot/record) |
| channel_id | String | 条件 | 通道ID或* |
| app | String | 条件 | 代理app,也用于 cleanup_media 过滤 |
| stream | String | 条件 | 代理stream,也用于 cleanup_media 过滤 |
| duration_secs | Integer | 录制必须 | 录制时长 |
| enabled | Boolean | 否 | 默认true |
| concurrency | Integer | 否 | 并发数,默认5 |
| callback_url | String | 否 | 任务完成后回调地址 |
| retention_days | Integer | 否 | 清理任务专用:保留天数,默认7 |
示例 1:每天凌晨 3 点清理所有 7 天前的录像(全部流)
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/schedule/tasks -H "Content-Type: application/json" -d '{"action":"cleanup_media","cron_expr":"0 3 * * *","retention_days":7}'
示例 2:每天凌晨 4 点清理所有 7 天前的截图
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/schedule/tasks -H "Content-Type: application/json" -d '{"action":"cleanup_snapshot","cron_expr":"0 4 * * *","retention_days":7}'
示例 3:只清理 live 应用下 camera1 流的 7 天前录像
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/schedule/tasks -H "Content-Type: application/json" -d '{"action":"cleanup_media","cron_expr":"0 3 * * *","retention_days":7,"app":"live","stream":"camera1"}'
示例 4:每周日凌晨 5 点清理残留会话
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/schedule/tasks -H "Content-Type: application/json" -d '{"action":"cleanup_sessions","cron_expr":"0 5 * * 0"}'
23.2 清理任务行为说明
| 动作 | 清理范围 | 参数 | 说明 |
|---|---|---|---|
cleanup_media | 录像文件 + 数据库记录 + Redis S3 缓存 | retention_days(默认7), app, stream(可选过滤) | 调用 ZLM deleteRecordDirectory 删除本地文件,然后清理数据库和 Redis 缓存 |
cleanup_snapshot | 截图文件(本地文件系统) | retention_days(默认7) | 删除 static/snapshots/{device_id}/{channel_id}/{YYYYMMDD} 目录 |
cleanup_sessions | 残留级联会话 | 无 | 扫描 Redis 会话,关闭无人观看的转发流并删除记录 |
23.3 列出所有任务
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/schedule/tasks?page=1&page_size=20"23.4 查询单个任务
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/schedule/tasks/task_xxx23.5 更新任务
curl -H "Authorization: Bearer <token>" -X PUT http://127.0.0.1:3002/api/schedule/tasks/task_xxx -H "Content-Type: application/json" -d '{"cron_expr":"0 9 * * *","enabled":true}'23.6 删除任务
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/schedule/tasks/task_xxx23.7 启用/禁用任务
curl -H "Authorization: Bearer <token>" -X PATCH http://127.0.0.1:3002/api/schedule/tasks/task_xxx/enable -H "Content-Type: application/json" -d '{"enabled":false}'23.8 内部执行接口
需要 X-Internal-Token 头。支持所有 action 类型。
curl -X POST http://127.0.0.1:3002/api/internal/task/exec -H "X-Internal-Token: your-secret-token" -H "Content-Type: application/json" -d '{"action":"cleanup_media","retention_days":7}'23.9 设备状态同步任务
定时扫描所有设备,仅状态变化时写入 device_status_log。支持 callback_url 推送状态变化事件。
- 环境变量:
SYNC_BATCH_SIZE(默认2000)、SYNC_MAX_ITERATIONS(默认10)、DEVICE_OFFLINE_TIMEOUT_SECS(默认180) - 自动清理:扫描过程中会自动移除
all_devices中的无效设备 ID - 回调格式(当提供了
callback_url时):
POST {callback_url}
Content-Type: application/json
{
"event": "device_status_changed",
"changes": [
{
"device_id": "34020000001320000001",
"previous_status": "ON",
"current_status": "OFF",
"ts": 1722225000
}
]
}
23.10 Cron 表达式与时区
使用 UTC 时间。例如北京时间 (UTC+8) 凌晨 3:00 对应 UTC 前一天 19:00,应写为 0 19 * * *。
24. 截图与辅助 API (v0.7.3+)
24.1 ZLM 截图接口
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/zlm-snap -H "Content-Type: application/json" -d '{"device_id":"34020000001320000001","channel_id":"34020000001310000001"}'24.2 全部设备通道接口
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/all-channels24.3 主动录像及事件回调
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/start-record-task -H "Content-Type: application/json" -d '{"app":"live","stream":"test","path":"callback_test.mp4","back_ms":10000,"forward_ms":10000,"callback_url":"http://your-server.com/notify"}'24.4 批量截图接口
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/batch-snap -H "Content-Type: application/json" -d '{"concurrency":3,"auto_stop_live":false}'25. 移动端多用户播放 v0.8.0+
GBHub 支持为移动端 App 创建独立用户,每个用户可被分配 设备通道 或 拉流代理 的播放权限。移动端通过 JWT Bearer Token 认证,管理员通过 JWT 管理用户和权限。
.env 中设置 JWT_SECRET,默认有效期为 7 天(可通过 JWT_EXPIRE_DAYS 调整)。权限格式:设备通道使用
<device_id>:<channel_id>,拉流代理使用 proxy:<app>:<stream>。
25.0 可用权限列表
管理员权限采用基于角色的访问控制(RBAC),每个用户拥有一个权限列表。以下为系统当前支持的所有权限及其含义:
| 权限标识 | 说明 |
|---|---|
devices:read | 查看设备列表、设备详情、通道列表 |
devices:write | 添加/删除设备、修改设备配置、通道绑定/解绑、通道名称管理 |
records:read | 查询云端录像 |
records:delete | 删除云端录像记录 |
alarms:read | 查询告警记录 |
alarms:delete | 删除告警记录 |
proxy:manage | 管理拉流代理、推流代理、FFmpeg 代理、ONVIF 操作 |
zlm:manage | 管理 ZLM 节点(增删改查、轮询) |
system:config | 系统配置:备份/恢复、定时任务、修改密码 |
user:manage | 用户管理:创建/删除用户、修改用户权限 |
snapshot | 请求截图、查询截图缓存 |
record:control | 手动控制录制(开始/停止/状态查询) |
ptz:control | 云台控制 |
audio:control | 语音广播与对讲 |
root 拥有以上全部权限。权限变更后即时生效,无需重启服务。25.1 管理员接口(需 JWT)
返回所有已创建的用户名列表。
请求示例
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/admin/users
响应示例
{
"code": 0,
"data": ["alice", "bob", "charlie"]
}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | String | 是 | 用户名 |
| password | String | 是 | 密码(明文,服务端会 Bcrypt 加密存储) |
| permissions | Array | 否 | 权限列表(见 25.0 节),默认为空数组 |
请求示例
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/admin/users \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"secret123","permissions":["devices:read","records:read"]}'
响应示例
{"code": 0}
删除用户及其所有权限分配。
请求示例
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/admin/users/alice
响应示例
{"code": 0}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| password | String | 是 | 新密码 |
请求示例
curl -H "Authorization: Bearer <token>" -X PUT http://127.0.0.1:3002/api/admin/users/alice/password \
-H "Content-Type: application/json" \
-d '{"password":"newpass456"}'
响应示例
{"code": 0}
返回该用户当前的权限列表。
请求示例
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/admin/users/alice/permissions
响应示例
{
"code": 0,
"data": ["devices:read", "records:read"]
}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| permissions | Array | 是 | 新的权限列表(完全覆盖原有权限) |
请求示例
curl -H "Authorization: Bearer <token>" -X PUT http://127.0.0.1:3002/api/admin/users/alice/permissions \
-H "Content-Type: application/json" \
-d '{"permissions":["devices:read","devices:write","proxy:manage"]}'
响应示例
{"code": 0}
返回该用户被授权的所有通道(包括设备通道和代理),并附带设备/通道名称等详细信息。
请求示例
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/admin/users/alice/channels
响应示例
{
"code": 0,
"data": [
{
"type": "device",
"device_id": "34020000001320000001",
"channel_id": "34020000001310000003",
"device_name": "NVR-01",
"channel_name": "摄像头01"
},
{
"type": "proxy",
"app": "live",
"stream": "camera1",
"name": "大门RTSP"
}
]
}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| channel_id | String | 是 | 设备通道标识,格式 <device_id>:<channel_id> |
请求示例
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/admin/users/alice/channels \
-H "Content-Type: application/json" \
-d '{"channel_id":"34020000001320000001:34020000001310000003"}'
响应示例
{"code": 0}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| channel_id | String | 是 | 设备通道标识(同分配接口) |
请求示例
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/admin/users/alice/channels \
-H "Content-Type: application/json" \
-d '{"channel_id":"34020000001320000001:34020000001310000003"}'
响应示例
{"code": 0}
自动扫描用户的所有权限,移除那些设备已不存在、通道已删除或代理已失效的权限。适用于设备下线或代理被删除后的权限清理。
请求示例
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/admin/users/alice/channels/clean
响应示例
{
"code": 0,
"removed": 2,
"msg": "已清理 2 个无效权限"
}
all_devices 及其通道缓存,以及 stream_proxies 列表,仅保留有效的条目。| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| app | String | 是 | 代理的 app 名称 |
| stream | String | 是 | 代理的 stream 名称 |
内部存储格式为 proxy:<app>:<stream>。
请求示例
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/admin/users/alice/proxy \
-H "Content-Type: application/json" \
-d '{"app":"live","stream":"camera1"}'
响应示例
{"code": 0}
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| app | String | 是 | 代理的 app 名称 |
| stream | String | 是 | 代理的 stream 名称 |
请求示例
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/admin/users/alice/proxy \
-H "Content-Type: application/json" \
-d '{"app":"live","stream":"camera1"}'
响应示例
{"code": 0}
25.2 移动端接口(JWT Bearer Token)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| username | String | 是 | 用户名 |
| password | String | 是 | 密码明文 |
请求示例
curl -X POST http://127.0.0.1:3002/api/mobile/login \
-H "Content-Type: application/json" \
-d '{"username":"alice","password":"secret123"}'
成功响应
{
"code": 0,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
失败响应(401)
{"code": -1, "msg": "Unauthorized"}
Authorization 头中携带 Bearer <token>。返回当前登录用户被授权的所有通道(包含设备通道和代理),同时附带播放地址、截图 URL 及是否有缓存截图。
请求示例
curl -H "Authorization: Bearer " http://127.0.0.1:3002/api/mobile/channels
响应示例
{
"code": 0,
"data": [
{
"type": "device",
"device_id": "34020000001320000001",
"channel_id": "34020000001310000003",
"device_name": "NVR-01",
"channel_name": "摄像头01",
"play_url": "http://192.168.28.252:9080/rtp/34020000001320000001_34020000001310000003.live.mp4",
"snapshot_url": "http://static.example.com/snapshots/...",
"has_snapshot": true
},
{
"type": "proxy",
"app": "live",
"stream": "camera1",
"name": "大门RTSP",
"play_url": "http://192.168.28.252:9080/live/camera1.live.mp4",
"snapshot_url": "/api/mobile/snapshot?id=proxy:live:camera1",
"has_snapshot": false
}
]
}
snapshot_url 可能为本地路径或完整 URL,取决于是否配置了 S3 上传。若 has_snapshot 为 false,可调用截图接口主动生成。返回指定通道的播放地址,并在后台异步触发截图(仅对国标设备有效,代理不会自动截图)。
| 路径参数 | 类型 | 说明 |
|---|---|---|
| channel_id | String | 通道标识,可以是 <device_id>:<channel_id> 或 proxy:<app>:<stream> |
请求示例
curl -H "Authorization: Bearer " http://127.0.0.1:3002/api/mobile/play/34020000001320000001:34020000001310000003
响应示例
{
"code": 0,
"url": "http://192.168.28.252:9080/rtp/34020000001320000001_34020000001310000003.live.mp4"
}
snapshot:latest:<device_id>:<channel_id>)。若已有缓存或正在截图,则不会重复执行。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| password | String | 是 | 新密码 |
请求示例
curl -X PUT http://127.0.0.1:3002/api/mobile/change-pwd \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{"password":"newpass789"}'
响应示例
{"code": 0}
主动请求通道截图,支持国标设备和拉流代理。对于代理,若流不在线则会尝试按需拉流(依据代理配置的 url),等待流上线后再截图。
| 查询参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | String | 条件必填 | 代理标识,格式 proxy:<app>:<stream>(与 device_id+channel_id 二选一) |
| device_id | String | 条件必填 | 国标设备 ID(与 id 二选一) |
| channel_id | String | 条件必填 | 国标通道 ID(与 id 二选一) |
示例 1:国标设备截图
curl -H "Authorization: Bearer " \
"http://127.0.0.1:3002/api/mobile/snapshot?device_id=34020000001320000001&channel_id=34020000001310000003"
示例 2:代理截图(自动拉流)
curl -H "Authorization: Bearer " \
"http://127.0.0.1:3002/api/mobile/snapshot?id=proxy:live:camera1"
成功响应
{
"code": 0,
"url": "http://static.example.com/snapshots/live/camera1/20260817/123456_camera1.jpg",
"msg": "截图已更新"
}
失败响应示例(代理拉流超时)
{
"code": -1,
"msg": "拉流超时,流未能上线"
}
addStreamProxy 拉流,等待最多 10 秒。若流上线,则执行截图并缓存结果(永久)。
以上所有移动端接口均需有效的 JWT Token,过期后需重新登录获取。
26. 录像转录(Transcribe)NEW v0.8.0+
将指定设备通道的历史录像片段异步录制为 MP4 文件,并提供播放地址。任务在后台执行,支持去重、并发控制、取消和状态查询。
并发限制:由环境变量
TRANSCRIBE_MAX_CONCURRENT 控制,默认 3 个任务。防重机制:同一
device_id + channel_id + start_time + end_time 的任务只会执行一次,重复提交直接返回已有的结果。文件保存:转录出的 MP4 存储在 ZLMediaKit 默认录制目录,受全局清理策略控制(默认保留 7 天)。
原速录制:任务以原速拉取录像流,不会倍速处理。
26.1 启动转录任务
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | String | 是 | 国标设备ID(NVR 或摄像头) |
| channel_id | String | 是 | 视频通道ID(注意不能填错,否则任务超时) |
| start_time | String | 是 | 开始时间,支持格式:2026-08-07 16:00:00 或 2026-08-07T16:00:00 |
| end_time | String | 是 | 结束时间,同上 |
| zlm_node | String | 否 | 指定 ZLMediaKit 节点 ID,不填则自动选择 |
| callback_url | String | 否 | 转录完成后回调通知的 HTTP(S) 地址 |
示例请求
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/playback/transcribe \
-H "Content-Type: application/json" \
-d '{
"device_id": "34020000001320000001",
"channel_id": "34020000001310000003",
"start_time": "2026-08-07 16:00:00",
"end_time": "2026-08-07 16:30:00"
}'
成功响应
{
"code": 0,
"msg": "transcribe task started",
"task_id": "550e8400-e29b-41d4-a716-446655440000"
}
常见错误响应
| HTTP 状态码 | code | msg |
|---|---|---|
| 400 | -1 | 缺少必填参数或时间格式错误 |
| 401 | -1 | 未授权(缺少或无效 JWT) |
| 409 | -1 | 任务已在运行中(同一时间段) |
| 429 | -1 | 并发任务数已达上限 |
注意:若同一时间段已转录过,接口会直接返回 {"code":0, "msg":"already transcribed", "file_url":"..."},不再创建新任务。
26.2 停止转录任务
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| task_id | String | 是 | 启动转录时返回的任务 ID |
curl -H "Authorization: Bearer <token>" -X POST http://127.0.0.1:3002/api/playback/transcribe/stop \
-H "Content-Type: application/json" \
-d '{"task_id":"550e8400-e29b-41d4-a716-446655440000"}'
成功响应
{"code":0,"msg":"stop signal sent"}
说明:停止信号发送后,任务会在下个检查点安全退出并清理资源。若任务已结束或不存在,返回 404 错误。
26.3 查询转录结果
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| device_id | String | 是 | 设备ID |
| channel_id | String | 是 | 通道ID |
| start_time | String | 是 | 开始时间,格式同启动接口 |
| end_time | String | 是 | 结束时间 |
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/playback/transcribe/query?device_id=34020000001320000001&channel_id=34020000001310000003&start_time=2026-08-07 16:00:00&end_time=2026-08-07 16:30:00"
响应(已完成)
{
"code": 0,
"status": "completed",
"file_url": "http://192.168.28.252:9080/record/rtp/proxy_playback_.../xxx.mp4"
}
响应(运行中)
{
"code": 0,
"status": "running",
"msg": "task is still in progress",
"task_id": "550e8400-e29b-41d4-a716-446655440000"
}
响应(未找到)
{
"code": 0,
"status": "not_found",
"msg": "no transcription found for this time range"
}
task_id,你可以用它调用停止接口。26.4 回调通知
如果启动时提供了 callback_url,转录完成后会向该地址发送 POST 通知:
POST {callback_url}
Content-Type: application/json
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"file_url": "http://192.168.28.252:9080/record/rtp/.../xxx.mp4"
}
26.5 常见问题
404 Not Found,任务会在约 15 秒后超时失败,请先通过 /api/device-channels 确认正确的通道 ID。
running,导致该时间段无法重新发起转录。可手动删除 Redis 键 transcribe:status:{core} 和 transcribe:task_id:{core} 后重试。
转录后的文件可在 云端录像管理 接口中查询,也可通过返回的 file_url 直接访问。
27. 设备与通道统计 NEW v0.8.0+
获取平台当前设备总数和通道总数,适合运维监控、仪表盘展示。采用 Redis Pipeline 优化,设备数 ≤1 万时响应迅速。
请求示例
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/stats/summary
成功响应
{
"code": 0,
"data": {
"device_count": 128,
"channel_count": 456
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| code | int | 0 表示成功,-1 表示失败 |
| device_count | int | 已注册设备总数(来自 Redis 集合 all_devices 的基数) |
| channel_count | int | 所有设备通道数量累加(来自 device:{device_id}:channels 缓存) |
错误响应
| HTTP 状态码 | 响应体 | 说明 |
|---|---|---|
| 401 | {"code":-1,"msg":"unauthorized"} | 未认证或 JWT 无效 |
| 403 | {"code":-1,"msg":"forbidden"} | 权限不足 |
| 500 | {"code":-1,"msg":"internal error"} | Redis 异常或内部错误 |