拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

wvp-GB28181-pro 与 ZLMediaKit 部署联调实战

wvp-GB28181-pro 与 ZLMediaKit 部署联调实战

1. 先把这套组合的职责边界划清楚

1.1 信令走 WVP、媒体走 ZLMediaKit,为什么不做成一体

刚接触 wvp-GB28181-pro 的人最容易犯的错,是把 WVP 当成一个"流媒体服务器"。实际上它压根不碰视频流。整套 GB28181 视频平台在 CentOS 7 上跑起来,逻辑上是两台独立服务在配合:WVP 负责 SIP 信令(设备的注册、心跳、目录查询、INVITE 点播、云台控制、语音广播),ZLMediaKit 负责 RTP 收流、解 PS 封装、转协议分发(RTSP/RTMP/HLS/HTTP-FLV/WebRTC)。两者之间靠两样东西通信:WVP 调 ZLM 的 HTTP API(比如openRtpServer开收流端口、closeRtpServer关端口),ZLM 主动回调 WVP 的 hook 接口(on_publish、on_stream_changed、on_rtp_server_timeout等)。

这个拆分带来的最大好处是故障域隔离。信令出问题,只是设备点不开;媒体出问题,只是画面卡或黑屏。如果你把两者揉在一块儿,一次 Java 进程的 Full GC 就会把正在传输的流一起干掉。而且 ZLMediaKit 是 C++ 写的,本身单机撑几千路转发问题不大,Java 侧的 WVP 只处理信令,CPU 占用极低,两者对机器的资源诉求完全不同——这种不对称恰恰说明它们本就该分开部署。

我一般建议至少给出一个明确的分工认知:WVP 是"指挥官",它只下达命令、记录状态、维护设备树;ZLMediaKit 是"搬运工",它只负责把 UDP 上来的 RTP 包拆包、重新封装、按需分发给浏览器或第三方播放器。理解了这层,后面所有配置项的归属就不会搞混——凡是以sip:开头的参数是给 WVP 的,凡是以[rtp]、[rtsp]这种段落结构出现的是给 ZLM 的。

还需要提前明确一个概念:GB28181 里所有媒体流都是"设备推、平台收"。不是平台去设备那里拉。设备收到 INVITE 后,按 SDP 里协商好的 IP 和端口,主动把 PS 流用 RTP 推上来。这一点非常关键,后面讲级联和排查黑屏时会反复用到。

1.2 版本组合选型:先定 JDK,再定其余

这一步很多人跳过,结果编译到一半发现 JDK 版本对不上。WVP-GB28181-pro 从 2.7 开始切换到了 Spring Boot 3,要求 JDK 17;2.6.x 及更早是 Spring Boot 2.x,JDK 8 即可。CentOS 7 上默认的 OpenJDK 只有 1.8,如果你要跑 2.7,得自己装 JDK 17 并改JAVA_HOME。

我个人的建议是:存量设备多、追求稳妥就上 2.6.x + JDK 8,社区资料最全,踩坑帖子也最多;新项目、需要 WebRTC 低延迟播放、需要更规范的接口就上 2.7.x + JDK 17。下表是两种组合的实际差异,供你决策。

对比项WVP 2.6.xWVP 2.7.x
运行环境JDK 8 + Spring Boot 2.7JDK 17 + Spring Boot 3.x
数据库MySQL 5.7 / 8.0 均可建议 MySQL 8.0
配置结构media节点扁平media下拆出rtp、stream等子节点
前端Vue 2 打包后放staticVue 3 独立打包
级联稳定性成熟,资料多修复了不少级联保活问题

ZLMediaKit 这边反而简单,它提供了编译好的二进制包,不用非得源码编译。CentOS 7 自带的 GCC 是 4.8.5,编译新版 ZLMediaKit 会报 C++14 相关的错,得装devtoolset-8之类的工具链,折腾成本不低。除非你要改源码,否则直接拿官方 Release 里的 linux 包解压就能用,省半天时间。

注意:CentOS 7 在 2024 年 6 月已经走完官方维护周期,默认的mirror.centos.org地址大多失效。装依赖之前先把 yum 源指向归档地址,或者干脆换成本地镜像源,否则你会在第一步就卡住。

1.3 端口清单与带宽估算,动手前先算一遍

GB28181 平台最典型的故障原因不是代码问题,是端口没开。下面这张表建议你部署前对着firewall-cmd --list-ports逐条核对一遍。

端口协议归属用途
5060UDP/TCPWVPSIP 信令,设备注册与点播
18080TCPWVP后端 HTTP 服务,也是 ZLM 的 hook 回调地址
80 / 8090TCPZLMHTTP 拉流、HLS、FLV
554TCPZLMRTSP 拉流
1935TCPZLMRTMP 拉流/推流
8000UDPZLMWebRTC 播放
30000-30500UDPZLMRTP 收流端口段

带宽一定要提前算。单路 1080P H.264 主码流通常按 4 Mbps 估,如果 100 路设备同时点播,出口就是 400 Mbps。这个数字不是让你去申请这么多带宽,而是提醒你:前端页面别一屏开 16 路,开四路就够看,需要多路监控就上轮巡。媒体端口段的大小也有讲究——30000-30500是 501 个端口,决定了同时最多能有多少路流在收。如果你只开 10000 单端口,靠 SSRC 复用也能跑,但排查问题时流全挤在一个端口上,抓包会非常痛苦。我一般按"预计并发路数 + 50% 余量"来设端口段。

2. CentOS 7 基础环境铺设

2.1 系统初始化:四件必做的事

拿到一台干净的 CentOS 7,先做四件事,顺序别乱。

第一件,处理 yum 源。如果系统还能联网但yum install报 404,改归档地址:

sed -i 's/^mirrorlist=/#mirrorlist=/g' /etc/yum.repos.d/CentOS-Base.repo sed -i 's|^#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-Base.repo yum clean all && yum makecache

第二件,关掉 SELinux。ZLMediaKit 和 WVP 都涉及大量端口监听和文件读写,SELinux 开着会在你看不见的地方拦截。生产环境可以配策略,测试环境直接关:

setenforce 0 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

第三件,开防火墙端口。CentOS 7 用的是 firewalld,RTP 端口段要整段放行:

firewall-cmd --zone=public --add-port=5060/udp --permanent firewall-cmd --zone=public --add-port=5060/tcp --permanent firewall-cmd --zone=public --add-port=18080/tcp --permanent firewall-cmd --zone=public --add-port=80/tcp --permanent firewall-cmd --zone=public --add-port=554/tcp --permanent firewall-cmd --zone=public --add-port=1935/tcp --permanent firewall-cmd --zone=public --add-port=8000/udp --permanent firewall-cmd --zone=public --add-port=30000-30500/udp --permanent firewall-cmd --reload

第四件,调大文件句柄和时间同步。ZLMediaKit 每路流都会占若干 fd,默认 1024 在几十路并发时就爆了:

echo "* soft nofile 65535" >> /etc/security/limits.conf echo "* hard nofile 65535" >> /etc/security/limits.conf

时间同步也要做,SIP 注册的Expires头和心跳全靠时间戳判断,服务器时间飘了会出现设备反复掉线。跑一条yum install -y chrony && systemctl enable --now chronyd就够。

提示:这四件事里最容易被忽略的是文件句柄。我遇到过一次"平台跑了两小时突然所有流中断",查了半天是 ZLM 打不开新 socket,ulimit -n一查还是 1024,改完重启就再没犯过。

2.2 Java、MySQL 8、Redis 三件套

Java 按前面选定的版本装。如果你走 JDK 17 路线:

yum install -y java-17-openjdk java-17-openjdk-devel alternatives --config java echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk' >> /etc/profile source /etc/profile java -version

MySQL 8 建议用官方 yum 仓库装,别用 CentOS 自带的 MariaDB,WVP 的部分 SQL 语法(比如JSON字段、utf8mb4_0900_ai_ci排序规则)在 MariaDB 上会报错。安装后要改两个地方:character_set_server=utf8mb4和default_authentication_plugin=mysql_native_password。后者是因为 WVP 用的连接池驱动在某些版本下对caching_sha2_password支持不好,会报认证失败。

Redis 装完改/etc/redis.conf,把bind 127.0.0.1保持不动(WVP 和 Redis 同机部署就够),设一个requirepass。WVP 用 Redis 存的是流状态缓存和 token,不是业务数据,丢了不影响设备注册,但会导致正在播放的流状态不一致,所以别再拿 Redis 当主存储用。

这里有个顺序建议:先装 MySQL 和 Redis 并确认能本地连上,再动 WVP。因为 WVP 启动时会立刻去连数据库和 Redis,连不上就是一堆Connection refused刷屏,日志噪音会盖掉真正的报错。

2.3 依赖包一次性装齐

把编译和运行需要的包装齐,避免来回补:

yum install -y epel-release yum install -y gcc gcc-c++ cmake make git wget unzip \ openssl openssl-devel libsrtp libsrtp-devel \ ffmpeg net-tools tcpdump lsof

ffmpeg一定装上,它不是给平台用的,是给你自己验证 ZLM 收流是否正常用的,后面会用它推一路测试流来确认媒体通道通不通。tcpdump是排查 SIP 和 RTP 的救命工具,没有它你只能靠猜。

3. ZLMediaKit 部署与关键配置

3.1 二进制包 vs 源码编译

官方 Release 页面提供ZLMediaKit_linux_release_xx.tar.gz这类包,解压后目录里就是MediaServer可执行文件和一堆配置。这条路在 CentOS 7 上能省掉工具链的坑。

如果你确实要源码编译,CentOS 7 必须先升 CMake(自带的是 2.8,最低要求 3.1,新版要 3.13+)和 GCC(自带 4.8.5 不支持 C++14 部分特性):

yum install -y centos-release-scl yum install -y devtoolset-8 scl enable devtoolset-8 bash gcc --version

然后按官方流程mkdir build && cd build && cmake .. && make -j4。编译过程在 2 核机器上大概要十几分钟,4 核会快不少。

注意:scl enable只在当前 shell 生效。如果你用了screen或nohup在别的会话里编译,工具链是没切过去的,会报一堆#error This file requires compiler support。

3.2 config.ini 里必须改的那几项

ZLMediaKit 的配置集中在conf/config.ini。这个文件很长,但真正需要动的没几处。下面按段落说明。

[general] mediaServerId=zlm-01 flowThreshold=100 enableVhost=0 [hook] enable=1 on_server_started= on_publish= on_play= on_stream_changed=http://127.0.0.1:18080/index/hook/on_stream_changed on_stream_none_reader=http://127.0.0.1:18080/index/hook/on_stream_none_reader on_rtp_server_timeout=http://127.0.0.1:18080/index/hook/on_rtp_server_timeout timeoutSec=10 [rtp] port_range=30000-30500 [rtc] port=8000

mediaServerId必须和 WVP 里配的媒体节点 ID 一致,否则 WVP 调 API 时 ZLM 会拒绝,日志里会出现hook 校验失败之类的字样。on_stream_none_reader这个回调很实用——当一路流没有任何观众时,WVP 会收到通知并主动关流,避免设备白白推流占用带宽。on_rtp_server_timeout则负责回收那些设备没推流的空端口,这个如果不配,跑一段时间端口段就会被耗尽,表现为"新点播全部失败"。

[rtp] port_range要和 WVP 里配的端口段完全对齐,两边不一致会出现 WVP 通知 ZLM 在 30100 开端口、ZLM 却说自己只有 30000-30050 的尴尬局面。

3.3 启动后先自检,别急着接设备

启动 ZLM:

cd ZLMediaKit ./MediaServer -d &

然后看log/目录下最新日志,确认三件事:HTTP 端口监听成功、RTP 端口段分配成功、hook 回调没有报 404(此时 WVP 可能还没起,404 正常)。

接着用 ffmpeg 推一路本地测试流,验证 ZLM 的收流和转发链路完整:

ffmpeg -re -i test.mp4 -c copy -f rtsp rtsp://127.0.0.1:554/live/test

换个终端用 ffplay 拉一下:

ffplay rtsp://127.0.0.1:554/live/test

这一步能出画面,说明 ZLM 本身没问题,后面接 GB28181 出问题就一定是信令或 RTP 参数的事,排查范围直接缩小一半。这个"先隔离验证"的习惯能帮你省掉大量时间,很多人一上来就接摄像头,黑屏了根本分不清是 ZLM 坏了还是 SIP 没通。

4. WVP-GB28181-pro 部署与核心配置

4.1 建库、导 SQL、调连接池

先在 MySQL 里建库:

CREATE DATABASE wvp DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER 'wvp'@'%' IDENTIFIED BY '你的密码'; GRANT ALL PRIVILEGES ON wvp.* TO 'wvp'@'%'; FLUSH PRIVILEGES;

然后从 WVP 项目根目录找 SQL 文件导入。不同版本路径不一样,2.6.x 一般在数据库/目录下,2.7.x 在db/或doc/下,文件名通常带mysql或wvp字样。直接mysql -uwvp -p wvp < xxx.sql就行。

导入完检查表数量,正常应该有几十张表,wvp_device、wvp_device_channel、wvp_platform这几个是核心。如果只有两三张表,说明 SQL 文件选错了,你导的可能是升级脚本而不是全量脚本。

连接池这块,WVP 用 HikariCP。单机接几百台设备的话,maximum-pool-size给到 20 就绰绰有余——它只处理信令,不像业务系统那样高并发查库。盲目调到 100 反而会因为连接数过多拖慢 MySQL。

4.2 application.yml 逐段拆解

这是整个部署里最容易出错的地方。下面按 2.6.x 的结构讲,2.7.x 的键名有微调,以你本地文件为准。

server: port: 18080 spring: datasource: url: jdbc:mysql://127.0.0.1:3306/wvp?useUnicode=true&characterEncoding=UTF8&serverTimezone=Asia/Shanghai username: wvp password: 你的密码 redis: host: 127.0.0.1 port: 6379 password: 你的redis密码 sip: ip: 192.168.1.100 port: 5060 domain: 3402000000 id: 34020000002000000001 password: 12345678 # 级联时作为下级平台对外暴露的地址 show-ip: 192.168.1.100 media: id: zlm-01 ip: 192.168.1.100 sdp-ip: 192.168.1.100 stream-ip: 192.168.1.100 hook-ip: 192.168.1.100 http-port: 80 secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc rtp-port: 30000

几个必须拎出来讲的字段:

sip.ip是 WVP 监听 SIP 的地址,多网卡机器上一定要写内网实际 IP,不能写 0.0.0.0,否则 SDP 里带出去的地址是错的,设备会把流推到错误的地址上。sip.domain是 SIP 域,通常用 10 位数字,比如3402000000。sip.id是平台自身的 SIP 编号,20 位,规则是"域(10位) + 类型编码(4位) + 序号(6位)",其中平台类型编码固定是2000。所以3402000000+2000+00000001=34020000002000000001,这个编号全网不能重复。

media.secret必须和 ZLMconfig.ini里的[general] secret完全一致,这是 WVP 调 ZLM API 的凭证。我见过有人只改了一边,然后所有点播都返回"打开 RTP 服务器失败",日志里却只显示 HTTP 401,很容易误判成网络问题。

media.rtp-port是单端口模式下的收流端口。WVP 支持两种模式:单端口(所有流都发到 30000,靠 SSRC 区分)和多端口(每路流动态分配一个端口)。单端口模式下防火墙规则少,但抓包分析困难;多端口模式更好排查,代价是要放行一整段。

提示:sdp-ip和stream-ip在 NAT 环境里是最要命的。如果 WVP 部署在云主机、设备在办公网,SDP 里带的必须是公网可达地址,否则设备收不到正确的收流地址,表现为"信令 200 OK 但一直没有画面"。

4.3 打包前端、启动服务、确认 hook 通

WVP 的前端通常是独立目录(比如web/或ui/),用 npm 构建:

cd web npm install npm run build

构建产物拷到后端src/main/resources/static下,或者直接用 Nginx 托管。如果只是自己用,我建议用 Nginx 反代,前端改动不用重新打包后端,省事。

后端起服务:

mvn clean package -DskipTests java -jar target/wvp-pro-x.x.x.jar --spring.config.location=application.yml

启动成功后,去 WVP 的"媒体节点"页面看 ZLM 是否显示在线。这一步是分水岭:如果显示离线,说明 WVP 调不通 ZLM 的 API,检查media.secret、media.ip、media.http-port三项;如果显示在线但流状态不刷新,说明 ZLM 的 hook 回调打不到 WVP,去 ZLM 日志里看回调 URL 有没有 404。

两个方向是独立的:WVP → ZLM 走 HTTP API,ZLM → WVP 走 hook 回调。一个方向通不代表另一个方向通,这个认知能帮你精准定位。

5. 设备接入与联调实测

5.1 摄像头侧参数怎么填

在摄像头的"平台接入"页面,通常要填这几项:

  • SIP 服务器地址:192.168.1.100
  • SIP 服务器端口:5060
  • SIP 域:3402000000
  • SIP 用户/设备编号:20 位,比如34020000001320000001
  • 注册密码:和设备编号对应的密码
  • 注册有效期:3600秒

设备编号的构成规则要记住:前 10 位是域,中间 4 位是类型,后 6 位是序号。常见的类型编码里,132是摄像机,131是球机,118是报警主机。比如3402000000+132+000001=3402000000132000000 1这样 20 位。

不同厂商的界面差异很大。海康一般叫"平台接入 → GB28181",大华叫"国标28181",宇视在"网络 → 高级配置"里。有个通用技巧:填完保存后重启一次设备的网络服务,不少型号不重启不生效,你会以为配错了。

注册成功后,在 WVP 的"设备"页面能看到设备状态变绿,点开能展开通道列表。看不到通道通常是两个原因:设备的目录查询响应超时,或者通道被禁用了。前者等十几秒会自己出来,后者要去设备的"通道管理"里手动启用。

5.2 点播、录像、语音对讲

点播的完整链路是:WVP 收到前端请求 → 调 ZLMopenRtpServer开端口 → 给设备发 INVITE,SDP 里带上收流 IP 和端口 → 设备回 200 OK → 设备开始推 RTP → ZLM 收到第一个包后通过 hook 通知 WVP → WVP 把播放地址返回前端。这条链路上任何一环断了都会黑屏,所以排查时要按顺序看 WVP 日志 → ZLM 日志 → tcpdump。

录像功能依赖 ZLM 的record配置。默认是点播即录,也可以配成按计划录。录像文件默认落在 ZLM 目录下的www/record/里,格式是 MP4。要注意磁盘空间——100 路 24 小时能吃掉几 TB,我一般会在 ZLM 配置里加fileSecond=3600按小时切片,再配合定时任务清理超过 7 天的文件。

语音对讲是比较容易被忽略的能力,它需要满足三个条件:设备本身支持音频通道且麦克风未被禁用;SDP 协商里带了音频媒体描述(通常是a=rtpmap:8 PCMA/8000);ZLM 开启了对应的音频转发。实际调试时如果只有单向能听、反向没声音,八成是设备的音频编码和平台协商的不一致,把 SDP 里的m=audio那行的端口和 payload 号对一遍基本能定位。另外注意,很多球机的对讲通道和视频通道是分开编号的,点播用的是视频通道,对讲得切到音频通道上去发 INVITE。

5.3 级联:媒体流方向这个坑必须先说清

关于热词里提到的"wvp-gb28181-pro 不支持上级平台主动向下级联拉取资源",这里需要澄清一个概念:GB28181 的级联在设计上就不存在"上级去下级拉流"这回事。级联中的媒体流方向永远是下级主动向上级推送。上级发 INVITE 给下级,下级收到后按 SDP 里的地址把流推到上级的收流端口上,方向是下级 → 上级。

所以当你在 WVP 里配级联,遇到"上级平台点播下级资源失败",问题不在"能不能拉",而在下面几个点上:

第一,SIP ID 冲突。上级和下级如果用了同一个域或者同一个平台 ID,SIP 消息会互相打架。级联的两端必须是不同的域,比如上级3402000000、下级3402010000。

第二,网络可达性。上级要能访问下级的 SIP 端口(5060),下级也要能访问上级的 SIP 端口和 RTP 收流端口段。这两个方向是独立的,只开一边不够。

第三,Catalog 查询响应。上级发Catalog查询下级资源,下级必须在超时前返回完整通道列表。如果下级设备多、通道上千,一次性返回可能超过 UDP 的 MTU 被分片丢弃,这时要开 WVP 里的"目录分批返回"选项。

第四,媒体流推送目标地址。下级推流时用的地址来自上级 INVITE 的 SDP。如果上级在 NAT 后面,SDP 里的地址是内网 IP,下级推过去必然失败。这种情况需要在上级配置里显式指定stream-ip为公网地址。

级联症状大概率原因验证方法
上级看不到下级设备SIP ID 或域冲突两端日志对比 SIP 消息中的 From/To 域
上级看到设备但点播失败RTP 端口未放行在上级机器 tcpdump 看是否有包到达
点播成功但立即断开下级推流地址不对抓下级出口流量看目标 IP
目录只有部分通道单包过大被分片丢弃开启分批返回

6. 踩坑速查与排查手法

6.1 常见问题速查表

下面这张表是我几次部署里攒下来的高频问题,按"症状 → 直接原因 → 处理"的形式整理,出问题时可以当索引查。

症状直接原因处理方式
设备一直显示未注册SIP 域或编号不匹配核对设备侧域与 WVPsip.domain
注册成功但无通道目录查询超时检查设备目录查询开关,等待重试
媒体节点显示离线secret 或端口不一致两侧比对media.secret和http-port
点播返回 200 但黑屏RTP 端口未放行或 IP 错误tcpdump 抓 30000 段 UDP 包
流播几秒后断开无观众自动关流检查on_stream_none_reader配置
新点播全部失败RTP 端口段耗尽检查on_rtp_server_timeout是否生效
平台跑一段时间卡顿文件句柄耗尽ulimit -n调到 65535
级联后设备重复出现上下级域相同改成不同的 SIP 域

6.2 抓包与日志的三层定位法

出问题时不要凭感觉改配置,按这三层往下走。

第一层看 WVP 日志。WVP 用的是 Logback,日志里 SIP 消息会有明确的收发标记。找INVITE、200 OK、ACK这几个关键字,看信令走到哪一步断了。如果连 INVITE 都没发出去,问题在 WVP 内部,可能是 Redis 连不上导致流状态拿不到。

第二层看 ZLM 日志。ZLM 的日志在log/目录下,会记录 RTP 收流的开始和结束,以及 hook 回调的返回码。看到openRtpServer成功但一直没有on_stream_changed,说明设备根本没推流过来,问题在设备侧或网络侧。

第三层抓包。这一步才是确定性的证据:

# 抓 SIP 信令 tcpdump -i eth0 -n port 5060 -w sip.pcap # 抓 RTP 收流 tcpdump -i eth0 -n udp portrange 30000-30500 -w rtp.pcap

拿sip.pcap用 Wireshark 打开,看 INVITE 里的 SDP 内容,重点看c=那行的连接地址和m=video那行的端口。这两个值就是设备要推流的目标,一旦不对,后面全白搭。rtp.pcap里如果全是包,说明网络通、是平台侧处理有问题;如果一个包都没有,说明设备没推或防火墙拦了。

提示:抓 RTP 包时用-c 100限制包数,不然 4 Mbps 的流抓几分钟就是几个 G,磁盘瞬间爆掉。

6.3 几个能提高稳定性的调优点

跑起来和跑得稳是两回事,下面几个点是我在实际运行中调出来的。

ZLM 的线程数。config.ini里有[general] threadNum,默认是 CPU 核数。如果主要是转发不加转码,保持默认就行;如果开了 HLS 切片和 MP4 录制,可以适当加 2-4 个,但别翻倍,线程太多调度开销反而拖慢转发。

WVP 的 JVM 参数。只做信令的话-Xms512m -Xmx1g足够跑几百台设备。设成 4G 是浪费,还会让 GC 停顿变长。加上-XX:+UseG1GC会更平滑。

RTP 端口段的回收。前面提过on_rtp_server_timeout,这个一定要配。我遇到过跑了两天后所有点播都失败的场景,查了半天是设备异常离线没发 BYE,WVP 没释放端口,501 个端口被慢慢占满。配好超时回收之后这个问题就没再出现。

录像磁盘的独立挂载。录像 IO 是持续的写入,如果和系统盘共用,MySQL 的写入延迟会被拖高,表现为偶尔的信令超时。有条件就单独挂一块盘给www/record/。

设备心跳间隔。默认 60 秒,设备多的时候会形成心跳风暴,几百台设备同一秒发注册刷新,SIP 线程会被瞬间打满。把过期时间设长一点,让设备的心跳自然错开,比加机器有效。

最后分享一个我自己用了很久的小习惯:部署完先在本地用 ffmpeg 推一路测试流跑通全链路,再接入真实设备。因为 ffmpeg 的行为完全可控,而摄像头的实现千奇百怪。当你知道平台侧一定没问题时,任何一个报错都能精准指向设备,排查效率至少翻一倍。这个顺序反过来做,你会同时面对两个未知,那是纯粹的时间黑洞。

返回列表