GBHub 国标视频平台

完整 API 开发手册 v0.8.0+ · 移动端多用户 · 定时任务 · 录制控制 · 会话清理 · 系统备份 · 设备搜索 · 分页列表 · 目录管理 · 设备状态同步 · 定时清理录像/截图 · 录像转录 · 设备与通道统计

统一端口:http://<IP>:3002
认证方式:JWT Bearer Token(管理端与移动端统一)
获取 Token:管理员使用 POST /api/admin/login,移动端使用 POST /api/mobile/login
JWT 有效期:默认 7 天(可通过环境变量 JWT_EXPIRE_DAYS 调整)

1. 认证与 Token 管理

所有管理 API(除登录接口外)均需在请求头中携带 JWT:Authorization: Bearer <token>

管理员通过 POST /api/admin/login 获取 JWT;移动端用户通过 POST /api/mobile/login 获取 JWT。

默认初始化超级管理员账号 root,密码由环境变量 ADMIN_INIT_PASSWORD 指定(默认 admin123)。

1.1 管理员登录

POST/api/admin/login

使用管理员用户名和密码获取 JWT Token。

参数类型必填说明
usernameString用户名(如 root)
passwordString密码
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

v0.7.0 起,全局 Token 已改为环境变量控制,用于 ZLM 播放/推流鉴权,与管理 JWT 无关。

1.3 修改登录密码(需 JWT)

POST/api/change-pwd
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。

POST/api/stream-token
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}'
GET/api/stream-token?app=live&stream=test&type=play
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/stream-token?app=live&stream=test&type=play"
DELETE/api/stream-token
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"}'
GET/api/stream-tokens
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/stream-tokens

2. ZLM 节点管理

2.1 获取节点列表

GET/api/zlm-servers
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/zlm-servers

2.2 更新节点

PUT/api/zlm-servers/{id}
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 删除节点

DELETE/api/zlm-servers
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 获取单个节点详情

GET/api/zlm-servers/{id}
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/zlm-servers/my-node-01

2.5 轮询获取在线节点

GET/api/zlm/round-robin
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/zlm/round-robin

3. 流媒体列表

GET/api/zlm-media-list?node_id=my-node-01
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/zlm-media-list?node_id=my-node-01"

4. 实时播放

4.1 开启直播

POST/api/start-live
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 停止直播

POST/api/stop-live
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 开启回放

POST/api/start-playback
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 查询云端录像

POST/api/records

返回的录像记录包含 node_id 字段,记录该录像文件所在的 ZLM 节点 ID。

参数类型必填说明
channel_idString通道ID
appString应用名
startString开始时间(支持多种格式)
endString结束时间
pageInteger页码,默认1
page_sizeInteger每页条数,默认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

DELETE/api/records
⚠️ 此接口已废弃 删除录像文件请使用定时清理任务(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 查询告警记录

GET/api/alarms
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 删除告警记录

DELETE/api/alarms
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 获取所有设备列表(不分页)

GET/api/devices
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/devices

8.1.1 添加设备

POST /api/devices

在平台中注册一个新设备(NVR 或摄像头)。设备信息存储在 Redis 中,初始状态为离线(ipport 为空),待设备主动注册或平台发起连接后更新。

参数类型必填说明
device_idString20 位国标设备编码(唯一)
passwordString设备注册密码(不填则使用全局配置)
nameString设备自定义名称(便于识别)

请求示例

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。设备上线后,ipport 字段会被自动更新。

8.2 分页获取设备列表 NEW v0.8.0+

GET/api/devices-paginated?cursor=0&count=200

基于 Redis SSCAN 的游标分页,适用于设备数量超过数千的场景。

参数类型必填说明
cursorInteger游标,首次传 0,后续使用上一次返回的 next_cursor
countInteger每页条数,默认 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+

GET/api/devices/search?keyword=xxx

智能判断:全数字按 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 获取设备通道列表

GET/api/device-channels?device_id=34020000001320000001
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/device-channels?device_id=34020000001320000001"

8.5 获取设备详细信息

GET/api/device-info?device_id=34020000001320000001
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/device-info?device_id=34020000001320000001"

8.6 刷新设备通道

POST/api/refresh-device-channels
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 修改设备配置

POST/api/device-config
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 删除设备

DELETE/api/devices
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+

GET/api/device-status-history?device_id=34020000001320000001&page=1&page_size=20

查询指定设备的历史在线/离线状态变化记录,数据来源于定时任务同步的 device_status_log 表。按时间倒序排列。

参数类型必填说明
device_idString20位国标设备编码
pageInteger页码,默认 1
page_sizeInteger每页条数,默认 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
  }
}
数据仅记录状态变化(ON→OFF / OFF→ON),不会产生连续重复状态。若设备从未被同步任务记录过,items 为空。

9. 通道配置

9.1 查询单个通道配置

GET/api/channel-config?device_id=...&channel_id=...
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/channel-config?device_id=34020000001320000001&channel_id=34020000001310000001"

9.2 修改单个通道配置

POST/api/channel-config
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 批量修改通道配置

POST/api/channel-configs/batch
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 获取绑定列表

GET/api/channels
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/channels

10.2 绑定通道

POST/api/channels
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 删除绑定

DELETE/api/channels
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 批量解绑

DELETE/api/channels/batch
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 清空所有绑定

DELETE/api/channels/clear
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/channels/clear

10.6 获取全部设备通道(不分页)

GET/api/all-channels
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/all-channels

10.7 分页获取全部设备通道 NEW

GET/api/all-channels-paginated?cursor=0&count=200
参数类型说明
cursorInteger游标,首次0,下次使用返回的 next_cursor
countInteger每页条数,默认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+

POST/api/channel-name
参数类型必填说明
channel_idString通道编码
nameString自定义名称
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":"一楼大厅"}'
DELETE/api/channel-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"}'
GET/api/channel-names?channel_id=34020000001310000001
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/channel-names"

11. 截图管理

11.1 请求设备截图

POST/api/snapshot
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 查询截图缓存

GET/api/snapshot-query?device_id=34020000001320000001
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/snapshot-query?device_id=34020000001320000001"

12. 云台控制

通过 POST /api/ptz 接口向设备发送云台控制指令。指令以十六进制字符串形式传递,支持持续按住和单次操作两种模式。

POST /api/ptz

发送云台控制命令。

参数类型必填说明
device_idString设备 ID
channel_idString通道 ID,不填则使用设备 ID
ptz_cmdString云台控制码(十六进制字符串),见下表

请求示例

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
注意:方向控制指令通常由前端在用户按住按钮时循环发送,松开时发送停止指令;单次操作(如变倍)只需发送一次即可。发送频率建议不低于 200ms 间隔,避免设备处理不过来。

13. 预置位管理

GET/api/presets?device_id=...&channel_id=...
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/presets?device_id=34020000001320000001&channel_id=34020000001310000001"
POST/api/presets/query
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 单向语音广播

POST/api/audio-broadcast
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"}'
POST/api/audio-broadcast-stop
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 双向语音对讲

POST/api/audio-talk
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"}'
POST/api/audio-talk-stop
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. 平台信息

GET/api/platform-info
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/platform-info

16. 目录与业务分组管理 NEW v0.8.0+

16.1 设置行政区域名称

POST/api/admin-region-name
参数类型必填说明
codeString行政区划代码
nameString名称
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 删除行政区域名称

DELETE/api/admin-region-name
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 查询行政区域名称

GET/api/admin-region-names?code=340200
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/admin-region-names?code=340200"

16.4 设置业务分组/虚拟组织名称

POST/api/biz-group-name
参数类型必填说明
codeString业务分组编码
nameString名称
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 删除业务分组名称

DELETE/api/biz-group-name
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 查询业务分组名称

GET/api/biz-group-names?code=34020000000021600001
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/biz-group-names?code=34020000000021600001"

16.7 设置通道业务分组

POST/api/channel-biz-group
参数类型必填说明
channel_idString通道编码
group_codeString业务分组编码
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 删除通道业务分组

DELETE/api/channel-biz-group
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 查询通道业务分组

GET/api/channel-biz-groups?channel_id=34020000001310000001
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/channel-biz-groups?channel_id=34020000001310000001"

17. 流代理管理

17.1 拉流代理

GET/api/stream-proxies
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/stream-proxies
POST/api/stream-proxies
参数类型必填说明
vhostString默认 __defaultVhost__
appString默认 live
streamString流ID
urlString拉流地址
on_demandBoolean是否按需
zlm_nodeString指定ZLM节点
enable_mp4Boolean是否开启MP4录制
auto_closeBoolean按需拉流无人观看自动关闭
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}'
DELETE/api/stream-proxies
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 推流代理

GET/api/stream-pusher-proxies
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/stream-pusher-proxies
POST/api/stream-pusher-proxies
curl -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"}'
DELETE/api/stream-pusher-proxies
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 开始录制

POST/api/start-record
参数类型必填说明
appString应用名
streamString流ID
typeInt0=HLS,1=MP4
customized_pathString保存目录
max_secondInt切片时长
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 停止录制

POST/api/stop-record
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 查询录制状态

POST/api/is-recording
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 获取级联列表

GET/api/servers
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 添加级联服务器

POST/api/servers

添加一个上级平台级联配置。

参数类型必填说明
device_idString下级设备 ID(用于 SIP 认证用户名)
realmStringSIP 域
passwordString认证密码
sip_serverString上级服务器地址(IP:端口
local_addrString本地监听地址(IP:端口),TCP 模式下为 TCP 监听端口
transportString传输协议:"UDP""TCP"
versionStringGB/T 28181 协议版本,默认 "2022"
server_idString上级平台 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 删除级联服务器

DELETE/api/servers
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 备份系统配置

POST/api/backup/system

导出所有代理配置、目录管理数据、通道绑定关系。

curl -H "Authorization: Bearer <token>" -X POST http://localhost:3002/api/backup/system -o backup.json

20.2 恢复系统配置

POST/api/restore/system
参数类型说明
clear_beforeBoolean是否清空现有数据再恢复,默认false
stream_proxiesArray拉流代理数组(可选)
stream_pusher_proxiesArray推流代理数组(可选)
admin_region_namesObject行政区域名称(可选)
biz_group_namesObject业务分组名称(可选)
channel_biz_groupObject通道业务分组绑定(可选)
channel_bindingsObject正向通道绑定(可选)
channel_bindings_revObject反向通道绑定(可选)
channel_namesObject通道自定义名称(可选)
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_timeoutRTP超时清理
/hook/on_server_started恢复流代理

22. 通用错误码

状态码/错误码含义
401认证失败(缺少或无效 JWT)
403权限不足(JWT 有效但无对应权限)
422请求体格式错误
500服务器内部错误
code: -1业务错误
code: 0成功

23. 定时任务管理 v0.8.0+

支持截图、录制、会话清理、设备状态同步,以及 定时清理录像 (cleanup_media)定时清理截图 (cleanup_snapshot)

认证:所有管理接口需要 JWT Bearer Token。
内部执行接口:使用 X-Internal-Token 头,仅供 scheduler-server 调用。
调度器扫描间隔:30 秒。

23.1 创建定时任务

POST/api/schedule/tasks
参数类型必填说明
actionStringsnapshot, record, cleanup_sessions, sync_device_status, cleanup_media, cleanup_snapshot
cron_exprStringCron 表达式(UTC)
device_idString条件国标设备ID(snapshot/record)
channel_idString条件通道ID或*
appString条件代理app,也用于 cleanup_media 过滤
streamString条件代理stream,也用于 cleanup_media 过滤
duration_secsInteger录制必须录制时长
enabledBoolean默认true
concurrencyInteger并发数,默认5
callback_urlString任务完成后回调地址
retention_daysInteger清理任务专用:保留天数,默认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 列出所有任务

GET/api/schedule/tasks?page=1&page_size=20
curl -H "Authorization: Bearer <token>" "http://127.0.0.1:3002/api/schedule/tasks?page=1&page_size=20"

23.4 查询单个任务

GET/api/schedule/tasks/{task_id}
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/schedule/tasks/task_xxx

23.5 更新任务

PUT/api/schedule/tasks/{task_id}
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 删除任务

DELETE/api/schedule/tasks/{task_id}
curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/schedule/tasks/task_xxx

23.7 启用/禁用任务

PATCH/api/schedule/tasks/{task_id}/enable
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 内部执行接口

POST/api/internal/task/exec

需要 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 推送状态变化事件。

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 截图接口

POST/api/zlm-snap
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 全部设备通道接口

GET/api/all-channels
curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/all-channels

24.3 主动录像及事件回调

POST/api/start-record-task
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 批量截图接口

POST/api/batch-snap
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 管理用户和权限。

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)

GET /api/admin/users

返回所有已创建的用户名列表。

请求示例

curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/admin/users

响应示例

{
          "code": 0,
          "data": ["alice", "bob", "charlie"]
        }
POST /api/admin/users
参数类型必填说明
usernameString用户名
passwordString密码(明文,服务端会 Bcrypt 加密存储)
permissionsArray权限列表(见 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}
DELETE /api/admin/users/:username

删除用户及其所有权限分配。

请求示例

curl -H "Authorization: Bearer <token>" -X DELETE http://127.0.0.1:3002/api/admin/users/alice

响应示例

{"code": 0}
PUT /api/admin/users/:username/password
参数类型必填说明
passwordString新密码

请求示例

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}
GET /api/admin/users/:username/permissions

返回该用户当前的权限列表。

请求示例

curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/admin/users/alice/permissions

响应示例

{
          "code": 0,
          "data": ["devices:read", "records:read"]
        }
PUT /api/admin/users/:username/permissions
参数类型必填说明
permissionsArray新的权限列表(完全覆盖原有权限)

请求示例

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}
⚠️ 此操作会完全覆盖用户原有权限,请谨慎操作。权限变更后立即生效。
GET /api/admin/users/:username/channels

返回该用户被授权的所有通道(包括设备通道和代理),并附带设备/通道名称等详细信息。

请求示例

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"
            }
          ]
        }
POST /api/admin/users/:username/channels
参数类型必填说明
channel_idString设备通道标识,格式 <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}
DELETE /api/admin/users/:username/channels
参数类型必填说明
channel_idString设备通道标识(同分配接口)

请求示例

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}
POST /api/admin/users/:username/channels/clean

自动扫描用户的所有权限,移除那些设备已不存在、通道已删除或代理已失效的权限。适用于设备下线或代理被删除后的权限清理。

请求示例

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 列表,仅保留有效的条目。
POST /api/admin/users/:username/proxy
参数类型必填说明
appString代理的 app 名称
streamString代理的 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}
DELETE /api/admin/users/:username/proxy
参数类型必填说明
appString代理的 app 名称
streamString代理的 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)

POST /api/mobile/login
参数类型必填说明
usernameString用户名
passwordString密码明文

请求示例

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>
GET /api/mobile/channels

返回当前登录用户被授权的所有通道(包含设备通道和代理),同时附带播放地址、截图 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_snapshotfalse,可调用截图接口主动生成。
GET /api/mobile/play/:channel_id

返回指定通道的播放地址,并在后台异步触发截图(仅对国标设备有效,代理不会自动截图)。

路径参数类型说明
channel_idString通道标识,可以是 <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"
        }
自动截图行为:仅对国标设备有效。服务端会在返回播放地址后,延迟 2 秒尝试请求设备截图,并将结果永久缓存(Redis key snapshot:latest:<device_id>:<channel_id>)。若已有缓存或正在截图,则不会重复执行。
PUT /api/mobile/change-pwd
参数类型必填说明
passwordString新密码

请求示例

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}
GET /api/mobile/snapshot

主动请求通道截图,支持国标设备和拉流代理。对于代理,若流不在线则会尝试按需拉流(依据代理配置的 url),等待流上线后再截图。

查询参数类型必填说明
idString条件必填代理标识,格式 proxy:<app>:<stream>(与 device_id+channel_id 二选一)
device_idString条件必填国标设备 ID(与 id 二选一)
channel_idString条件必填国标通道 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": "拉流超时,流未能上线"
        }
代理截图流程:若流不在线,会查询代理配置并调用 ZLM addStreamProxy 拉流,等待最多 10 秒。若流上线,则执行截图并缓存结果(永久)。
权限校验:无论何种方式,均会校验当前用户是否拥有该通道/代理的权限,否则返回 403。

以上所有移动端接口均需有效的 JWT Token,过期后需重新登录获取。

26. 录像转录(Transcribe)NEW v0.8.0+

将指定设备通道的历史录像片段异步录制为 MP4 文件,并提供播放地址。任务在后台执行,支持去重、并发控制、取消和状态查询。

认证:所有接口需要 JWT Bearer Token。
并发限制:由环境变量 TRANSCRIBE_MAX_CONCURRENT 控制,默认 3 个任务。
防重机制:同一 device_id + channel_id + start_time + end_time 的任务只会执行一次,重复提交直接返回已有的结果。
文件保存:转录出的 MP4 存储在 ZLMediaKit 默认录制目录,受全局清理策略控制(默认保留 7 天)。
原速录制:任务以原速拉取录像流,不会倍速处理。

26.1 启动转录任务

POST/api/playback/transcribe
参数类型必填说明
device_idString国标设备ID(NVR 或摄像头)
channel_idString视频通道ID(注意不能填错,否则任务超时)
start_timeString开始时间,支持格式:2026-08-07 16:00:002026-08-07T16:00:00
end_timeString结束时间,同上
zlm_nodeString指定 ZLMediaKit 节点 ID,不填则自动选择
callback_urlString转录完成后回调通知的 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 状态码codemsg
400-1缺少必填参数或时间格式错误
401-1未授权(缺少或无效 JWT)
409-1任务已在运行中(同一时间段)
429-1并发任务数已达上限

注意:若同一时间段已转录过,接口会直接返回 {"code":0, "msg":"already transcribed", "file_url":"..."},不再创建新任务。

26.2 停止转录任务

POST/api/playback/transcribe/stop
参数类型必填说明
task_idString启动转录时返回的任务 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 查询转录结果

GET/api/playback/transcribe/query
参数类型必填说明
device_idString设备ID
channel_idString通道ID
start_timeString开始时间,格式同启动接口
end_timeString结束时间
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 常见问题

通道 ID 错误:若填入设备不存在的通道 ID,设备将返回 404 Not Found,任务会在约 15 秒后超时失败,请先通过 /api/device-channels 确认正确的通道 ID。
任务“丢失”:服务重启后,正在运行的任务会消失,但 Redis 中的状态键仍保留为 running,导致该时间段无法重新发起转录。可手动删除 Redis 键 transcribe:status:{core}transcribe:task_id:{core} 后重试。

转录后的文件可在 云端录像管理 接口中查询,也可通过返回的 file_url 直接访问。

27. 设备与通道统计 NEW v0.8.0+

获取平台当前设备总数和通道总数,适合运维监控、仪表盘展示。采用 Redis Pipeline 优化,设备数 ≤1 万时响应迅速。

GET/api/stats/summary

请求示例

curl -H "Authorization: Bearer <token>" http://127.0.0.1:3002/api/stats/summary

成功响应

{
  "code": 0,
  "data": {
    "device_count": 128,
    "channel_count": 456
  }
}
字段类型说明
codeint0 表示成功,-1 表示失败
device_countint已注册设备总数(来自 Redis 集合 all_devices 的基数)
channel_countint所有设备通道数量累加(来自 device:{device_id}:channels 缓存)

错误响应

HTTP 状态码响应体说明
401{"code":-1,"msg":"unauthorized"}未认证或 JWT 无效
403{"code":-1,"msg":"forbidden"}权限不足
500{"code":-1,"msg":"internal error"}Redis 异常或内部错误
性能说明:设备数 ≤ 10000 时,接口响应时间通常在几十毫秒内。如果设备量超过一万,建议使用计数器缓存方案或进一步优化。