跳过导航,直接进入主要内容跳过导航,直接进入主要内容跳过导航,直接进入主要内容

MiBee NVR GB/T 28181 指南

本指南介绍 MiBee NVR 的 GB/T 28181(中国视频监控国家标准)集成:SIP 平台配置、设备接入、音频、语音对讲、订阅推送、PTZ、设备录像回放和故障排除。

什么是 GB/T 28181?

GB/T 28181 是中国视频监控网络系统的国家标准,定义了 IP 摄像机、NVR 和平台通过 SIP 和 RTP/PS 通信的方式。MiBee NVR 实现平台角色(UAS — 应答方),这意味着:

  • 设备通过 SIP(UDP 端口 5060,默认)REGISTER 到 NVR
  • 设备发送 Keepalive 心跳维持在线状态
  • NVR INVITE 通道拉取 RTP/PS 媒体流(拉流模式)
  • NVR 将 MPEG-PS 解复用为 H.264/H.265 NALU 与音频帧(G.711/AAC),进入标准录像/直播管线

兼容矩阵:GB/T 28181-2007/2011/2016/2022(见 internal/gb28181/doc.go)。支持的摄像机品牌包括海康威视、大华、宇视和其它 GB28181 兼容制造商。

快速开始

步骤 1:启用 GB28181 服务器

推荐:Web 设置页。打开 NVR Web UI → 设置 → GB28181,打开启用开关并填写参数后保存(密码为只写字段,留空保存表示保持不变)。

GB28181 设置页

等价的 YAML 配置(mibee-nvr.yaml):

gb28181:
  enabled: true
  sip_listen: ":5060"
  server_id: "34020000002000000001"
  realm: "3402000000"
  password: "yourpassword"
  port_range: "30000-30050"
  heartbeat_interval: "60s"
  catalog_interval: "30m"
  media_transport: "tcp-passive"  # udp | tcp-passive | tcp-active(默认 tcp-passive,见下)
  subscribe_catalog: true       # 通道变更实时推送
  subscribe_alarm: true         # 报警订阅
  subscribe_mobile_position: false
  subscribe_expires: "3600s"
  allowed_device_ids: []        # 空 = 允许所有设备注册(启动时会打印 WARN 提示;生产建议显式列出)

关键参数:

  • server_id:NVR 的 20 位 GB/T 28181 平台编号(设备端需完全一致)
  • realm:SIP 摘要认证域(通常为 10 位区域码)
  • password:SIP 摘要认证密码。留空 = 不鉴权(任何能访问 5060 端口的设备都可注册,见"安全考虑")
  • media_transport:RTP 媒体传输 —— tcp-passive(默认,NVR 监听、设备连接,海康/大华 NAT 默认)、udp、tcp-active(NVR 拨向设备应答地址)。默认使用 TCP 的原因(#460):实测 UDP 媒体在真实 GB 相机上丢帧率约 16%(IDR 突发包触发网卡/软中断路径丢包,每次丢帧打断 P 帧参考链,表现为花屏/马赛克直到下个 IDR);同一网络 TCP 丢帧 <1%。个别不支持 TCP 媒体的老设备可改回 udp。

步骤 2:配置摄像机

在 GB28181 摄像机(海康、大华等)上配置 SIP 平台接入:

海康威视(Web UI):网络 → 高级平台接入 —— 服务器地址填 NVR IP、服务器端口 5060、设备 ID 填 20 位国标码、密码与 NVR 一致、启用平台接入。

大华(Web UI):网络 → TCP/IP → 28181 —— 服务器 IP/端口/设备 ID/设备域(realm)/密码与 NVR 一致、启用 28181。

设备应在几秒内 REGISTER 成功。

步骤 3:自动入册(零手动配置)

无需手动添加相机。 设备注册成功后 NVR 自动完成:

  1. 记入设备列表并跟踪在线状态(心跳超时判离线)
  2. 自动查询目录(Catalog),发现全部真实视频通道(组织节点自动跳过)
  3. 每个通道自动创建一台相机(gb-<通道ID>),与 ONVIF/RTSP 相机并列出现在相机列表
  4. 自动 INVITE 拉流开始录像
  5. 自动补全厂商/型号(DeviceInfo),订阅目录变更与报警推送

需要手动绑定特殊通道时,也可以用 YAML 或 Web 表单显式创建:

cameras:
  - id: "hikvision-front-door"
    name: "海康前门"
    protocol: "gb28181"
    gb28181:
      device_id: "34020000001320000001"
      channel_id: "34020000001320000001"
    recording_enabled: true
    enabled: true

步骤 4:开启音频(按相机)

音频默认关闭。在相机编辑页打开 音频 开关(或 API PUT /api/cameras/{id} {"audio_enabled": true})后,PS 流中的音频轨(G.711 A-law/μ-law、AAC)会写入 MP4 音轨并进入直播音频。

功能总览

能力 状态 说明
REGISTER + Digest 鉴权 / 白名单 ✅ 401 挑战、周期重注册、注销、IP 变化自动重建会话
自动入册 ✅ 注册 → 目录 → 通道建卡 → 自动拉流,零手动配置
实时点播(INVITE) ✅ UDP / TCP 被动 / TCP 主动(0x24、rfc4571、auto 组帧)
录像 ✅ H.264/H.265,30s 分片、IDR 对齐、滚动合并
直播 ✅ 经 StreamHub 进 HLS/WebRTC/FLV/WS 全部协议
音频 ✅ G.711 A-law/μ-law + AAC → MP4 音轨 + 直播音频;无 PSM 流自动兜底
语音对讲 ✅ 浏览器麦克风 → 设备扬声器(LiveView 一键对讲)
设备录像检索/回放 ✅ RecordInfo + 回放取流进录像库(Recordings 页)+ 倍速/拖动
PTZ + 预置位 ✅ 方向/变倍/预置位/巡航(FICommand)
目录订阅 ✅ 通道变更实时 NOTIFY,替代纯轮询
报警订阅 ✅ → 事件总线/SSE/REST 环形缓存
移动位置订阅 ✅ 车载/布控球场景,REST 查询轨迹
时钟同步 ✅ 设备发 Query,平台应答标准时间
设备信息/状态自动化 ✅ 厂商/型号自动补全,keepalive 不丢元数据
多级级联(下级角色) ✅ 向上级平台注册、聚合目录、INVITE 转发(见"级联上联")
GB35114 国密 ⏸ 按需评估(见 #341)

配置参考

服务器配置

参数 类型 默认值 描述
enabled bool false 启用 GB28181 服务器
sip_listen string ":5060" SIP UDP 监听地址
server_id string (必填) 平台 20 位国标编号
realm string (必填) SIP 摘要认证域
password string (建议设置) SIP 摘要认证密码;留空 = 不鉴权
port_range string "30000-30050" RTP 媒体端口池("start-end")
heartbeat_interval string "60s" 期望的设备心跳间隔
catalog_interval string "30m" 目录轮询间隔(订阅开启时仅作兜底)
media_transport string "tcp-passive" 媒体传输:tcp-passive / udp / tcp-active(默认 TCP 的原因见上文,#460)
sip_transport string "udp" 信令传输:udp(可叠加 tcp 监听)
tcp_framing string "auto" TCP 组帧:"rfc4571"、"0x24"、"auto"
subscribe_catalog bool true 目录订阅(通道变更实时推送)
subscribe_alarm bool true 报警订阅
subscribe_mobile_position bool false 移动位置订阅(静止相机无需开启)
subscribe_expires string "3600s" 订阅有效期(80% 时自动续订)
allowed_device_ids []string [] 注册白名单(空 = 允许所有)
allow_same_ip_enroll bool false 允许同 IP 双协议并存:即使已有相机从该设备 IP 取流(或 ONVIF 序列号匹配),GB28181 通道仍自动建条目。适用于刻意让 ONVIF + GB28181 并存的场景,#596
sub_channel_probe string "auto" 子通道探测模式:auto(仅探测厂商为海康/大华的设备)/ on(探测所有设备)/ off(关闭),#560
sub_channel_probe_offset int 1 子通道候选码 = 主通道码 + 该偏移(海康惯例 +1;0 = 禁用探测),范围 0–99
alarm_linkage object {enabled: false} 报警联动流(#355):{enabled, duration}——收到报警通知时,对未在推流的报警通道发起 INVITE,保持 duration(默认 "60s")后 BYE;该通道对应的相机要求录像时则保持不断开
security35114 object {enabled: false} GB35114 国密安全(SM2/SM3 证书体系)——见下文 GB35114 安全增强;仅在 -tags gb35114 构建的二进制中生效,默认构建启用时仅告警

tcp_mode(bool)是 media_transport 的旧别名,保留仅为 YAML 兼容,已不再影响默认值(v0.12.0 起默认即 tcp-passive,#460);需要 UDP 请显式设置 media_transport: "udp"。

GB35114 安全增强

gb28181.security35114 节(#714/#707,GB35114 A 级)启用国密证书体系:REGISTER 双向认证 + keyed-SM3 Note 完整性。仅在 -tags gb35114 构建的二进制中生效;默认构建下启用该节只记录一条警告。Digest 认证(password)设备与国密路径并存、互不干扰。

参数 类型 默认值 描述
enabled bool false 启用 GB35114 REGISTER 认证器
platform_cert string (必填) 平台 SM2 签名证书路径(双向挑战时用它签名)
platform_key string (必填) 平台 SM2 私钥路径
device_certs_dir string 空 预置设备证书目录,每设备一个 <deviceID>.pem 文件。可选——设备也可通过 Capability cnonce 上报证书(信任首用);预置是更严格的策略

试点证书签发(无 CA 的实验/小型部署):-tags gb35114 构建附带一条签发命令——

mibee-nvr gen-gb35114-certs --platform-id <20位平台ID>   --device-id <20位设备ID>[,<20位设备ID>...] --out-dir gb35114-certs

自签 SM2 平台身份 + 由平台签发的设备身份(PKCS#8 私钥 0600 + GM/T 0015-2012 证书),输出布局即上表三个路径参数的取值形态(devices/<deviceID>.pem),把设备证书与私钥分发到对应设备即可。签发材料经完整的 Challenge/VerifyRegister/VerifyOK 握手回归验证(两侧 VKEK 一致)。生产部署请改用真实 CA(CFCA 等)签发。

相机配置

参数 类型 描述
protocol string 必须为 "gb28181"
gb28181.device_id string 设备 20 位国标编码
gb28181.channel_id string 通道 20 位国标编码
audio_enabled bool 音频开关(默认 false,开启后录 MP4 音轨 + 直播音频)
gb28181.sub_channel_id string 探测到的子码流通道编码(自动回填,fill-once;清空后重启可重新探测)。有值时 ?quality=sub 与子流转发可用,#560

子码流(子通道探测,#560)

GB 设备的子码流通常不在目录里——海康系设备按通道编码偏移(主码流码 +1)隐式存在。NVR 在设备入册并稳定取流后,按厂商惯例对每个已绑定相机的主通道做一次子通道探测(一次额外 INVITE,进程生命周期内最多一次):

  • 成功(子通道有媒体流):探测码自动落 gb28181.sub_channel_id(fill-once),/api/cameras/{id}/protocols 如实回报 sub_stream.available=true,?quality=sub(WS/FLV/HLS/WHEP 宫格与级联子流转发)即可用
  • 失败(404/超时/486):静默放弃,相机保持无子流的降级路径,零错误状态
  • 偏移量可配(sub_channel_probe_offset,默认 1);auto 模式只对 DeviceInfo 厂商为海康(Hikvision/海康)/大华(Dahua/大华)的设备探测,自研设备零打扰
  • 已回填的 sub_channel_id 不会被覆盖;清空该字段并重启 NVR 可重新触发探测
  • 目录里已存在的兄弟通道码(如多通道 NVR 的 02/03)绝不会被当作子码流复用

音频

  • 编解码:G.711 A-law / μ-law(8kHz)、AAC(ADTS 封装自动转 ASC)
  • 开关:按相机 audio_enabled,关闭时丢弃解复用出的音频帧
  • 无 PSM 流兜底:部分固件把音频复用进 PS 流但不发 PSM(或 PSM 不声明音频)。NVR 按优先级判定编解码:PSM 声明 → INVITE 应答 SDP a=rtpmap → 字节启发式(ADTS 同步字 → AAC;μ/A-law 按静音簇投票,4KB 内静音样本 μ-law 聚 0xFF/0x7F、A-law 聚 0x55/0xD5)。判定时记 INFO 日志 codec inferred
  • 无 PTS 音频:按样本数推进时间线,兼容省略音频 PTS 的固件
  • 设备端接入要求(推荐做法):音频复用进同一路 PS/RTP 流(同端口同 SSRC),PSM 声明音频(stream_type 0x90=μ-law / 0x91=A-law / 0x0F=AAC,stream_id 0xC0-0xDF),G.711 发 8kHz 单声道裸字节

语音对讲

LiveView 页国标相机有 对讲 按钮:浏览器麦克风 → AudioWorklet 降采样到 8kHz → A-law 编码 → WebSocket 上行 → NVR 发起 audio-only INVITE(m=audio ... RTP/AVP 8,a=sendrecv)→ 设备接收地址收 RTP。半双工:直播音频与对讲下行并存。

API:GET /api/cameras/{id}/gb28181/talk(WebSocket,二进制帧 = A-law 字节)、GET /api/cameras/{id}/gb28181/talk/status。

级联上联(下级角色)

NVR 可作为下级平台向上级 GB/T 28181 平台上联:本机相机聚合为国标目录上报,上级 INVITE 任意通道时以 RTP/PS 转发媒体(纯封装不转码)。上级无需特殊支持——任何标准平台(包括另一台 MiBee NVR 的平台角色)即可对接。

gb28181_cascade:
  enabled: true
  server_domain: "34020000002000000001"   # 上级平台 20 位编号
  server_addr: "192.168.1.10:5060"       # 上级 SIP 地址
  local_device_id: "34020000001320000099" # 本 NVR 作为下级设备的编号
  realm: "3402000000"
  password: "..."                          # encrypt-config 加密
  sip_listen: ":5061"                      # 级联信令端口(与平台角色 5060 并存)
  heartbeat_interval: "60s"
  register_expires: 3600
  hub_activation_timeout: "10s"           # 多级级联:上级点播未在录 GB 子相机的按需激活限时(#451)

行为要点:

  • 通道编号按相机首次入目录顺序分配(<编号前10位>132+7位序号),持久化防重启变号——上级的绑定始终有效
  • REGISTER + Digest、Expires 80% 续注、Keepalive;上级重启(keepalive 403)立即重注册
  • 目录应答聚合全部非 MJPEG 相机;H.264/H.265 由首帧 NAL 嗅探决定 PSM 类型
  • 上级 INVITE → 200 OK(sendonly) → 从 StreamHub 取流 → PS 复用 → RTP 推送;BYE/错误清理
  • 目录收敛(cameras[].cascade_enabled: false):该相机从聚合目录隐藏、对其通道的 INVITE 返回 404,但通道编码分配保留——重新开启即恢复原编码,上级绑定不漂移
  • 级联上报子码流(cameras[].cascade_sub_stream: true):INVITE 转发改走相机按需拉取的子码流——低分辨率档让上级预览不再吃满上行带宽;相机无子码流或拉取失败自动回退主流,无子码流的相机不受影响
  • 多级级联按需激活(gb28181_cascade.hub_activation_timeout,#451):上级点播一个当前未在录的 GB 子设备通道时,中间级先向该子设备发起本地 INVITE(限时默认 10s),拿到流再转发——超时回 500 不建立无媒体对话,BYE 后按空闲回收本地拉流;已激活引用随会话释放。非 GB 相机不走此路径
  • 多上级上联(gb28181_cascade.upstreams,#370):单上级表单之外可配置任意数量的额外上级——每条独立运行自己的 REGISTER/Keepalive 会话(共享 SIP 监听端口),独立在线状态;字段留空回退单上级表单值
  • v1 限制:仅视频(hub 音频暂不区分 G.711 A/μ 律);不推送目录变更 NOTIFY(上级轮询兜底)

多上级配置示例:

gb28181_cascade:
  enabled: true
  server_domain: "34020000002000000001"   # 首个上级(单上级表单仍是第一个 upstream)
  server_addr: "192.168.1.10:5060"
  local_device_id: "34020000001320000099"
  realm: "3402000000"
  password: "..."
  upstreams:                               # 额外上级(#370)
    - server_domain: "34020000002000000002"
      server_addr: "192.168.1.11:5060"
      local_device_id: "34020000001320000098"  # 该平台分配给本机的编号(可各不相同)
      realm: "3402000000"
      password: "..."
      heartbeat_interval: "60s"            # 可选:覆盖该上级的保活节奏
      register_expires: 3600               # 可选:覆盖该上级的 REGISTER 有效期

订阅与事件

  • 目录订阅:设备通道变更通过 NOTIFY 实时推送(合并进通道表并自动建卡)
  • 报警订阅:GET /api/gb28181/devices/{id}/alarms 查询环形缓存(最近 200 条),同时进事件总线(SSE gb28181.alarm)
  • 移动位置订阅:GET /api/gb28181/devices/{id}/positions 查询位置轨迹
  • 三个开关与有效期见设置页 / 上表;到期前 80% 自动续订

设备录像检索与回放

Recordings 页可按国标通道检索设备侧存储的录像(RecordInfo)并取回:取回片段经正常录像管线落盘(分段、记录行),在 Recordings 页直接播放,支持倍速/拖动(INFO 控制)。

API:

  • GET /api/gb28181/channels/{id}/records?start=&end= — 检索设备录像列表
  • POST /api/gb28181/channels/{id}/playback — 开始取回(body 含 start/end)
  • GET /api/gb28181/channels/{id}/playback — 取回进度
  • DELETE /api/gb28181/channels/{id}/playback — 停止
  • POST /api/gb28181/channels/{id}/playback/control — 倍速/拖动/暂停

PTZ 控制

PTZ 经 MANSCDP DeviceControl 下发。支持方向(含对角)、变倍(需 PTZType=2)、预置位/巡航(FICommand)。通道的 PTZType 来自目录报告(0=无、1=云台、2=云台+变倍)。

Web UI:LiveView 相机页 PTZ 面板(按住移动、松开停止、预置位调用/设置)。

curl -X POST http://localhost:9090/api/gb28181/channels/34020000001320000001/ptz \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic base64(username:password)" \
  -d '{"direction": "up", "speed": 128}'

方向:up/down/left/right/up-left/up-right/down-left/down-right/zoom-in/zoom-out/stop。

API 参考

设备与通道

  • GET /api/gb28181/devices — 已注册设备(支持 ETag)
  • GET /api/gb28181/devices/{id}/channels — 设备通道列表
  • POST /api/gb28181/devices/{id}/catalog-refresh — 触发目录刷新(202)
  • GET /api/gb28181/devices/{id}/alarms — 报警环形缓存
  • GET /api/gb28181/devices/{id}/positions — 移动位置轨迹

媒体会话

  • POST /api/gb28181/channels/{id}/invite / bye — 手动拉流/停流
  • POST /api/gb28181/channels/{id}/ptz — PTZ 控制

按需抓拍与手动录像(GB/T 28181-2022)

  • POST /api/gb28181/channels/{id}/snapshot — 向设备下发 SnapShotCmd 按需抓拍({"snap_num":1,"interval":0});设备把 JPEG 回传到公共回调端点 POST /api/gb28181/snapshot/upload?session=<SessionID>,帧保存至 snapshots/gb-<通道ID>/ 并触发 camera.snapshot 事件;会话在收到设备完成通知后关闭,超时未收到通知则判为失败
  • POST /api/gb28181/channels/{id}/record — 手动开始 / 停止录像({"action":"start"} / {"action":"stop"},对应 RecordCmd)

录像检索/回放(设备侧)

  • 见上节

语音对讲

  • GET /api/cameras/{id}/gb28181/talk(WebSocket)、GET .../talk/status

错误响应

状态 场景
400 请求体缺失/畸形;不支持的 PTZ
404 通道不存在
409 设备离线
500 内部错误(MANSCDP 编码/发送失败)

故障排除

设备未注册

  1. 确认 sip_listen 监听(ss -ulnp | grep 5060)与防火墙放行 UDP 5060
  2. 核对设备端五要素:服务器 IP/端口 5060/服务器 ID(须与 server_id 完全一致)/域(realm)/密码
  3. 看日志:journalctl -u mibee-nvr -f | grep -i gb28181 —— REGISTER auth failed = 密码不匹配;not in allowlist = 白名单
  4. 改过 NVR 密码后:设备下一次重注册(≤1 个注册周期)会 403 掉线,设备端同步修改后自动恢复,无需重新入册

视频黑屏 / 无流

  1. 检查 port_range 未耗尽、防火墙放行该 UDP 段
  2. NAT 场景切换 media_transport: tcp-passive
  3. TCP 组帧报错时依次尝试 tcp_framing: rfc4571 / 0x24 / auto
  4. 编码:H.264/H.265 自动探测,无需配置

花屏 / 马赛克(图像下半截模糊有码)

典型症状:画面某区域(常见下半屏)出现马赛克/色块,数秒后随下一个关键帧恢复,周而复始。根因是 UDP 媒体丢帧(IDR 突发包触发丢包 → P 帧参考链断裂,#460 实测丢帧率可达 16%):

  1. 确认 media_transport 为默认的 tcp-passive(若曾被改为 udp 请改回)
  2. 已是 TCP 仍花屏 → 检查 tcp_framing(依次尝试 rfc4571 / 0x24 / auto)
  3. 服务器端可对照接收日志中的 gap_skipped / AU ended mid-PES 计数定位丢包位置

音频无声

  1. 确认相机 音频开关 已开启(audio_enabled,默认关)
  2. 看日志 codec inferred —— 无 PSM 设备会自动判定编解码;若始终无此日志且无音轨,抓包确认设备确实把音频复用进了 PS 流
  3. 设备端推荐做法见"音频"节;无 PSM 也能出声(自动兜底),但其它平台(ZLMediaKit 等)会丢,建议设备侧补 PSM 声明

会话周期性回收重邀

日志出现 recycling stale session reason=no keyframe 且录像每隔约一分多钟有空窗:设备关键帧间隔(GOP)超过 NVR 的 75 秒看门狗。属正常自愈行为(重邀强制出新 IDR),但建议把设备 GOP 收敛到 2-4 秒。

REGISTER 源端口轮换

部分 SIP 栈每个 REGISTER 换源端口。NVR 仅按 IP 判断地址变化,端口轮换不会回收会话,无需处理。

心跳超时掉线

设备心跳间隔与 NVR heartbeat_interval(默认 60s)不匹配时调整任一侧。

字符集乱码(GBK vs UTF-8)

MANSCDP 编解码器自动处理:剥离 XML 声明、UTF-8 校验、GB18030/GBK 回退。仍乱码时检查设备端编码设置。

时钟同步

设备因时钟漂移鉴权异常或录像检索时间不对时:NVR 自动应答设备的 TimeSync 查询;两侧建议均同步 NTP。

限制与已知问题

  • 设备自注册伪通道:NVR 重启后,多通道目录设备会短暂出现一台"设备自身通道"的相机(不推流)。已知问题,重启后手动归档即可,跟踪于 #352
  • 对讲真机覆盖:语音对讲目前经模拟器 E2E 验证,真机回环验证跟踪于 #353
  • TCP 0x24 组帧:非标准扩展(GB/T 28181-2016/2022 指定 RFC4571),混合部署用 auto
  • 多级级联 / GB35114:未实现,按需评估(#341)
  • 报警联动点播:报警事件已进总线,联动自动拉流跟踪于 #355

安全考虑

  • 鉴权:务必设置 password(留空 = 任何可达设备都能注册)。配合 allowed_device_ids 白名单双层防护
  • 传输:SIP/RTP 为明文(GB35114 国密/TLS 未实现)。公网部署必须用防火墙/VPN 收敛暴露面,勿直接暴露 5060 与端口池
  • 端口池:默认 51 路,按并发需求扩展(RPi 3B 建议 <200)

支持资源

页面已加载完成,可访问性功能已启用
页面已加载完成,可访问性功能已启用
页面已加载完成,可访问性功能已启用