简介:一份面向安防与视频监控领域的28181平台对接接口说明文档,聚焦下级平台与上级平台之间的SIP通信流程。文档详细拆解了平台注册与心跳保活两大核心环节,包括REGISTER信令的完整交换过程、401鉴权挑战与应答、基于MD5的摘要认证,以及Keepalive心跳消息的交互机制,可直接作为开发者和维护者进行二次开发或联调时的接口参考。资源为单个doc文档,共85KB,内容精炼,适合需要快速掌握GB/T 28181平台对接接口的技术人员。目前已有291人学习下载。通过文中给出的真实信令示例,读者可以直观理解从REGISTER请求到200 OK的完整鉴权流程,并能对照排查实际对接过程中常见的鉴权失败、心跳超时等问题。整体结构清晰,便于按需查阅信令格式与字段含义。
1. 28181平台对接接口不是一份死文档,是你跑通视频对接的“信令地图”
《28181平台对接接口详解.doc》这类文档,我拿到手一般先不急着照配置,而是先把它当成一张信令地图。因为大部分对接失败不是IP填错,而是不知道接口背后跑的是SIP注册、目录订阅和媒体协商三段流程。28181指GB/T 28181,是视频监控领域里设备与平台、平台与平台互联的国家标准,它把SIP当作会话控制通道,再用RTP/RTCP传视频码流。平台对接接口要解决的核心问题就三个:设备注册、目录下发、实时点播。这篇笔记会从接口骨架、参数配置、抓包验证、现场排错一直讲到平台级联,适合刚接手国标对接的运维、集成商和平台开发。
2. 接口骨架:先分清会话控制和媒体流,再谈调通28181
2.1 接口从哪来:GB/T 28181在SIP上扩展了什么
很多搞了多年网络的人第一次看28181会蒙,因为它的注册流程像SIP,但目录查询、云台控制、报警上报又全是自定义的XML消息。其实GB/T 28181选用了SIP作为基础协议,语音和视频的呼叫控制都沿用SIP方法,但为了让监控域里的设备能互相发现和管理,又定义了一套消息体,固定使用Content-Type: Application/MANSCDP+xml。
MANSCDP可以理解成“面向监控设备的会话描述与控制协议”,所有目录查询、设备状态、云台控制、报警通知的请求和响应,都打包在这类XML里。而媒体流走的是另外一条通道,用RTP承载PS封装后的视频码流。所以对接接口要了解的第一件事就是:信令面一旦通了,只能说明注册和消息能到对方;媒体面要另测RTP,两者不能混在一起调试。
因此在看任何一份28181接口文档时,我习惯了先把章节分为信令和媒体两大类。信令类主要看SIP方法、消息体、鉴权方式;媒体类主要看SDP协商、RTP端口、封装格式。后面的抓包和排错也都是顺着这个分法进行的。
2.2 一个最小注册流程:REGISTER、401质询与200 OK
设备要接入28181平台,第一步就是SIP注册。完整的交互不是设备发一次REGISTER就完,而是一个标准的Digest鉴权过程,抓包你会看到四帧。
| 方向 | SIP方法 | 关键头字段 | 含义 |
|---|---|---|---|
| 设备 → 平台 | REGISTER | To/From: 设备SIP ID;Contact: 设备IP和端口 | 发起注册请求 |
| 平台 → 设备 | 401 | WWW-Authenticate: Digest realm=..., nonce=... | 要求做摘要鉴权 |
| 设备 → 平台 | REGISTER | Authorization: Digest uri=..., response=... | 携带密码计算的摘要 |
| 平台 → 设备 | 200 | Expires: 3600 | 注册成功,有效期1小时 |
这四帧看懂了,以后排查注册问题会很快。第1帧里的To和From都是设备的20位SIP ID,比如34020000001320000001;Contact记录设备的实际IP和端口,平台会把这个地址当成后续信令的发送目标。第3帧的response是用用户名、密码、nonce等算出来的MD5摘要。如果两者密码不同,平台会回403或直接忽略。
注册成功后的Expires字段很关键,代表注册有效期。多数设备默认3600秒,平台在到期前会收到设备的刷新REGISTER,如果设备离线或网络中断,平台会在超时后把它标记为离线。对接调试时我喜欢把这个值临时改小到60秒,这样快速测心跳是否正常。
2.3 目录查询与订阅:MESSAGE和SUBSCRIBE各管哪一段
设备注册上线后,平台要知道这台设备下有哪些摄像机通道,这就有两个办法:一次性查询和持续订阅。这两个接口经常被混为一谈,但实际走的是不同的SIP方法。
一次性目录查询用MESSAGE,平台主动发一条XML到设备,设备先回一个200 OK表示收到,随后再发一条MESSAGE带查询结果给平台。典型查询消息体是这样:
<Query> <CmdType>Catalog</CmdType> <SN>100</SN> <DeviceID>34020000001320000001</DeviceID> </Query>CmdType是操作类型,查询目录固定填Catalog;SN是消息序号,每次请求增加即可,用于把响应和请求对应起来;DeviceID是被查询的设备ID,可以填设备本身,也可以填某个通道ID。设备返回的XML里CmdType是CatalogResponse,下面挂Item列表,每个Item代表一个通道,里面有DeviceID、名称、状态、经纬度等。
持续订阅用的是SUBSCRIBE。平台向设备发SUBSCRIBE,头域Event: Catalog,设备收到后先回200,等目录变化时再主动给平台发NOTIFY。这个接口适合上级平台需要实时感知通道增减的场景,但很多低端NVR只实现了MESSAGE查询,对SUBSCRIBE是回200不动作。所以遇到“订阅已成功,目录却一直不更新”的问题,先抓包看平台是不是真的发了NOTIFY,如果没有,基本上就是设备没实现订阅通知,老老实实改成轮询查询。
2.4 实时点播INVITE:SDP里媒体参数怎么填才能拉到流
设备注册和目录都通了,接下来就是拉流。平台向设备发INVITE,设备回200 OK,媒体流就通过RTP到达平台。INVITE的SDP是媒体协商的核心,我常看到接口文档写得很简单,实际平台上却因为SDP方向填错导致黑屏。
一份标准且兼容性最好的SDP长这样:
v=0 o=34020000001320000001 0 0 IN IP4 192.168.1.100 s=Play c=IN IP4 192.168.1.100 t=0 0 m=video 5000 RTP/AVP 96 a=rtpmap:96 PS/90000 a=recvonlyo=里的IP是媒体接收地址,c=也一样,平台会把后续RTP流发到这个IP上的m=端口。s=Play表示实时点播,回放时常见是Playback。a=rtpmap:96 PS/90000说明用RTP承载PS封装,时间戳频率90000。a=recvonly表示平台只收流,方向一定要写对。
设备回200 OK后,平台要再发一个ACK完成三次握手,然后设备才开始推流。如果漏了ACK,设备会不断重发200,但RTP就是不来。调试时看到这个现象,先检查平台代码或日志里ACK是否发出去。
3. 平台对接接口落地:必填参数、抓包验证与一条龙调试
3.1 对接前必填的六个核心参数:IP、端口、SIP ID、域、密码与通道数
在线下给客户做对接时,我最先做的一件事就是整理一张参数表,让两端工程师按着表填,比翻文档效率高一倍。六项里最容易被忽略的是SIP域和通道ID的编码规则。
| 参数 | 示例值 | 说明 |
|---|---|---|
| SIP服务器IP | 192.168.1.10 | 平台的SIP监听地址 |
| SIP服务器端口 | 5060 | 默认UDP端口,有些平台用TCP 5060,要先确认 |
| 设备SIP ID | 34020000001320000001 | 20位编码,前8位是中心编码 |
| 设备密码 | 12345678 | 参与REGISTER摘要鉴权 |
| SIP域 | 34020000 | 通常取SIP ID前8位 |
| 通道数/通道ID | 34020000001320000002 等 | 每个摄像机一个编号,最后一个通道号不同 |
SIP ID的20位编码看上去玄学,实际有规律:前8位中心编码代表区域,中间4位是类型和行业编码,后7位是序号和校验位。对接时如果平台要求通道ID的前8位和SIP域一致,那就确认平台是按中心编码限制接入的。密码基本都是8位数字,但有的国标平台支持字母和符号,建议先沿用设备出厂密码,通了再改。
端口方面,SIP信令默认走UDP 5060。如果设备端用的是TCP 5060,平台也要开启TCP监听;两边不匹配时设备报文发出去,平台根本没收到。很多设备会把信令和媒体分成两个线程,信令注册成功但媒体端口没监听,这会在点播时报对端不可达。
3.2 用sngrep和Wireshark看信令:三个关键过滤表达式
排查28181对接问题,不能只靠平台日志。平台日志经常只说“设备离线”,不告诉你为什么。我的习惯是在设备侧或者平台侧镜像口抓包,用sngrep看信令交互,用Wireshark做深挖。sngrep是字符界面工具,一条命令就能把SIP对话按会话列出来,非常直观。
sudo sngrep -d eth0 -p 5060-d指定抓包网卡,-p指定SIP端口。运行后能看到所有SIP消息,按tab键展开某一通会话,能直接看到REGISTER、401、200 OK的完整报文。如果现场没有sngrep,用tshark也一样:
sudo tshark -i eth0 -Y "sip || rtsp" -w 28181_debug.pcap保存的pcap可以带回办公室在Wireshark里看。在Wireshark里我常用的过滤器有三个:sip.Method==REGISTER只看注册方法;sip.Status-Code只看所有响应码,配合时间排序可以很快找到哪一步卡住;rtp只看媒体包,用来判断RTP到底有没有来。这三个过滤表达式中,sip.Status-Code是最能说明问题的,看到401说明鉴权流程正常,看到403说明密码错,看到480说明设备暂时不可用,看到488则通常是不接受SDP。
现场不方便装工具的时候,也可以配合udp抓包。很多嵌入式设备不带sngrep,但能ping通平台IP,这时用nc -u -zv 192.168.1.10 5060只能测UDP通不通,测不出SIP语义,所以最可靠的办法还是镜像抓包。
3.3 从发起注册到平台显示在线:七步操作清单
把上面的参数整理好,接下来的调试顺序要固定,避免东一榔头西一棒子。我一般按七步走:
- 在设备或接入网关里填入SIP服务器IP、端口、SIP ID、域和密码。
- 在平台上添加设备,填入同样的SIP ID和密码,有些平台还需要勾选“主动注册”或“被动注册”。
- 设备端启动注册,观察平台在线状态。
- 如果离线,抓包看有没有REGISTER发出、平台有没有回401。
- 若401之后没有第二个REGISTER,检查密码或摘要算法不一致。
- 若注册成功,发一次目录查询,确认设备把所有通道上报。
- 选一个通道发起实时点播,用sngrep确认INVITE、200、ACK完整,再用VLC拉流验证。
第七步最容易踩坑。很多平台显示“点播中”,但VLC里黑屏,问题往往不是信令,而是RTP端口不通。建议在平台侧先确认媒体端口范围,然后在设备侧放通对应UDP端口。如果现场是跨网段的,还要检查路由器和防火墙有没有放行RTP端口,不要只开5060。
4. 对接中最容易翻车的五个坑:从离线到黑屏的现场排错
4.1 设备注册不上,平台日志报401却不再回应
现象:设备配置无误,平台在线列表却一直离线。抓包看到设备发REGISTER,平台回了401,但设备没有发第二个REGISTER。
原因:两个最常见。一是密码不一致,设备用A密码计算摘要,平台用B密码验算,必然对不上;二是部分设备在收到401后,默认走RFC2617的MD5算法,而平台要求的是MD5-sess或带uri校验的算法,如果设备没有可选项,就会一直停在401状态。
解决:先把两端密码都改成出厂默认值,比如12345678。再看抓包里Authorization头的algorithm字段,如果平台要求MD5-sess,而设备发的是MD5,就需要在设备配置里找“摘要算法”选项。有些NVR厂家将选项藏在“SIP高级配置”里,不仔细看根本发现不了。最后检查设备系统时间,如果设备时钟差了几分钟,也会导致摘要中的nonce也算不对,平台宁可沉默也不回错。
4.2 注册成功目录不出:只查到一条根节点
现象:设备已在线,平台上点击刷新目录,转几圈后只显示一个设备根节点,没有摄像机通道。
原因:这类问题经常不是信令没通,而是通道ID规划不一致。平台发送的目录查询DeviceID是设备ID,设备返回的Item里每一个通道ID都有独立的20位编码。如果通道ID的前8位中心编码和平台规划的域编码不一致,平台会直接丢弃这些通道,只留下根节点。另一种可能是平台对通道类型做了过滤,比如只接受编码类型为“摄像机”的通道,而设备上报的是“视频服务器”。
解决:打开抓包里的目录查询响应XML,复制一个Item里的DeviceID,和平台要求的域编码对比。如果前8位不同,需要在设备端重新配置通道编码。还要看Status字段,是ON还是OFF,有些平台不显示离线通道。这里提醒一句:很多设备默认通道ID不是规范的20位数字,需要人工补齐,别指望设备自己改。
4.3 实时点播黑屏:信令正常却收不到RTP包
现象:INVITE、200 OK、ACK三帧都正常,平台显示正在播放,但画面黑屏,抓包里一封RTP都没有。
原因:SDP里媒体接收地址和端口写错了。平台作为收流方,会在m=video后面写上自己的一个UDP端口,设备会向这个端口发RTP。如果平台的实际媒体监听地址和c=里的IP不一致,比如平台有两个网卡,SDP里写的是内网地址,而设备从另一个路由过来,数据包就被丢了。
解决:抓包时除了看SIP,还要看平台有没有向设备发送过RTP。如果没有,说明设备压根没收到ACK或者SDP方向是sendonly。如果设备发过RTP但平台没收到,就用tcpdump -i eth0 udp port 5000在平台侧看到底有没有包到达。还有一个常见做法是让设备改用TCP传输,在SDP里加上a=transport:TCP,这样能避开UDP端口不通的玄学问题,代价是延迟略高。
4.4 云台控制指令发了没反应
现象:平台上点“右转”,设备在抓包里明明收到了MESSAGE,也回了200,但云台不动。
原因:MESSAGE只是把XML发给设备,设备回200只代表“接收成功”,不代表“执行成功”。PTZ命令的CmdType虽然是Control,但真正的方向指令在PTZCmd字段里,是一串十六进制,比如右转是A0 00 02 20 00 00之类,不同厂商会有扩展码。如果设备的解码驱动只认私有扩展命令,而平台发的是通用协议,设备自然不执行。
解决:先用设备自带的SDK或IE页面测试云台是否工作,确认硬件没问题。然后抓包看设备实际收到的PTZCmd和厂家协议手册里的命令码是否一致。不一致时,需要让平台在接口配置里选对应厂家,或者把云台控制从“标准28181”切换成“私有扩展”。另外,很多设备在执行连续移动时,要先收到一个PanRight启动命令,再在松开按钮时收到一个Stop命令,如果平台只发一次启动命令,设备只会动一下停一下,或者完全不动。
4.5 设备在分平台能看,大平台就卡
现象:同一台NVR接到地市的分平台,码流正常;再级联到省平台,播放就卡顿甚至花屏。
原因:典型的是码流封装和传输模式问题。28181规定RTP里通常是PS封装,有些厂家在分平台用的私有协议,到省平台才走28181,就会出现PS流的解析兼容问题。还有H.265码流在部分老平台和播放器里没有正确识别,画面上绿屏或黑屏。码率过高时,UDP传输发生分片丢失也是大平台卡顿的主要因素。
解决:先把设备主码流降低到2Mbps以内,关闭动态GOP,强制用PS封装,看是否好转。再用ffmpeg直接拉流测试:
ffmpeg -i "rtp://192.168.1.10:5000" -t 10 -f null /dev/null如果能跑满10秒不报错,说明流本身没大问题。如果报Protocol not supported或者Invalid data,基本是封装不兼容。遇到H.265,不要直接在VLC里试,先用ffprobe看编码格式:
ffprobe -v error -select_streams v:0 -show_streams rtp://192.168.1.10:5000这样能确认到底是H.264还是H.265。省平台要兼容H.265,一般要求平台版本在2016标准之后。另一个后备方案就是把设备编码改成H.264,最省事。
5. 从单设备接入到平台级联:接口文档之外要补的参数
5.1 平台与平台级联时的上下级域与目录ID规划
单设备接入调试通过后,更多人会碰到平台与平台级联。这不再是设备找SIP服务器,而是整个平台作为下级平台向上级平台注册。这时接口文档常常不够用,因为还要规划上下级域的编码规则,否则目录一推上去上级看不懂。
上级平台通常会给一个“SIP域编码”和“上级SIP服务器地址”,下级平台在配置级联时,要填自己的“平台SIP ID”和密码,并且保证本级所有通道ID的前8位域编码与上级分配一致。我之前遇到一个项目,下级平台用34020000作为域编码,上级平台内部却用34020100做区域划分,导致通道虽然上报了,但在上级地图上无法定位。这种问题不靠抓包,而是靠事先拿到《行政区划编码表》逐一对齐。
级联的目录上报也有两种方式:手工导出导入和实时订阅。多数平台支持把下级目录用EXCEL导出来改,但生产环境我更推荐订阅方式,就是让上级平台向下级平台发SUBSCRIBE,下级平台把目录变化通过NOTIFY推上去。注意这里的Event头是Catalog,但消息体里CmdType要写CatalogResponse。很多平台把这块写死在内部,对不齐时就容易出现“上级能收到目录但状态全是离线”的怪现象,解决的方法最常见是让两边平台工程师各出一份对接参数表,逐项比对。
5.2 跨网段NAT场景:SIP会话穿透怎么配
如果设备或下级平台部署在一个私网里,和公网平台对接,就要处理NAT。28181的SIP里面,IP地址至少出现在三个地方:Via、Contact、SDP。私网设备发出的REGISTER里,Via和Contact都是内网IP,平台如果直接按这个地址回信令,包就到不了。所以很多设备在配置页里有一个“NAT”开关,开启后会把Via和Contact替换成映射后的公网IP。
| 配置项 | 私网直连 | NAT场景 |
|---|---|---|
| SIP服务器IP | 填平台内网IP | 填平台公网IP |
| 本机IP | 设备内网IP | 设备外网映射IP |
| NAT开关 | 关闭 | 开启 |
| 媒体端口 | 随机或固定 | 必须映射到外网对应端口 |
| RTP传输模式 | 自动/UDP | 建议TCP |
除了信令替换,媒体端口也要映射。很多平台支持“媒体端口范围”,比如设备端从10000到20000。NAT场景下,这段UDP端口要全部映射到外网。只映射5060是很多初学者的血泪教训:信令通了、INVITE也通了,但RTP因为回程找不到内网端口就断了。如果公司网络不允许开太多端口,换成TCP传输模式,只需要映射一个TCP端口,虽然比UDP费一点性能,但打洞逻辑简单得多。
在平台侧也有对应的配置,通常是“允许NAT穿透”或“支持UDP keepalive”。设备开启NAT后,会周期性给平台发Keepalive消息,平台才能动态刷新设备的外网IP和端口。如果平台没有这个功能,设备注册后地址一变化,平台就再也联系不上了。
5.3 录像回放与报警推送:接口调用顺序和鉴权
实时点播跑通之后,录像回放是第二个大头。回放的接口改动不大,INVITE的Subject头和SDP里会带上时间范围。多数字段和实时点播一样,区别在于s=Playback,并且SDP的o=行里会附带起始和停止时间,有些平台用自定义XML头传时段。
回放流程上有一个必须注意的顺序:INVITE → 200 OK → ACK → 媒体流。如果有倒放或变速播放,平台会再发一个INVITE更新会话,或者使用RTSP的PLAY方法做变相控制,但大多数纯28181平台只用INVITE和BYE。若要兼容第三方播放器,也可以在平台侧转成RTSP再输出,这样播放器不用解析PS流,代价是多一次转码延迟。
报警推送在设备端实现得比平台端更简单。设备检测到移动侦测后,向平台发一条MESSAGE,CmdType为Alert,里面带报警时间和报警类型编码。平台收到后回一个200,如果平台配置了录像联动,则会在内部把报警和录像文件关联。要注意的是,报警信息里的DeviceID必须是报警通道的ID,而不是设备根ID。如果用根ID发,平台虽然能收到报警,但不知道是哪个通道,界面上会显示“未知通道”。所以对接报警时,先确认通道ID在目录上报里存在,再触发一次移动侦测,最后在平台侧看能不能匹配。
6. 一个验证技巧:用抓包的响应码判断对接是否真通
对接28181接口调到最后,我不看平台面板,只看三个响应码。第一个是REGISTER收到的200 OK,第二个是目录查询MESSAGE后设备回的第一个200 OK,第三个是INVITE返回的200 OK。这三个200都出现,对接就基本完成了。过程里如果出现401,那是正常的鉴权挑战,但REGISTER流程里第二个REGISTER必须带回新的Authorization,否则不算通。
实际操作上我会写一个简单的shell别名,让现场同事一抓就能过滤出SIP响应码:
alias siptrace='sudo tshark -i eth0 -Y "sip.Status-Code || sip.Method==REGISTER" -T fields -e frame.time -e ip.src -e sip.Method -e sip.Status-Code'跑起来后,屏幕上会按时间列出所有SIP方法和响应码。你会很直观地看到:REGISTER、401、REGISTER、200,这就是设备上线;SUBSCRIBE、200,这是订阅成功;INVITE、200、ACK,这才具备拉流条件。如果列表里一直只有REGISTER和401,没有第二个REGISTER,那问题就在密码或鉴权算法,不用去翻平台日志瞎猜。
我的习惯是把这条命令和sngrep都留在现场笔记本里,sngrep看对话,tshark看响应码。遇到黑屏这类媒体问题,再加一条rtp过滤,看RTP包的源IP是不是设备IP、目的端口是不是平台SDP里那个端口。这比任何一台设备的调试界面都真实。
单位里新来的同事总问我,28181接口细节这么多,怎么快速上手。我一般让他先把每个接口的响应码画成一条竖线,从REGISTER到INVITE,线上标出关键的200、401、ACK,后面再遇到问题就顺着这条线找。这个习惯帮我在好几个项目里避开黑匣子一样的平台日志,少通宵几次。对接28181没有玄学,抓包看到的每一帧都是证据。希望这些经验和踩坑记录能帮到你,在下次对接时少走一段弯路。
本文还有配套的精品资源,点击获取