做视频接入的项目,只要涉及公安、教育、政务、交通,绕不开 GB/T 28181。这个标准把不同厂商的摄像头、NVR、平台统一到一套信令体系上,理论上「接入即互通」。
实际做起来,理论归理论。我参与过的国标项目里,能一次接通的不到三成。问题高度集中在三处:注册成功但取不到流、取到流但播不了、级联后下级设备不上线。
这篇把这三处的成因和排查路径讲清楚。
一、先理解结构:SIP 管信令,RTP 管码流
很多人一开始就搞混,因为国标里两套协议交织在一起。
| 协议 | 作用 | 端口 |
|---|---|---|
| SIP | 设备注册、目录查询、邀请推流、云台控制、报警订阅 | 默认 5060(UDP/TCP) |
| RTP / PS | 实际音视频码流传输 | 动态分配,通常在 30000-40000 区间 |
流程是:平台向设备发 INVITE(SIP),设备返回 200 OK 并告诉平台「我会把流推到某个 IP:Port」(SDP 里的 m=video 行),然后设备用 RTP 往那个地址推 PS 封装的码流。
关键点:信令通不代表码流通。SIP 走 5060,RTP 走另一个端口。防火墙只放了 5060,就会出现「注册成功、目录能查、点播放没画面」的经典现象。
二、坑一:注册上了但取不到流
表现:平台能看到设备在线,能查到通道列表,点播放一直转圈或者提示超时。
成因一:RTP 端口没放通
最常见。设备把流推到平台的某个端口,这个端口被防火墙拦了。排查方法:
- 在平台侧抓包,看有没有收到设备的 RTP 包
- 如果收到 SIP 的 INVITE 和 200 OK,但没收到 RTP,基本可以确定是端口问题
- 临时把平台放在公网或者关掉防火墙测试,能通就是防火墙问题
解决:把 RTP 端口范围整段放通(比如 30000-40000 UDP),或者用平台的端口收敛功能(有些平台支持只用一个端口收所有流)。
成因二:NAT 导致 SDP 里的地址不可达
设备在内网,平台在公网。设备在 SDP 里填的是自己的内网 IP(比如 192.168.1.64),平台按这个地址去收流,收不到。
解决:
- 平台侧开启「强制使用信令源地址」,忽略 SDP 里的 IP,用 SIP 报文的实际源 IP
- 或者设备侧开启 NAT 穿透,配置公网映射地址
- 或者部署在同一个网络里,绕开 NAT
成因三:通道 ID 填错
国标的通道 ID 是 20 位数字,格式是「中心编码 8 位 + 行业编码 2 位 + 类型编码 3 位 + 网络标识 1 位 + 序号 6 位」。设备目录查询返回的 ID 必须原样使用,不能截断、不能补零。
有些设备的目录响应里 ID 是 20 位,但实际推流时要求用 18 位或者带前缀,这种属于厂商不标准。遇到只能按厂商文档来。
成因四:设备侧通道没启用或者被占用
NVR 上的某个通道被本地录像占满,或者被另一个平台占用(很多设备同时只支持 1-2 路并发取流)。点播放前先确认这个通道没被别的地方用着。
三、坑二:取到流了但播不了
表现:抓包能看到 RTP 包在进,但播放器黑屏、花屏、或者只出声没图像。
成因一:PS 封装解析问题
国标规定码流用 PS(Program Stream)封装。PS 是 MPEG-2 体系里的容器格式,里面包着 H.264/H.265 视频和 G.711/AAC 音频。
问题在于:很多播放器不支持直接播 PS。浏览器的 video 标签只认 MP4、WebM,不认 PS。所以平台通常要做转封装——把 PS 拆成裸 H.264 流,再转成 FLV 或者 WebRTC 输出给前端。
如果平台不做转封装,直接给浏览器推 PS,必然播不了。这不是配置问题,是架构缺失。
成因二:I 帧丢失导致花屏
H.264 的 P 帧和 B 帧依赖 I 帧。如果平台从流中间开始接收,第一个包不是 I 帧,解码器就无法还原画面,表现为持续花屏直到下一个 I 帧到来。
国标默认 GOP 可能长达 100 帧(4 秒),意味着花屏可能持续 4 秒。解决:
- 设备侧把 GOP 调小(比如 25-50 帧)
- 平台侧缓存最近的 I 帧,新观众接入时先发 I 帧
- 播放端请求关键帧(国标支持 SIP INFO 消息请求 I 帧)
成因三:时间戳不连续
PS 流里的 PTS/DTS 时间戳如果跳变,播放器会卡顿或者加速。有些设备在断流重连后时间戳从头开始,导致播放端时间轴错乱。
排查:抓包看 RTP 头里的 timestamp 字段是否连续递增。如果不连续,问题在设备侧。
四、坑三:级联后下级设备不上线
级联是指上级平台通过国标对接下级平台,把下级平台的设备和视频资源纳入统一管理。典型场景:区级平台对接市级平台,市级平台对接省级平台。
级联的注册方向容易搞反:下级平台作为 SIP 客户端,向上级平台注册。也就是说,配置「上级平台地址」的是下级平台。
成因一:SIP 域和 ID 不匹配
国标要求 SIP 域是 10 位数字(通常是行政区划代码),平台 ID 是 20 位。上级平台配置的下级域/ID,必须和下级平台自己配置的完全一致,一个字符都不能差。
常见错误:下级配了 34020000002000000001,上级填了 3402000000200000001(少一位),注册被拒但日志只显示「认证失败」,看不出是位数问题。
成因二:目录订阅没有正确响应
级联建立后,上级会发 SUBSCRIBE 订阅下级目录。下级要回 200 OK 并主动推 NOTIFY 上报设备列表。如果下级不推 NOTIFY,上级看不到任何设备。
有些下级平台只支持「查询」不支持「订阅」,需要上级主动发 Catalog 查询。检查上级平台有没有配置自动目录查询。
成因三:媒体流走错路径
级联取流有两种模式:
- 上级直接向下级设备取流:要求上级能直接访问到下级设备的 IP
- 下级平台转流:上级向下级平台取流,下级平台再从设备取流转发
第一种模式在跨网、跨 NAT 场景下基本走不通。选第二种更稳,但下级平台的转流能力(并发路数、带宽)要够。
成因四:心跳超时导致反复掉线
国标要求下级定期发 MESSAGE 心跳,默认 60 秒。如果上级的超时判断设得比心跳间隔短,会不停判定下级离线。
排查:看上级日志里下级的注册/离线记录,如果是规律的周期性掉线,就是心跳参数不匹配。
五、排查顺序:按这个顺序走,别乱试
遇到问题不要一上来就改配置,按链路顺序排查效率最高:
- SIP 能注册吗? 看平台日志有没有收到 REGISTER,返回 200 还是 401/403
- 目录能查到吗? 查不到说明注册后没有正确响应 Catalog 查询
- INVITE 发出去有响应吗? 有 200 OK 说明信令通,没响应说明设备侧拒绝或网络不通
- RTP 包收到了吗? 抓包看。没收到查端口和 NAT,收到了查封装和时间戳
- 能解码吗? 拿到裸流用 VLC 试播,能播说明平台转封装有问题,不能播说明码流本身有问题
这个顺序能把「信令层」和「媒体层」的问题分开,避免在错误的层次上浪费时间。
六、几个工程上的建议
1. 端口规划提前做
一个 500 路并发的平台,RTP 端口范围要预留足够。按每路 2 个端口(RTP + RTCP)算,需要 1000 个端口。规划时按峰值的 1.5 倍留。
2. 保持设备和平台的时钟同步
国标信令里的时间戳依赖 NTP。设备时间偏差超过 5 分钟,某些平台会拒绝注册。所有设备和平台都配 NTP。
3. 抓包工具必备
Wireshark 加国标解码插件,能直接看 SIP 消息内容和 RTP 流统计。没有抓包能力,排查效率会低十倍。
4. 保留原始码流
平台侧把收到的 PS 流落一份原始文件(哪怕只保留 1 分钟),出问题时能直接分析。这比反复复现问题快得多。
5. 厂商兼容性要提前测
不同厂商的国标实现差异很大,尤其是目录结构、云台控制指令、报警上报格式。项目开始前拿实际设备测一遍,别等到交付前才发现不兼容。
写在最后
GB/T 28181 的文档写得很细,但细不等于好实现。标准本身留了很多「可选项」和「厂商自定义」的空间,导致不同厂商的实现看起来都符合标准,实际互通时全是问题。
做这类项目,预留 30% 的工期给兼容性调试是合理的。如果你按理论工期排,大概率会延期。