ONVIF 管「设备到客户端」,国标管「平台到平台」。 一个靠行业联盟推,一个是强制国标——所以两个都得会。
第八章把 ONVIF 从 WSDL 到能跑的代码走完了,那一套是「直连设备」的路子。 这一章换一头:几十上百台设备怎么被一个平台统一管起来,靠的就是 GB/T 28181。
一、同一个问题,两种站位
两套协议都在解决「怎么控制一台摄像机」,但它们假设的场景完全不同: ONVIF 假设「客户端直接连设备」,国标假设「平台连平台、设备挂在下面」。
| 维度 | ONVIF | GB/T 28181 |
|---|---|---|
| 管到哪一层 | 设备到客户端 | 平台到平台 |
| 信令 | SOAP over HTTP | SIP |
| 媒体 | RTSP/RTP | RTP,PS 封装 |
| 身份 | WS-UsernameToken | SIP Digest |
| 谁定的 | ONVIF 论坛 | 国家标准 |
第二行决定了整个技术栈的走向:ONVIF 用 HTTP,所以能穿绝大多数防火墙; 国标用 SIP,天生就是「会话」模型,适合电话那样的一来一回。 第三行是国标最特别的一处:它的 RTP 负载不是裸 H.264,而是 PS 封装。 原因很实在——国标要在一个流里同时带视频、音频、报警和私有数据, 而 PS 本来就是干这件事的。
二、为什么国内必须用国标
最直接的原因是「强制」: 公安、交通、教育这些行业的联网平台,招标文件里直接写「符合 GB/T 28181」。 不满足这一条,连投标资格都没有。 但抛开合规,它确实解决了一个 ONVIF 解决不了的问题:大规模级联。 一个市局要接几十个分局、几百个派出所、几万台设备, ONVIF 那种「客户端直连设备」的模型根本撑不住—— 它没有「目录」这个概念,谁也不知道下面有多少台。 国标把「目录」做成了协议的一部分:设备要注册、平台要心跳、通道要能被查询, 于是「全网有多少路视频」这个问题第一次有了标准答案。 这也是它比 ONVIF 更适合「联网」两个字的根本原因。 代价是它更重:一个能跑国标的平台,代码量是一个 ONVIF 客户端的几十倍, 因为它要维护注册状态、心跳超时、目录同步、级联关系。 所以现实中的做法是「用开源平台」——这也是第十一章要讲的那两个东西存在的理由。
三、动手 Demo:同一件「取设备信息」,两套协议各写了什么
把同一件事各写一遍,量一量字符数、元素数和命名空间占多少。
import re
onvif = ('<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" '
'xmlns:tds="http://www.onvif.org/ver10/device/wsdl">'
'<s:Body><tds:GetDeviceInformation/></s:Body></s:Envelope>')
gb = ("MESSAGE sip:34020000001320000001@3402000000 SIP/2.0\r\n"
"Content-Type: Application/MANSCDP+xml\r\n\r\n"
"<Query><CmdType>DeviceInfo</CmdType>"
"<SN>1</SN><DeviceID>34020000001320000001</DeviceID></Query>")
for name, txt in (("ONVIF", onvif), ("国标", gb)):
ns = sum(len(m) for m in re.findall('xmlns:[a-z]+="[^"]*"', txt))
print(name, len(txt), len(re.findall("<[A-Za-z]", txt)), ns)
实跑输出:
--------------------------------------------------------------------
同一件「取设备信息」,两套协议各写了什么
--------------------------------------------------------------------
**ONVIF 和国标解决的是同一个问题,但站位完全不同**:**一个面向「设备」,一个面向「平台」。**
**下面把同一件事各写一遍,量一量差别。**
写法 字符数 元素数 命名空间字节 占比
-------------------------------------------------------------------------
**ONVIF(SOAP)** **208** **3** **99** **48%**
**国标(SIP+XML)** **210** **4** **0** **0%**
**最后两列是这件事的关键**:**ONVIF 将近一半的字节花在命名空间声明上**,
**而国标一个命名空间都没写。**
**国标那一句里,真正有用的只有 `DeviceInfo` 和那串 20 位编号**,
**剩下全是 SIP 头和 XML 壳——但它至少不重复声明。**
**两段都是纯 ASCII,所以字符数等于字节数**,**这一点让「谁更胖」可以直接按长度比。**
**两套协议的分工可以这样记**:
维度 ONVIF GB/T 28181
-------------------------------------------------------------
**管到哪一层** **设备到客户端** **平台到平台**
**信令** **SOAP over HTTP** **SIP**
**媒体** **RTSP/RTP** **RTP,PS 封装**
**身份** **WS-UsernameToken** **SIP Digest**
**谁定的** **ONVIF 论坛** **国家标准**
**第三行是国标最特别的一处**:**它的媒体流走的是 RTP,但负载是 PS 封装的**,**而不是裸的 H.264。**
**原因是国标要兼容「一段录像里既有视频又有音频还有私有数据」**,
**而 PS 这种东西本来就是为了「把多种流塞进一个文件」发明的。**
**最后一行决定了它们的适用场景**:**ONVIF 是行业联盟的事实标准,国标是强制性的国家标准**,
**在国内做联网平台,两个都得会。**
最后两列是重点:ONVIF 将近一半的字节花在命名空间声明上,而国标一个都没写。
这不是谁写得好,是 XML 的两种用法——
ONVIF 要保证「同样的元素名在不同厂商那里不冲突」,所以必须声明;
国标只有一个命名空间,干脆省了。
国标那一句里,真正有用的只有 DeviceInfo 和那串 20 位编号,剩下全是 SIP 头和 XML 壳。
但它至少不重复声明,所以同样的意图,国标比 ONVIF 省下将近一半的字节。
两段都是纯 ASCII,所以字符数等于字节数——这一点让「谁更胖」可以直接按长度比,
不用去纠结中文的编码问题。
30 秒实验
- 算一下:一次目录同步要发 500 条这样的报文,按 ONVIF 那 208 字节算,一共多少 KB?(约 104 KB)
- 想一下:为什么国标不需要命名空间声明?
- 想一下:ONVIF 的「客户端直连设备」在几百台设备时会卡在哪?
常见误区
- 以为「国标就是 ONVIF 的中文版」。 两者站位不同,一个面向设备,一个面向平台。
- 以为「有了 ONVIF 就不用国标」。 招标文件里写的是国标,不合规就没有投标资格。
- 以为「国标更先进所以更快」。 它更重,要维护注册、心跳、目录, 代码量是 ONVIF 客户端的几十倍。
自测三问(点开对答案)
1. ONVIF 和国标最根本的差别? —— **管到哪一层**:一个设备到客户端,一个平台到平台。 2. 国标为什么用 PS 封装而不是裸流? —— **要在一个流里同时带视频、音频、报警和私有数据**。 3. 为什么大规模联网必须用国标? —— **它把「目录」做进了协议**,能回答「全网有多少路视频」。下一节从术语开始:国标文档里那几个词,混一个就会读错整段。
- ☐ (本节完,下一节 10.02.01 术语和定义)