1. 开篇为什么你需要一个自己的国标视频平台如果你正在看这篇文章大概率是遇到了一个非常具体的问题手头有一堆摄像头可能是海康、大华也可能是其他支持国标GB/T 28181协议的设备你想把它们统一管理起来实现网页直播、录像回放、设备控制甚至还想搞点二次开发。但市面上的商业平台要么太贵要么不够灵活要么就是“黑盒子”你完全不知道里面是怎么跑的。别急这正是我几年前踩过的坑。当时为了一个项目我几乎试遍了所有开源方案最终发现wvp-28181-pro和ZLMediaKit这套组合拳是构建私有化、可定制国标视频平台的最优解。wvp负责“管人”也就是信令和控制ZLMediaKit负责“干活”也就是媒体流的转发和处理。它俩一结合就是一个五脏俱全、完全自主可控的视频中台。今天我就带你从零开始手把手完成这两个核心组件的深度集成。这不是一个简单的安装教程我会重点拆解它们之间“握手”的细节让你明白信令是怎么流转的视频流又是怎么被拉取和分发的。理解了这些以后出任何问题你都能自己定位甚至可以根据业务需求进行魔改。整个过程我会尽量用大白话和实际操作的例子来讲哪怕你之前没怎么接触过流媒体跟着做也能跑起来。2. 环境准备给平台一个安稳的家在开始敲命令之前我们得先把“地基”打好。这个地基包括操作系统、基础依赖和两个核心的数据库。我强烈建议你使用Linux系统进行部署无论是Ubuntu还是CentOS稳定性和性能都比Windows好太多社区支持也更完善。这里我以 Ubuntu 20.04 LTS 为例其他系统命令稍有不同但思路完全一致。2.1 安装系统级依赖这些是编译和运行 wvp-pro 及 ZLMediaKit 所必需的工具包。打开你的终端依次执行以下命令。首先更新软件包列表确保我们安装的是最新版本sudo apt-get update接下来安装 Java 运行环境、Git、Maven、Node.js 和 NPM。wvp-pro 的后端是 Java (Spring Boot) 写的前端是 Vue所以需要这些来编译和运行。sudo apt-get install -y openjdk-11-jdk-headless git maven nodejs npm这里我选择了 OpenJDK 11它是目前长期支持且兼容性很好的一个版本。安装完成后别忘了验证一下java -version mvn -v node -v如果都能正确输出版本号说明基础环境就绪了。2.2 部署数据库MySQL 与 Rediswvp-pro 用 MySQL 来存储所有持久化数据比如设备信息、通道列表、用户权限等。而 Redis 则用作缓存和消息队列提升系统响应速度处理一些实时状态信息。安装 MySQLsudo apt-get install -y mysql-server sudo systemctl start mysql sudo systemctl enable mysql安装完成后运行安全初始化脚本设置 root 密码并移除一些不安全默认设置sudo mysql_secure_installation接着登录 MySQL为 wvp-pro 创建一个专用的数据库和用户sudo mysql -u root -p在 MySQL 提示符下执行CREATE DATABASE wvp CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; CREATE USER wvp_user% IDENTIFIED BY YourStrongPassword123!; GRANT ALL PRIVILEGES ON wvp.* TO wvp_user%; FLUSH PRIVILEGES; EXIT;这里创建了一个名为wvp的数据库并授权给用户wvp_user。请务必将YourStrongPassword123!替换成你自己设定的强密码。%允许从任何主机连接如果你只在本地部署可以改为localhost更安全。安装 Redissudo apt-get install -y redis-server sudo systemctl start redis-server sudo systemctl enable redis-serverRedis 默认配置基本够用但建议你修改一下配置文件/etc/redis/redis.conf找到bind 127.0.0.1这一行如果你需要从其他服务器访问 Redis可以将其注释掉前面加#或改为bind 0.0.0.0并设置一个密码找到# requirepass foobared去掉注释并改掉foobared。修改后重启 Redissudo systemctl restart redis-server。3. 编译与部署 ZLMediaKit你的高性能流媒体引擎ZLMediaKit 是整个平台的流媒体核心所有视频流的接收、转码、分发RTSP、RTMP、HLS、HTTP-FLV等都由它来完成。它的性能非常强悍单机就能轻松支撑数百路并发。3.1 获取源码与编译首先我们把代码拉取到本地。为了速度我们使用 Gitee 的镜像仓库git clone --depth 1 https://gitee.com/xia-chu/ZLMediaKit.git cd ZLMediaKit千万别忘了初始化子模块很多编译错误都是因为这步漏了git submodule update --init --recursive接下来是编译环节。ZLMediaKit 使用 CMake 进行构建。我们创建一个构建目录并进入mkdir build cd build然后运行 CMake 生成编译配置。这里我们启用一些常用的功能比如 SSL 支持用于 HTTPS/WSScmake .. -DCMAKE_BUILD_TYPERelease -DENABLE_WEBRTCtrue -DENABLE_SRTtrue参数解释-DCMAKE_BUILD_TYPERelease是编译发布版本性能最优-DENABLE_WEBRTC和-DENABLE_SRT是按需开启 WebRTC 和 SRT 协议支持如果你不需要可以去掉。最后使用 make 进行编译-j4表示用4个线程并行编译速度更快数字可按你 CPU 核心数调整make -j4编译过程可能需要几分钟耐心等待。成功后在build/release/linux/Debug或build/release/linux/Release目录下取决于你的编译类型你会找到MediaServer这个可执行文件它就是 ZLMediaKit 的服务端程序。3.2 配置与运行 ZLMediaKitZLMediaKit 的配置文件是config.ini通常位于可执行文件同目录下。首次运行前我们可以先复制一份默认配置cd release/linux/Release cp config.ini.default config.ini现在你可以直接用默认配置启动它试试看./MediaServer -d -d参数表示以守护进程后台模式运行。启动后你可以通过netstat -tunlp | grep MediaServer查看它监听的端口默认有 80、443、554、1935等或者直接访问http://你的服务器IP:80应该能看到一个简单的状态页面。不过为了后续与 wvp-pro 完美集成我们最好关注两个关键配置项在config.ini中[http]段落下的port这是 ZLM 的 HTTP API 端口wvp-pro 通过这个端口控制 ZLM。默认是 80如果冲突可以改成其他比如6080。[hook]段落这是 ZLM 的事件回调配置非常重要。你需要将on_flow_reporton_playon_publishon_record_mp4on_rtsp_authon_rtsp_realmon_shell_loginon_stream_changedon_stream_none_readeron_stream_not_foundon_server_started这些事件的admin_params都设置成一个密钥例如secret035c73f7-bb6b-4889-a715-d9eb2d1925cc。同时将enable设为 1并将url指向你即将部署的 wvp-pro 的 hook 地址如http://wvp服务器IP:18080/index/hook。这样 ZLM 有任何事件比如有流注册、有播放请求都会通知 wvp-pro。4. 编译与配置 wvp-28181-pro国标信令的大脑wvp-pro 是国标协议的信令服务器负责设备的注册、目录查询、云台控制、录像检索与回放等所有“指挥调度”工作。它自己不处理具体的视频流而是“命令” ZLMediaKit 去处理。4.1 获取源码与编译前端同样我们从 Gitee 克隆代码git clone https://gitee.com/pan648540858/wvp-GB28181-pro.git cd wvp-GB28181-prowvp-pro 的前后端是分离的。前端代码在web_src目录下我们需要先编译它。进入目录并安装依赖、构建cd web_src # 可以使用淘宝镜像加速 npm install --registryhttps://registry.npmmirror.com npm run build这个build过程会把 Vue 源码打包成静态文件。如果网络不好导致npm install失败多试几次或检查网络。成功编译后会在上级目录的src/main/resources下生成一个static文件夹里面就是编译好的前端页面。4.2 初始化数据库与编译后端回到项目根目录现在我们需要初始化数据库。将项目sql目录下的mysql.sql文件导入到之前创建的wvp数据库中cd .. mysql -u wvp_user -p wvp sql/mysql.sql输入你之前设置的密码这条命令会创建所有必要的表结构。接下来使用 Maven 打包 Java 后端项目mvn package -DskipTests-DskipTests参数是为了跳过测试加快打包速度。这个过程会下载大量依赖请保持网络通畅。完成后在target目录下你会找到wvp-pro-*.jar文件这就是可运行的 Spring Boot 应用包。4.3 深度配置详解让 wvp 与 ZLM 握手这是最关键的一步配置不对两者就无法通信。我们不建议直接修改 jar 包里的配置文件而是将配置文件提取到外部。复制一份配置文件模板到方便的地方比如和 jar 包同级cp src/main/resources/application-dev.yml ./application.yml现在我们来详细编辑这个application.yml文件。数据库连接配置找到spring.datasource部分修改为你自己的 MySQL 信息spring: datasource: url: jdbc:mysql://localhost:3306/wvp?useUnicodetruecharacterEncodingUTF8rewriteBatchedStatementstrueserverTimezoneAsia/Shanghai username: wvp_user password: YourStrongPassword123!Redis 配置找到spring.redis部分spring: redis: host: localhost port: 6379 password: your_redis_password # 如果没设密码就留空或删掉这行 database: 0 # 建议给wvp单独用一个db比如 1SIP 服务器配置国标核心这是 wvp 作为国标服务器的身份标识设备会向这个地址注册。sip: ip: 192.168.1.100 # 【必须】你的服务器公网IP或内网IP设备能访问到的 port: 5060 # SIP信令端口默认5060 domain: 3402000000 # SIP域国标编码一般用前10位 id: 34020000002000000001 # SIP服务器ID国标20位编码 password: admin123 # 设备注册密码可自定义这里的ip至关重要。如果设备在公网这里必须填服务器的公网IP如果是内网测试填内网IP。domain和id需要符合国标编码规则你可以用默认的也可以根据自己情况修改。媒体服务器ZLM配置这是 wvp 与 ZLMediaKit 通信的桥梁。media: id: FQ3TF8yT83wh5Wvz # ZLM的唯一标识自定义与ZLM配置对应可选但建议设置 ip: 192.168.1.100 # 【必须】ZLM服务器的IP同上需可达 http-port: 6080 # 【必须】ZLM的HTTP API端口config.ini里[http]的port secret: 035c73f7-bb6b-4889-a715-d9eb2d1925cc # 【必须】Hook密钥与ZLM的hook.admin_params一致 rtp: enable: true # 启用多端口模式兼容性更好 port-range: 30000,30500 # RTP流发送端口范围 send-port-range: 30000,30500 # 级联发送端口范围请确保ip、http-port和secret与 ZLMediaKit 的实际配置完全一致。secret就像一把钥匙两边必须用同一把。其他实用配置在user-settings部分有一些影响行为的开关user-settings: auto-apply-play: true # 自动点播用固定流地址播放时自动触发点播方便 play-timeout: 10000 # 点播超时时间毫秒网络不好可调大 interface-authentication: true # 开启API接口鉴权生产环境建议开启 record-sip: true # 是否录制国标通道的录像 save-position-history: false # 是否保存设备移动位置历史如云台配置完成后保存文件。5. 启动、联调与排坑实战万事俱备只欠东风。我们按顺序启动服务并观察日志来验证集成是否成功。第一步启动 ZLMediaKit。进入你的 ZLM 编译输出目录使用配置文件启动cd /path/to/ZLMediaKit/release/linux/Release ./MediaServer -c config.ini -d 查看日志确认无报错tail -f logs/MediaServer.log。你应该能看到服务器启动并加载了 hook 配置。第二步启动 wvp-pro。在application.yml所在目录运行java -jar wvp-pro-*.jar如果想让它在后台运行可以用nohup java -jar wvp-pro-*.jar 。启动时注意观察控制台日志。关键的成功标志是看到类似这样的信息... c.g.w.w.s.i.ZlmServiceImpl - ZLMediaKit 连接成功 ... c.g.w.w.s.i.ZlmServiceImpl - 设置ZLM hook 成功这表示 wvp-pro 已经成功连接上了 ZLMediaKit 并配置好了 Hook。第三步登录平台并添加设备。浏览器访问http://你的服务器IP:18080默认端口使用默认账号admin密码admin登录。进入后首先在“媒体服务器”页面你应该能看到一个状态为“在线”的 ZLM 服务器ID 就是你配置的media.id。这说明信令层面的连接完全正常。接下来就是激动人心的时刻添加国标设备。在“国标设备”页面点击“添加”。你需要填写设备的国标编号20位、IP、端口默认5060、密码设备侧配置的认证密码和你的 SIP 服务器信息即你在 wvp 中配置的sip.id和sip.ip。配置保存后如果网络可达且密码正确设备状态会很快变成“在线”并且会自动同步通道列表过来。第四步测试播放与排坑。在通道列表里点击某个通道的“播放”按钮。这个过程背后发生了很多事wvp 向设备发送 SIPINVITE消息请求点播。设备回复200 OK并在 SDP 中告知媒体流接收地址和端口。wvp 将这个信息设备流地址通过 HTTP API 告诉 ZLM“去这个地址拉流”。ZLM 启动一个 RTP 端口向设备拉取视频流。同时wvp 会生成一个播放地址如http://你的ZLM-IP:6080/rtp/34020000001320000001.live.flv返回给前端。前端播放器如 jessibuca拿到这个地址向 ZLM 发起 HTTP-FLV 播放请求。ZLM 将拉取到的 RTP 流转封装成 FLV推送给播放器。如果播放失败你可以按这个链路排查设备一直离线检查 wvp 的sip.ip是否填写正确设备要能访问到这个IP检查防火墙是否放行了 5060 SIP 端口。播放器黑屏/加载失败打开浏览器开发者工具的“网络”选项卡看播放地址的请求是否返回了200 OK并持续接收数据。如果没有查看 wvp 和 ZLM 的日志。常见原因是 ZLM 的media.ip配置错误必须是播放器能访问的地址或者 RTP 端口范围30000-30500被防火墙阻挡。ZLM Hook 失败在 ZLM 的日志里搜索on_stream_changed等 hook 事件看是否成功回调到了 wvp200状态码。如果回调失败检查 wvp 的 hook 地址是否可访问以及secret是否一致。6. 进阶云端录像与级联实战基础功能跑通后你可以探索更强大的功能。云端录像是刚需。wvp-pro 通过一个辅助服务wvp-pro-assist来管理 ZLM 生成的 MP4 录像文件。你需要单独编译并运行这个服务然后在 wvp 配置中指定record-assist-port。之后在界面上就能对通道进行定时录像、手动录像和录像检索回放了录像文件会存储在 ZLM 配置的rootPath下的record目录。另一个高级功能是国标级联。这意味着你的 wvp 平台可以作为下级平台向上级国标平台如公安视频网平台注册。配置就在 wvp 的“系统管理”-“上级平台”里。你需要填写上级平台的 SIP 信息。级联成功后上级平台就能看到你平台上的所有通道并可以调用播放。这里的关键是网络互通和 SIP 域、ID 编码符合上级要求。级联的媒体流发送端口范围就是配置中rtp.send-port-range指定的。在实际项目中我还遇到过 NAT 穿透的问题。如果设备或 ZLM 服务器在多层 NAT 之后可能需要配置 STUN 服务器或进行端口映射。wvp 和 ZLM 都支持配置外网 IPsdp_ip和stream_ip在复杂网络环境下仔细配置这几个参数往往能解决问题。最后性能调优方面对于高并发场景可以调整 ZLM 的config.ini中的线程数threadNum、合并写配置mergeWriteMS以及调整 wvp 的 JVM 启动参数如-Xmx4g分配更多内存。监控方面ZLM 有丰富的 HTTP API 可以获取流状态、服务器负载wvp 也记录了详细的操作日志便于集成到你的运维体系中。这套组合我已经在多个生产环境稳定运行了两年多从几十路到几百路的项目都支撑过。它的优势就在于架构清晰出了问题你知道该看哪里的日志该调哪个参数。希望这份超详细的指南能帮你少走弯路顺利搭建起属于自己的、功能强大的国标视频能力中台。如果在配置过程中遇到具体报错多看看日志文件大部分答案都在里面。