Windows 源码编译 ZLMediaKit 最新版:工具链选型、CMake 开关与避坑指南
简介Windows平台下的ZLMediaKit最新编译版专供流媒体开发者、运维人员及需要将摄像头RTSP流转换为网页可播HTTP-FLV服务的用户使用。相比博客早期链接中的旧版此版本同步上游最新代码已支持.live.flv后缀拉流可直接配合按需拉流方案实现RTSP取流并在浏览器端播放也省去自行编译环境的搭建与依赖配置成本。压缩包为RAR格式共128个文件、约317MB内含MediaServer.exe、test_server.exe等23个可执行程序可直接启动服务端与测试工具配套的PDB/ILK调试符号和LIB导入库便于二次编译与模块对接HTML/JS/CSS构成Web管理界面PEM证书、INI/JSON配置文件及说明文档帮助快速完成环境配置。此外包内的动态链接库与静态资源让解压后的程序具备较完整运行条件。目前已有917人学习下载适合在Windows环境评估、部署或二次开发ZLMediaKit尤其适用于需要最新拉流协议支持、希望以较低成本实现摄像头Web直播的场景。1. 为什么要在 Windows 上自己编译 ZLMediakit 最新版本想在 Windows 上自己部署流媒体服务ZLMediakit 是最常被翻牌的方案一个进程同时扛 RTSP、RTMP、HLS、HTTP-FLV 和 WebRTC性能不错配置也不算复杂。但「最新编译版本」这件事Windows 用户往往比 Linux 用户更难受——官方 Release 页面的更新频率赶不上主分支IO 线程模型优化、WebRTC 的 ICE 重连、SRTP 升级这些修复都只存在于源码里。于是自己动手编译就成了绕不开的一步。下面这份记录是我在 Windows Server 上从源码编译 ZLMediakit 的完整过程工具链怎么选、CMake 开关怎么设、编译完怎么跑起来以及五个我踩过的坑。适合需要跟进上游版本、或者想裁剪能力做二次集成的开发者。2. 编译前准备工具链选型、依赖清单与三种获取“最新版本”的路径2.1 为什么官方 Release 不等于“最新编译版本”官方 Release 会周期性地放出 Windows 包但如果你需要的是当天修复的 bug 或刚合并的特性等 Release 是不现实的。ZLMediakit 的主分支开发节奏很快很多改动从合入到出现在 Release 页面中间隔着数周甚至更久。另一个常见路径是下载第三方编译包这类包确实省事但你不知道它用的是哪个 commit、哪些 CMake 开关被打开依赖 DLL 的来源也不透明生产环境一旦出问题很难复盘。所以“最新编译版本”最可靠的做法是自己拉最新源码、自己编一遍顺手把不需要的协议关掉。如果你完全不想碰编译还有一个替代思路是在 Windows 上装 Docker 后跑官方镜像适合快速验证不适合长期跟进上游。镜像更新同样滞后而且 Windows 上的 Docker 端口映射与文件挂载会带来新的网络层开销我见过有人用 Docker 版跑 WebRTCUDP 端口映射没配好浏览器侧一直卡在连接中。真正要跟进上游版本源码编译仍然是绕不开的那条路。2.2 工具链选型VS2022 CMake 为什么比 MinGW 省心在 Windows 上编译 ZLMediakit最省心的是 Visual Studio 2022 社区版 CMake 的组合。需要安装的组件是「使用 C 的桌面开发」它自带 MSVC 编译器、Windows SDK 和 CMake 支持。如果服务器没有桌面环境也可以只装 Build Tools for Visual Studio 2022 的命令行工具集我只装 VC 工具集加独立 CMake一样能编出完整产物。为什么不推荐 MinGWZLMediakit 的依赖链里OpenSSL 和 libsrtp 在 MinGW 下要么找预编译库很费劲要么需要自己再用 mingw 编译一遍而 MSVC 生态里 vcpkg 能一条命令把 OpenSSL、libsrtp 全部装好CMake 直接识别。MinGW 不是不能编是时间成本不划算。另外注意编译机和运行机都别用 32 位ZLMediakit 的并发模型在 x64 下才是完整形态我见过有人用 x86 编出来跑 RTMP 推流连接数一上来 CPU 直接拉满。装完组件后在命令行分别执行cmake --version和cl验证。如果cl报错说明没进开发者环境直接从开始菜单打开「x64 Native Tools Command Prompt for VS 2022」所有环境变量会自动配好。CMake 建议装独立版版本不低于 3.20因为新版 ZLMediakit 的 CMakeLists 用了较新的语法太老的 CMake 会在配置阶段直接语法报错错误提示还不直观。2.3 依赖清单OpenSSL、libsrtp、ZLToolKit 哪个能裁剪先看一张依赖表再决定你要装什么依赖是否必须作用裁剪方式ZLToolKit必须网络事件循环、线程池、日志框架随 ZLMediakit 工程一起编译无法单独裁剪OpenSSL强烈建议HTTPS、SRTP 密钥协商、API 鉴权传输加密关ENABLE_OPENSSL可去掉但会失去 HTTPS 与 WebRTC 能力libsrtpWebRTC 必需WebRTC 的 SRTP 包加密不开ENABLE_WEBRTC就不用装FFmpeg可选转封装、HLS 转码、GB28181 等不开ENABLE_FFMPEGx264可选H.264 软编码不转码不装很多人一看到依赖列表就以为编译很复杂其实核心只有 ZLToolKit 和 OpenSSL。libsrtp 只有在开 WebRTC 时才需要如果你只是把流拉出来给分析程序用比如接了 YOLO 做检测拉的是 RTSP 或 HTTP-FLV 裸流WebRTC 完全可以关掉构建时间能少一大截。至于 FFmpeg 和 x264纯流媒体分发不需要除非你要做实时转码或协议转封装。裁剪的原则是在 CMake 阶段用开关决定而不是去源码里删文件这样下次升级版本时只需要重新拉一次代码开关配置原样复用。还有一个常见误用是以为装了 OpenSSL 程序就能自动找到其实 MSVC 编译出来的程序找 DLL 是按 exe 所在目录、PATH 顺序查找的不到运行那一刻你不知道缺什么这个后面第 5 章会重点说。2.4 开始前确认这条命令能跑通准备阶段的最终检查非常简单在 x64 Native Tools 命令行里执行cmake --version # 输出 3.20 以上 cl # 输出版本信息而不是“找不到命令” git --version # 输出 git 版本三条都通过再继续。cl找不到一般是组件没装全回到 VS Installer 勾上「使用 C 的桌面开发」cmake找不到就装独立 CMake 并加入 PATH。这一步花两分钟能省掉后面配置阶段一半的报错排查。3. 用 CMake Visual Studio 编译 ZLMediakit从源码到 MediaServer.exe 的完整命令3.1 拉取源码两个仓库必须放同一级目录ZLMediakit 的构建依赖配套的 ZLToolKit 仓库两者由同一个组织维护版本需要始终同步。拉取命令mkdir D:\ZLMediaKit-build cd D:\ZLMediaKit-build # 两个仓库同级放置CMake 通过 ../ZLToolKit 找到依赖 git clone --depth 1 https://github.com/ZLMediaKit/ZLMediaKit.git git clone --depth 1 https://github.com/ZLMediaKit/ZLToolKit.gitZLMediaKit 的主工程通过 CMake 去上级目录找 ZLToolKit 源码两个仓库不放在同一级配置阶段就会直接退出报错信息里会包含 ZLToolKit 路径字样。--depth 1只拉最新提交这正是「最新编译版本」需要的如果你之后要对比某个旧版本需要去掉--depth 1做全量 clone再git checkout到对应 tag。第一次 clone 数据量不大网络不稳定就多试两次别急着换方式。3.2 用 vcpkg 准备 OpenSSL 和 libsrtpvcpkg 是微软维护的 C/C 库管理器这里用它解决 OpenSSL 和 libsrtp 的编译与路径问题。命令git clone https://github.com/microsoft/vcpkg.git cd vcpkg .\bootstrap-vcpkg.bat # 明确指定 x64避免默认装 32 位版本 .\vcpkg install openssl:x64-windows libsrtp:x64-windowstriplet 写成x64-windows是必须的否则 vcpkg 默认装 x86 版本后面 CMake 配 x64 工程时会找不到库。如果你不打算开 WebRTClibsrtp:x64-windows可以不装命令改成只装 openssl 即可。安装时间取决于机器OpenSSL 编译慢的时候十几分钟正常看到输出里出现安装完成的时间统计就说明装完了。装完不要关这个窗口下一步 CMake 要引用 vcpkg 的 toolchain 文件路径D:\ZLMediaKit-build\vcpkg\scripts\buildsystems\vcpkg.cmake。3.3 CMake 配置命令九个关键开关一次说清回到 ZLMediaKit 源码目录执行配置命令。以下命令假设你用 VS2022 和 vcpkgcd D:\ZLMediaKit-build\ZLMediaKit cmake -B build -G Visual Studio 17 2022 -A x64 -DCMAKE_TOOLCHAIN_FILED:\ZLMediaKit-build\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLETx64-windows -DENABLE_WEBRTCON -DENABLE_MP4ON -DENABLE_HLSON -DENABLE_SRTOFF -DENABLE_OPENSSLON -DENABLE_X264OFF -DENABLE_FFMPEGOFF逐个说开关ENABLE_WEBRTC需要 libsrtp开启后编译产物和运行内存都会增加不需要就关ENABLE_MP4控制 MP4 录制和点播ENABLE_HLS控制 HLS 切片输出做网页拉流通常要留着ENABLE_SRT是 SRT 低延迟传输协议不玩公网传输可以先关ENABLE_OPENSSL必须为 ON否则 API 鉴权和 HTTPS 全废ENABLE_X264和ENABLE_FFMPEG都关纯分发场景用不到开着反而要去额外下载 FFmpeg 库。-A x64指定 64 位-G Visual Studio 17 2022对应 VS2022VS2019 用户把 17 改成 16。CMAKE_BUILD_TYPE在 VS 生成器下不决定最终配置编译时靠--config Release指定所以这里不写它。如果你确认不要 WebRTC把ENABLE_WEBRTC改成 OFF并在 3.2 里不装 libsrtp这是很多接 YOLO 做视觉分析的部署选型拉流用 RTSP 或 HTTP-FLV浏览器侧根本不需要 WebRTC 推流。同样是“最新编译版本”开关组合不同产物体积和稳定性差异很大。提示配置阶段如果报找不到 srtp 或 openssl先回 3.2 确认 vcpkg 装的是 x64-windows 而不是默认的 x86。3.4 编译、定位产物与运行时 DLL配置通过后开始编译cmake --build build --config Release --parallel 8 cd build\bin\Release dir首次全量编译二十分钟到一个小时都正常--parallel 8是并行任务数CPU 核心少就改 4。编译完成后build\bin\Release下会有 MediaServer.exe 和一批测试工具这个目录就是你的运行目录。但别急着双击还差依赖 DLL。OpenSSL 的动态库在 vcpkg 的 installed 目录里需要拷到 exe 旁边$vcpkgBin D:\ZLMediaKit-build\vcpkg\installed\x64-windows\bin Copy-Item $vcpkgBin\libssl-3-x64.dll . -Force Copy-Item $vcpkgBin\libcrypto-3-x64.dll . -Force if (Test-Path $vcpkgBin\srtp3.dll) { Copy-Item $vcpkgBin\srtp3.dll . -Force }libssl-3-x64.dll和libcrypto-3-x64.dll的版本号会随 vcpkg 的 OpenSSL 版本变化如果文件名对不上用Get-ChildItem $vcpkgBin | Where-Object {$_.Name -match ssl|srtp}列出实际文件再拷贝。srtp3.dll只在开了 WebRTC 时存在所以用 Test-Path 判断。ZLToolKit 不需要单独编译或拷贝 DLL它在 CMake 配置阶段被织入 ZLMediaKit 工程一起构建默认以静态库形式链进 MediaServer.exe。官方 Release zip 解压就能跑但里面没有你刚才设的那些开关自己编译的意义就在这些ENABLE_*参数都由你决定。很多人说“同样叫新版自己编的跑得更稳”其实不是编译器差异而是开关组合和依赖来源更可控。4. 编译版本跑起来最小配置、端口规划与自检命令4.1 最小运行目录exe、DLL 与 config.ini 的摆放关系ZLMediaKit 启动时默认在当前工作目录找 config.ini所以运行前把源码conf目录下的模板拷贝到 exe 同目录cd build\bin\Release Copy-Item D:\ZLMediaKit-build\ZLMediaKit\conf\config.ini . -Force .\MediaServer.exe第一次启动别加-d前台跑能看到完整日志确认起来了再谈后台化。启动日志里会打印监听端口和配置加载路径。打开 config.ini改动几个地方[http]段的port改 10080因为 Windows 上 80 端口经常被 IIS 或 SQL Server Reporting Services 占用[api]段设一个secret给后面的鉴权和自检用[rtsp]的端口保持 554[rtmp]的端口保持 1935这两个端口被占的概率低一些。如果启动日志直接报端口绑定失败先别急着找 ZLMediaKit 的毛病用netstat -ano | findstr :10080看是谁占着端口再决定是改自己配置还是处理占用进程。与其去「关闭端口号」不如改 ZLMediaKit 的监听端口因为改自己配置比动系统服务风险低得多。4.2 端口规划哪些必须放行哪些按需开先给一张我常用的端口表把值和用途固化成团队规范端口协议用途建议10080/tcpHTTPAPI 管理接口、HTTP-FLV、HLS 拉流必须放行554/tcpRTSPRTSP 拉流/推流按需放行1935/tcpRTMPRTMP 推流/拉流按需放行8000/udpWebRTCWebRTC 音视频数据通道开 WebRTC 时必须放行Windows 防火墙是默认拦入站的本机回环 127.0.0.1 测不出问题换局域网 IP 一拉流就卡住。用netsh advfirewall firewall精确放行这几个端口比临时关防火墙干净第 5 章会给完整命令。如果你把 API 端口改成了 10080记得同时看下[http]段的sslport不开 HTTPS 就保持注释状态。我为什么强调把端口固定下来因为 ZLMediaKit 的 API、流媒体服务和 WebRTC 是三套独立监听端口一旦随启动参数漂移后续的防火墙规则、NSSM 服务参数、监控报警全都要跟着改。踩过一次端口漂移的坑后我把端口写死成了配置模板新环境复制粘贴就能用。4.3 三行命令做首屏自检API、RTSP 拉流、RTMP 推流服务起来后按顺序执行三条命令curl.exe http://127.0.0.1:10080/index/api/getServerConfig ffmpeg -re -i test.mp4 -rtsp_transport tcp -c copy -f rtsp rtsp://127.0.0.1:554/live/test ffplay rtsp://127.0.0.1:554/live/test第一条返回的 JSON 里code为 0 就说明 API 通了data 里能看到编译时间戳和版本号这也能验证你编的确实是最新 commit。第二条用 ffmpeg 推一条 RTSP 流到 ZLMediaKit-rtsp_transport tcp指定走 TCP避免 UDP 被 Windows 防火墙拦-c copy不做转码测试时 CPU 占用接近 0。第三条拉流能出画面就说明推拉链路全通。没有 ffplay 就用 VLC 打开同一个 RTSP 地址效果一样。测完 127.0.0.1 再用本机局域网 IP 测一遍这一步能提前暴露防火墙问题。以后在 Windows 上做直播流调试完全可以全程命令行完成不需要图形界面这也是「命令行直播」调试流最实用的习惯。4.4 调日志级别与正确使用 log 目录config.ini 里[general]段的log_level决定控制台和日志文件详细度调试阶段设 0 或 1跑熟后设 2。日志文件默认写在 exe 同目录的log文件夹按天滚动。如果你把推流源命名成业务含义比如rtsp://127.0.0.1:554/camera/entrance01日志里就能直接看到某一路流的推流时间、断流原因、带宽占用。看日志时留意两条信息推流成功会出现「流媒体注册成功」类似字样拉流结束会打印「无人观看自动关闭」之类的回收信息。这些输出在 Windows 事件日志里看不到别去翻系统安全日志ZLMediaKit 自己的 log 文件夹才是第一排查入口。另外配置里如果写了绝对路径用正斜杠/比反斜杠稳ZLMediaKit 内部是跨平台实现Windows 的反斜杠在转义场景下容易让路径拼接出错。5. Windows 编译 ZLMediakit 的 5 个高频坑与排查手段5.1 坑一启动报错找不到 libssl-3-x64.dll现象编译成功双击 MediaServer.exe 弹窗「找不到 libssl-3-x64.dll」或命令行启动直接报错退出。原因MediaServer.exe 优先按 exe 所在目录找 DLLvcpkg 把 OpenSSL 的 DLL 装在installed\x64-windows\bin没拷过来。解决把 OpenSSL 和 libsrtp 的 DLL 拷贝到 exe 同目录命令在 3.4 已给过。拷贝完用dir *.dll确认清单。如果系统里装了多个 OpenSSL 版本文件名可能带不同后缀以 vcpkg installed 目录里实际文件为准。换机器部署时同样要带上这套 DLL只拷 exe 过去会在别的机器上报同样的错这个坑和 VB6 程序缺 msvbvm60.dll 本质一样都是运行库依赖没随程序分发。5.2 坑二回环拉流正常局域网拉流一直转圈现象127.0.0.1 拉流秒开换成局域网 IP 后播放器一直转圈或超时。原因Windows 防火墙默认阻止入站连接RTSP/TCP 或 WebRTC/UDP 没放行。解决用 netsh 放行端口rem 按实际端口调整只放行你需要的协议 netsh advfirewall firewall add rule nameZLMediaKit TCP dirin actionallow protocolTCP localport554,1935,10080 netsh advfirewall firewall add rule nameZLMediaKit UDP dirin actionallow protocolUDP localport8000放行后再测。如果还不通打开「事件查看器—Windows 日志—安全」筛选来源为 Windows Filtering Platform 的事件看有没有拦截记录。有记录就说明规则没生效检查端口和协议有没有写错没有记录就去查交换机或虚拟机的安全组策略。局域网排错时回环通、局域网不通九成是防火墙先把这条路径走完再动配置。5.3 坑三WebRTC 编译失败或者连不上现象CMake 配置报找不到srtp2/srtp.h或者编译通过但 Chrome 里一直连接中。原因前一种是没装 libsrtp或者装了但 CMake 没通过 vcpkg toolchain 找到它后一种通常是 UDP 端口 8000 没放行或者 NAT 环境没有做端口映射。解决编译期错误确认 3.2 装了libsrtp:x64-windows且 3.3 的CMAKE_TOOLCHAIN_FILE指向 vcpkg.cmake。运行期问题先检查防火墙 UDP 8000再用浏览器开发者工具看 WebRTC 的 ICE 状态Candidate 地址如果是内网 IP 且双方能 ping 通基本就是 UDP 被拦。WebRTC 在局域网内跑必须保证 UDP 从客户端直达服务端中间任何 NAT 设备都要把 UDP 8000 转进来。这个排查链路比 RTSP 长建议先把 RTSP 跑通再开 WebRTC避免两个变量同时排。5.4 坑四杀毒软件静默删掉 MediaServer.exe现象启动时闪退任务管理器里没有进程Windows 安全中心显示「威胁已被处理/已隔离」或者第三方杀软弹窗提示。原因自己编译的 exe 没有数字签名容易被 Defender 或国产杀软误报。解决在「Windows 安全中心—病毒和威胁防护—排除项」里把编译输出目录加进去第三方杀软把整个运行目录加白。这个坑在 Windows Server 上尤其常见因为服务器默认开着更强的防护策略。加完排除项重新拷贝 exe 再启动。如果线上要分发建议用Get-FileHash MediaServer.exe记录 SHA256部署后校验一次防止安全软件在同步过程中「修复」成空文件。5.5 坑五cmd 前台正常做成服务后秒退现象手动双击或命令行跑没问题注册成 Windows 服务后一启动就停服务列表显示停止事件查看器报 7034 或 7001。原因服务的工作目录不是 exe 所在目录导致 config.ini 和 log 目录找不到或者启动脚本里用了相对路径。解决注册服务时显式指定 AppDirectory启动参数用绝对路径的 config.ini。如果你用批处理包装服务不要写成start MediaServer.exe后立即退出这样服务会认为主进程已经结束而把服务停掉。很多「脚本命令闪退」不是真的闪退是启动方式让服务拿不到持续运行的进程句柄。排查这类问题先看服务事件日志再看 exe 同目录的 log 文件夹顺序反了容易浪费时间。6. 让新编译版本长期稳定运行服务化、鉴权与健康自检自己编译的 ZLMediakit 跑通只是开始生产环境要处理三件事进程意外退出能自动拉起、API 不能裸奔、每一天都能确认它在正常服务。下面是我目前固定的做法。6.1 用 NSSM 注册成 Windows 服务并自动重启rem 启动目录必须指向 exe 所在目录否则 config.ini 找不到 nssm install ZLMediaKit D:\ZLMediaKit-build\ZLMediaKit\build\bin\Release\MediaServer.exe -c D:\ZLMediaKit-build\ZLMediaKit\build\bin\Release\config.ini nssm set ZLMediaKit AppDirectory D:\ZLMediaKit-build\ZLMediaKit\build\bin\Release nssm set ZLMediaKit AppExit Default Restart nssm set ZLMediaKit AppThrottle 3000 nssm start ZLMediaKitAppDirectory如果不设服务启动的工作目录会在 system32config.ini 直接找不到AppExit Default Restart让进程退出后自动重启AppThrottle 3000表示崩溃后间隔 3 秒再拉起避免崩溃风暴把 CPU 打满。6.2 开启 API 鉴权并用 PowerShell 做健康自检在 config.ini 的[api]段设置secret你自己的密钥所有 API 调用都要带?secret。健康自检脚本用 PowerShell 写通过任务计划程序每 5 分钟跑一次$sec 你的密钥 $resp Invoke-RestMethod http://127.0.0.1:10080/index/api/getServerConfig?secret$sec if ($resp.code -eq 0) { $resp.data.mediaServer.version } else { Write-Error $resp.msg Restart-Service ZLMediaKit -Force }code0并且能打印出版本字符串就说明 API、鉴权、进程都在工作状态失败时重启服务并看一眼日志文件里的最后几行。这个脚本可以用任务计划程序注册成每 5 分钟运行动作选「启动程序」。最后再用Get-FileHash MediaServer.exe记录一次 SHA256升级或部署时核对防止二进制文件被安全软件误删或替换。我自己第一次在 Windows 上编译时编译本身没翻车翻车全在 DLL、防火墙和服务目录上。后来把上面这套固定成模板新版本升级只需要重复第 3 章的 CMake 命令和这个服务脚本半小时内能完成从拉代码到上线。希望帮到你。本文还有配套的精品资源点击获取