免费GB28181平台搭建实战:从SIP信令到海康设备接入与运维 做了这么多年安防项目最烦的一件事就是甲方手里全是海康、大华的摄像头却非要你搭一个统一平台。摄像头厂家自己的平台只能管自家设备想跨品牌、把视频流集中到一个Web页面里播放就得走GB28181。所谓GB28181简单说就是一套国标协议让不同厂家的摄像头和平台可以互相注册、取流、对讲。它本身不收费却承载了安防行业90%以上的设备接入需求。我最近刚帮一个本地运输企业搭完一套免费GB28181平台用的就是smarteye接入的设备里既有海康的球机也有枪机一路折腾下来踩了四五个典型的坑。这篇文章不聊PPT直接把我从选型到部署、从设备接入到告警运维的完整过程写出来希望能帮想自己动手搭平台的人少走几趟弯路。1. 选型纠结免费GB28181平台哪来的免费午餐1.1 商业平台与开源平台的一次真实对比接这个需求之前我先让商务打听了一圈商业GB28181平台的价格。按接入路数收费的模式下一家运输企业如果接200路摄像头年费轻轻松松破万这还没算流媒体服务器和网关的授权费用。对很多中小项目来说这笔钱不算小数目而且平台本身的功能不一定比开源方案强到哪里去。排除了商业平台之后我把目光锁定在开源方案上。市面上能跑GB28181的开源项目不算少wvp-GB28181-pro、smarteye、以及一些基于FFmpeg自研的技术方案各有各的取舍。我当时的核心诉求是三点一是免费且社区要活跃遇到问题能搜到答案二是部署不能太复杂毕竟项目工期卡得死三是管理界面要够用甲方需要自己添加设备、看状态不能全靠命令行。1.2 smarteye的技术栈和取舍smarteye吸引我的地方在于它把信令服务和媒体服务做在了一套体系里用Docker编排之后一条命令跑起来管理后台自带Web界面。简单来说它的工作流程是这样的启动SIP信令服务在5060端口监听接收摄像头的注册和心跳设备上线后通过目录请求上报自己的通道信息页面点击实时预览时平台向设备发起INVITE会话协商媒体传输地址摄像头把RTP/PS流推到媒体服务端口再由媒体服务转封装成浏览器能播放的HTTP-FLV或者HLS平台把收到的视频流转存或者分发给Web前端这整套链路里信令负责找谁媒体服务负责搬运各司其职。和wvp那种需要额外搭一套ZLMediaKit作为媒体流服务的思路相比smarteye的一体化设计在初期部署阶段确实省了不少事拓扑简单排查问题时不用同时开三四个服务的日志。1.3 免费背后的隐性成本但免费不是零成本这是所有开源平台使用者都必须心里有数的事。服务器得自己买域名或者公网IP得自己准备出了问题没人给你开工单只能自己看日志。更现实的是免费平台的上游依赖比如FFmpeg、Netty、数据库这些组件一旦某个版本出现安全漏洞你得自己跟进升级。我给这台平台选了台2核4G的云服务器带宽5M起步先跑100路以内的接入。存储方面如果要做录像回放还得额外挂一块数据盘。这些开销和商业平台年费比起来确实不高但如果项目负责人没算清楚这笔账进场之后再临时扩容就会很狼狈。2. 读懂GB2818120位设备编码和SIP信令的几件要命事2.1 20位国标编码到底是什么很多人第一次接触GB28181上来就填SIP服务器ID填完发现设备死活注册不上后台日志里全是401或者超时。问题的根源往往不是IP填错而是ID编码不符合规则。国标ID统一是20位数字从左到右依次是中心编码8位前2位省级、中间2位市级、后4位行业编码、设备类型编码2位比如111代表中心服务器131代表摄像机132代表NVR、设备序号7位自己编保证唯一、校验位1位由前19位计算出来。举个例子一个SIP服务器ID可以是34020000002000000001前8位34020000代表省份和城市中间2位00代表行业接着2位20是类型编码十位2百位0具体含义可以先不管关键是必须符合20位的长度和编码规则。海康摄像头的Web配置页面通常会把校验位自动计算好但如果你在smarteye后台手动注册设备ID就得按这个规则仔细填一位都不能错。2.2 注册、心跳、Invite三步搞懂信令要理解后续的踩坑必须先搞懂GB28181的SIP信令流程其实记好三步就行。第一步是注册。摄像头向平台SIP服务器发送REGISTER请求平台回401要求认证摄像头再带着用户名密码重发REGISTER平台认证通过后设备显示在线。这个流程和打电话先拨号、对方接听前先问一句你哪位的道理一模一样。第二步是心跳。设备注册成功后会周期性地向平台发送MESSAGE消息告诉平台我还活着。心跳周期通常15到60秒可配平台在心跳超时后会把设备标记为离线。第三步是INVITE。当你在平台的Web界面点开一路摄像头预览时平台会向设备发送INVITE请求里面带着一个SDP描述写着平台希望接收媒体流的IP、端口、音视频编码信息。设备收到后开始往这个地址推RTP流。2.3 媒体传输为什么要用PS流这里有个初学者容易忽略的点GB28181传视频流用的不是裸H.264也不是RTSP里的RTP直接打包而是把H.264/H.265数据封装成PS流之后再放进RTP包里。PS流是Program Stream相当于把视频和音频的时间戳信息打包在一个容器里。为什么要多此一举因为国标场景下要兼容录像回放、语音对讲、多种码流切换PS流能更好地承载系统层的同步信息。我们在部署时不需要自己去实现PS封装smarteye的媒体服务已经做了处理但理解这一点对排查黑屏问题很有帮助。比如设备推流的时候只推了视频没推音频PS流里就不会有音频PES包表现就是画面正常、没有声音这种问题在代码里调试不出来只能抓包看PS流结构。2.4 海康设备提示未授权的常见根因海康摄像头接入国标时经常提示401 Unauthorized很多新手第一反应是密码不对。实际上密码只是其中一个很小的原因我排过最多的根因是这几种第一密码为空。海康设备接入GB28181时平台接入密码默认是空的需要手动设置至少8位。如果设备端没有设置密码平台端却配置了密码必然401。反过来设备端设置了密码平台端没写也400系列报错。第二设备时间与服务器时间差得太多。SIP摘要认证里带了时间戳设备和平台时间相差超过5分钟认证就会失败。解决办法是把摄像头和服务器都配置NTP时间同步这一步很多人会漏掉。第三平台侧没留对设备的认证信息。smarteye在添加设备时要登记一个SIP用户ID和密码和摄像头里配置的必须完全一致注意是SIP密码不是摄像头的登录密码。我遇到过客户把摄像头Web登录密码填进去的结果当然注册失败。3. 服务器落地部署从一台裸机到smarteye跑起来3.1 服务器配置与网络要求部署前先把服务器需求明确清楚免得后期被动。我选的是Ubuntu 22.04 LTS系统2核4G内存起步硬盘至少40G。这样的配置跑一台smarteye服务加配套的MySQL数据库接入50路以下基本够用CPU占用在视频流转发时会明显上去4G内存也还算从容。网络方面几个关键的端口要提前确认没有被占用最好画一张端口规划表用途端口协议SIP信令5060UDP/TCPHTTP管理后台8080TCP流媒体服务10000-20000UDP/TCP数据库如独立部署3306TCP如果你的服务器在云上记得在安全组规则里把这些端口全放开尤其不要只开了TCP而漏掉UDP。GB28181的信令和媒体传输默认走UDP这也是后面踩坑的大头。3.2 Docker编排与一键部署smarteye项目里自带docker-compose.yaml和很多开源平台一样安装步骤其实可以概括成三步下载代码或镜像、改配置、启动。我的操作流程是这样的# 克隆项目代码 git clone https://github.com/smarteye/smarteye-server-docker.git # 进入部署目录 cd smarteye-server-docker # 用项目自带的一键部署脚本启动 ./deploy.shdeploy.sh里做的事情说白了就是依次启动MySQL、Redis、信令服务和媒体服务并通过合理的镜像依赖确保顺序。实际跑起来之后可以确认一下容器状态docker ps看到信令服务容器和媒体服务容器都是Up状态就说明最基础的流程跑通了。之后打开http://服务器IP:8080进入Web管理页面用初始化配置里的默认账号登录。注意deploy.sh里如果用了--network host模式容器会直接复用宿主机网络这种情况下端口映射问题就会少很多但要注意宿主机的防火墙仍然需要放行相应端口。3.3 必须改的几个配置文件参数部署完之后启动脚本生成的配置文件里有几项是无论如何都要检查的分别是SIP服务器ID默认值通常是一串符合国标的20位数字按项目地区编好即可但必须保证和后面摄像头里填的一致。SIP服务器域和ID的前10位通常一致海康设备要求域和ID匹配否则注册不了。媒体端口范围注意和宿主机防火墙端口放行范围保持一致比如10000-20000别代码里写10000到20000防火墙却只放行了30000到40000。外部IP地址这点最容易忽略。如果服务器有多个网卡或者用了云服务器的私网IP信令SDP里携带的媒体接收地址可能是内网IP局域网里的设备能找到你公网设备就找不到。需要显式配置成服务器的公网IP这就是GB28181环境中最经典的能注册不能预览问题的根源。这些参数在管理后台通常可以直接配置也可以在配置文件中手动改。我个人的习惯是先改配置文件再启动服务避免后台配置热更新没生效导致的二次排查。4. 海康设备接入实录四个坑每个都让摄像头消失4.1 海康Web管理页面的GB28181配置海康摄像头的国标接入配置入口一般藏在网络-高级设置-平台接入里选择协议类型为GB28181然后会看到一整个页面的参数需要填写。我把每项和smarteye后台的对应关系整理成了一张表照着填基本不会错海康设备端参数填写内容对应平台参数SIP服务器IDsmarteye的SIP服务器IDSIP IDSIP服务器域smarteye的SIP服务器域SIP域SIP服务器地址服务器的公网IP服务器地址SIP服务器端口5060服务器端口SIP用户名设备在平台上的注册ID设备国标IDSIP密码设备接入密码接入密码通道ID摄像头的国标编码通道编号填报界面里通常还会有一个注册有效期和心跳周期默认3600秒和60秒。这两个值其实够用但别和平台端的超时设置冲突。4.2 坑一设备ID和通道ID随意填写我接第二路球机时顺手把设备SIP用户名填成了设备的序列号结果摄像头一直在线但平台端就是获取不到视频通道列表目录查询状态始终是未响应。排查了半天最后发现是设备ID不符合国标编码规则。平台端添加设备时用的国标ID和摄像头里SIP用户名填的ID必须完全是同一个值而且通道ID也不能乱填得按中心编码131类型码序号校验位的20位规则来。海康设备有个特性如果你在SIP用户名里填了非20位数字它不会报错但平台解析时接收到的设备信息就会变成乱数据。解决办法很简单在平台上手动添加这路设备时直接复用摄像头SIP用户名那一栏的值作为设备国标ID通道ID则用平台自动生成的通道编码不建议手工乱编。4.3 坑二H.265编码导致页面黑屏平台和设备都注册成功心跳正常通道也在线但点开预览就是一片黑。这个坑我在部署第一批海康摄像头时踩得最狠。原因是海康摄像头默认的视频编码是H.265也就是HEVC。smarteye的管理后台如果用浏览器播放HTTP-FLV而浏览器本身不支持HEVC解码画面自然黑屏平台日志里却看不到任何错误因为视频流已经推上来了只是浏览器解不了。解决办法就两条路最简单的就是把摄像头主码流和子码流的视频编码改成H.264换成H.264之后预览秒出图。如果你确实要保留H.265那就得给播放器配一个支持HEVC的插件或者换用支持H.265的Web播放器但这会引入额外的分发和转码开销对免费方案来说有点不值。实际项目中为了兼容性我都直接统一成H.264。4.4 坑三UDP端口被防火墙拦掉第三个坑发生在给外网设备做接入时。内网测试的几路摄像头接入正常但一台在营业部网点、通过公网转发接入的摄像头始终注册不上信令日志里连REGISTER包都看不到。抓包分析之后发现设备发出SYN包到达服务器之后就没有回包了这是典型的防火墙拦截特征。回头看云安全组才发现只放行了TCP 5060UDP 5060完全没有放开。GB28181信令默认走UDP这种情况注册包到不了应用层平台日志自然一片空白。调整安全组规则把UDP 5060、UDP 10000-20000全部加上白名单改完配置后重新启动摄像头注册流程设备秒上线。这个坑可以说是外网接入GB28181最容易踩的没有之一。部署前我已经做了端口规划表实际配置时还是漏掉了UDP方向足以说明这类细节有多容易被忽视。4.5 坑四心跳周期和注册有效期不匹配有一路摄像头接入后运行得很稳但每隔几个小时就会被平台标记为离线过一会儿又自动恢复在线反复横跳。看设备端和平台端日志发现设备报的是注册过期正在重新注册。问题出在参数匹配上。海康设备端如果设置注册有效期为3600秒心跳周期为60秒但smarteye平台端配置的会话超时时间是180秒就会导致这样一种尴尬局面平台以为设备已经超时了把会话清掉但设备还觉得自己注册着直到下一个心跳周期到来才会触发重新注册。表现就是设备反复离线、在线。解决办法不是非此即彼而是统一两端的参数逻辑。最简单的做法是把平台端的SIP会话超时时间调成大于设备的注册有效期比如设备注册有效期3600秒平台超时时间改成7200秒留足余量。这样设备确实掉线了平台才能在预期的时间窗口内正确捕捉到。这个参数在smarteye的配置文件里叫expireTime不同版本的名称略有差异但逻辑都是一样的。5. 语音对讲和实时预览真接通了才明白的那些细节5.1 GB28181语音对讲的完整过程项目做到一半甲方突然提了个新需求要在监控中心直接和司机喊话。我一开始以为不就是双向对讲嘛后来发现GB28181的语音对讲和普通IP电话不是一回事。国标语音对讲的流程简单来说是这样的平台先通过SIP控制信令向设备发起对讲请求让设备把自己采集到的音频流推送到平台指定的媒体端口平台同时也可以把中心的麦克风采集的音频流推送给设备让设备通过扬声器播放出来。这个过程中音频封装成PS流走RTP传输。设备端的海康摄像头如果要支持对讲本身需要带音频输入接口或者内置麦克风而且平台的Web播放器也需要支持采集麦克风音频。smarteye后台的对讲按钮会同时触发两个方向的IMU消息控制。5.2 对讲卡顿的排查思路在调通对讲功能时遇到的最大问题是平台到设备的音频推流一直失败设备端能听到中心说话但中心听不到设备端的一丁点声音。排查链路是这样的先看平台日志信令正常音频流也确实在往设备的媒体端口推送。再用抓包工具看RTP包发现设备并没有回应任何音频RTP包。问题基本上锁定在音频编码协商环节。海康的一些设备对音频编码格式有严格要求只支持PCMA即G.711 A律不支持G.722。而我在平台端默认配置的是G.722导致SDP协商结果设备不接受。把音频编码强制改成PCMA之后对讲立即通了。建议接海康设备做对讲时音频编码直接选PCMA别犹豫。G.722虽然音质理论上更好但兼容性差一截耗时耗力未必值得。5.3 实时预览延迟怎么压到一秒内实时预览是整个过程里最直观的体验。用HTTP-FLV播放时本地局域网内延迟能控制在1秒之内但如果走公网延迟往往会飙到3秒以上体验很差。要压延迟无非是几个点一是前端播放协议优先选HTTP-FLVHLS切片本身就带来几秒的延迟只适合录像回放不适合实时指挥二是确认设备编码参数里I帧间隔设置合理不要设置成100帧25帧就够过长的I帧间隔会让播放器等待下一个关键帧才能出画面三是媒体服务器的缓冲时间调短。smarteye的配置里有一个媒体拉流缓冲时长默认可能在200到500毫秒改成100毫秒之后公网环境下预览延迟能压到1.5秒左右局域网在0.5秒以内。需要注意的是缓冲时间不是越小越好调得太短网络抖动时画面会出现卡顿。100到150毫秒是一个比较均衡的区间。6. 平台上线后别撒手Prometheus盯住资源与离线告警6.1 GB28181平台到底吃多少资源free方案的好处是省了授权费坏处是没有商业平台的监控团队替你盯着。平台上线后要是把服务器跑挂了甲方不会知道这是因为免费只会觉得是你能力不够。所以运维监控必须自己搭。先搞清楚平台吃饱饭的量级。100路以内的摄像头接入如果只做实时预览和按需转发2核4G的服务器CPU总体占用在30%到50%之间浮动其中媒体服务转封装是最大的开销。如果开启录像存储功能磁盘吞吐和带宽占用会明显上升100路全天录像数据量百G级别是常态提前规划磁盘扩容。还有就是连接数。每一路在线预览都会保持一个到设备的长连接和一个到前端播放器的长连接2G内存的服务器撑到200路左右时容易出现句柄耗尽或者内存不足所以监控内存和句柄数是必须做的事。6.2 node_exporter采集与Grafana展示我在这台GB28181服务器上用Prometheus加node_exporter做了最基础的资源监控整体流程是node_exporter负责把服务器的CPU、内存、磁盘、网络指标暴露成一个HTTP接口Prometheus定时来抓取数据最后通过Grafana展示成仪表盘。部署非常顺滑两条命令就能起node_exporterdocker run -d -p 9100:9100 --name node_exporter prom/node-exporter然后在Prometheus的配置文件里加一个抓取目标scrape_configs: - job_name: gb28181-server static_configs: - targets: [你的服务器IP:9100]Grafana里导入一个node_exporter的官方仪表盘模板CPU、内存、磁盘、网络、打开文件数就全有图形了。这套方案对没有监控基础的人来说也很友好。6.3 设备离线告警的另一种思路Prometheus能解决的只是服务器活着的问题但GB28181平台最核心的监控指标其实是摄像头有没有掉线。这一指标真正关系到业务可用性视频设备因为断电、网络抖动而离线在运输企业里几乎是每天都有的事。我们的做法是写了一个简单的巡检脚本定时调用smarteye的管理API统计离线设备列表如果离线数量超过阈值就通过企业微信机器人推送告警消息。脚本本身不复杂核心就两步先登录后台拿Token再查设备状态列表。这个思路比在Prometheus里自定义exporter要省事得多而且贴近业务。如果以后接入路数增长再考虑把离线事件写成自定义export指标把数据接到Prometheus统一管理。设备离线和服务器资源监控两条腿走路才算是真正把平台看住了。说回到整体体验用smarteye搭这套免费GB28181平台最深的感受是免费两个字背后需要你自己去填平的坑并不少但也正因为有这些坑你才会真正搞懂SIP信令、国标编码、端口规划这些底层逻辑。我后来再接手任何品牌摄像头的国标接入任务基本不用查文档只需要看一眼设备参数页面的几项配置就知道问题大概出在哪。最后再分享一个实际项目里的小技巧把所有摄像头和平台端的GB28181参数做成一张统一的表格贴到项目的运维共享文档里。这个表格能省下后续无数次远程指导别人改配置的时间。摄像头接入这件事只要参数能对上其他都是小事。