简介:ZLMediaKit是一款轻量级、高并发、低延迟的流媒体服务器,最新编译的Windows 64位版本为开发者省去源码编译环节,可直接部署于Windows Server或Windows 10/11,用于直播推流、拉流分发及多协议转换。它支持RTSP、RTMP、HLS、HTTP-FLV等主流协议,并可搭配WebRTC实现低延迟播放,在在线教育、远程会议、安防监控等场景中非常实用。压缩包共61个文件、约30.67MB,核心包含MediaServer.exe可执行程序、mk_api.dll动态库、config.ini配置文件和www前端页面,同时提供lib导入库、manifest清单、pem证书、日志及license等附属文件,便于二次开发与排错。Release目录已整理好,拷贝后按官方文档修改配置即可快速启动,也适合通过API进行功能扩展。目前已有909人学习下载,无论是流媒体初学者还是生产环境维护者,都能借助这份资源快速搭建稳定服务。
1. 为什么我把Windows上的直播推流交给了ZLMediaKit
拿到这个2024年5月30日编译好的ZLMediaKit Windows64版本时,我的第一反应是先看日志文件的时间戳和目录结构。这份资源的价值很直接:它省掉了在Windows上配置CMake、拉依赖、编译整个工程的折腾,直接把MediaServer.exe和配套dll打包好,解压就能跑。对维护Windows服务器、又不想碰这套编译链的开发者来说,这是最省时间的上手方式。
我选择它是因为ZLMediaKit对http-flv和RTSP的支持足够扎实,在直播推流、监控上墙、在线课堂这类场景里,低延迟和并发能力比很多商业方案更稳。适合谁?适合手里有一台Windows服务器,需要快速搭一个流媒体服务做推拉流验证或内网分发的开发者。
2. 部署前的三个确认:目录结构、配置读取顺序与日志格式
拿到压缩包先别急着双击MediaServer.exe。Windows下跑流媒体服务,翻车大多发生在路径不对、配置没加载、端口被占这三件事上。这一章把部署前需要确认的东西过一遍,后面启动的时候才不慌。
2.1 Release包里哪些文件是运行必需,哪些是开发附属
解压后的文件夹里文件不少,但真正跑服务只需要其中一小部分。我一般先按使用场景分成三类:运行文件、开发文件、辅助文件。下面这张表是我拆这个包时做的分类,照着分就不会拿错文件去部署。
| 文件 | 用途 | 运行是否需要 |
|---|---|---|
| MediaServer.exe | 主程序,流媒体服务本体 | 必需 |
| config.ini | 所有协议端口、鉴权、日志等配置 | 必需 |
| mk_api.dll、zltoolkit.dll、jsoncpp.dll等 | 运行依赖库,缺失会闪退 | 必需 |
| default.pem | HTTPS/SSL默认证书,不替换也能用 | 必需 |
| www目录 | Web后台静态资源和Hook页面 | 推荐保留 |
| swagger | API接口文档,调试时非常有用 | 可选 |
| zlmediakit.lib、mk_api.lib、ext-codec.lib等 | 二次开发用的静态库和导入库 | 仅开发需要 |
| log目录 | 运行时日志输出目录 | 自动生成 |
注意一个容易踩的坑:这些dll和exe必须是同一套编译产物。有人图省事,从别处复制一个更高版本的MediaServer.exe替换进来,结果exe和mk_api.dll版本对不上,启动时报错找不到入口点。这个包里exe和dll是同一天编译的,用的时候别单独替换其中任何一个。
2.2 config.ini里与推流链路直接相关的参数
ZLMediaKit启动时通过-c参数指定配置文件,不指定的话会在工作目录下找config.ini。这个文件决定了你走RTSP、RTMP还是HTTP-FLV时对应哪个端口,也决定了后面调REST API时用什么密钥。
我部署时通常会先检查下面这几段配置,字段名在不同版本里可能略有出入,但含义基本一致:
[general] ; 服务器时区,影响日志和HLS切片时间 timeZone=8 [api] ; REST API的鉴权密钥,调用管理接口时必须带上 secret=your_secret_here [rtmp] port=1935 ; 0为不启用,1为启用 enable=1 [rtsp] port=554 enable=1 [http] port=8080 ; 开启后HTTP-FLV和HLS走这个端口 enable=1关键参数就三个:rtmp的port决定推流地址里的冒号后数字,rtsp的port决定摄像头或播放器直连端口,http的port决定HTTP-FLV拉流地址。secret这一项要重点改,默认值如果被同网段的人猜到,别人就能直接调你的API关流、踢人。我一般会换成一串足够随机的字符串再启动。
还有个容易误读的地方:config.ini里有的版本会出现多个[api]区块或重复字段,这是历史兼容写法,后出现的覆盖先出现的。我遇到不确定的时候,会搜一下整个文件里同一个字段出现几次,避免改了半天改的是被覆盖的那个值。
2.3 启动MediaServer:用日志确认服务真的活着
启动方式我喜欢在命令行里手动执行一次,前台跑,这样可以马上看到日志刷出来,确认没有爆红再退出。实际做服务时再用守护方式或者注册成Windows服务。
cd C:\your_path\Release MediaServer.exe -c config.ini -d解释一下两个参数的含义。-c指定配置文件绝对路径或相对路径,不带时默认找当前目录下的config.ini;-d表示以守护进程方式运行,服务会在后台跑,不占用当前命令行窗口。第一次部署我建议不要加-d,改成直接运行MediaServer.exe,这样端口占用、配置报错都会直接在窗口里打印出来。
启动完成后,进入log目录找最新的日志文件,文件名类似2024-05-30_00.log这种日期加序号格式。我习惯先看三件事:
- 有没有打印出实际监听的端口列表,确认554、1935、8080都在。
- 有没有出现“bind failed”或“Address already in use”字样,说明端口被占。
- 有没有加载config.ini失败的提示,通常是因为路径不对或文件被改了编码。
如果日志里没有报错,再开另一个窗口用netstat确认端口在听,才算真正启动成功。我一般不会跳过这一步,因为有些版本即使端口绑定失败也会继续跑,看起来像活着,实际上拉流全失败。
3. 把流推上去再拉下来:HTTP-FLV与RTSP的实战组合
服务起来了,下面要做的就是真正推一路流进去,再拉出来验证链路通不通。这一章从推流端选型讲起,到拉流验证,再到用API管理流状态,是我每次部署必走的完整闭环。
3.1 推流端选型:为什么先用FFmpeg做链路验证
ZLMediaKit本身是流媒体服务器,不是采集端,所以推流需要外部的推流器。在Windows上我一般用FFmpeg做验证,因为它命令行简单、协议覆盖全,一套命令同时能推RTMP和RTSP,不需要装额外软件。
ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -f flv rtmp://127.0.0.1:1935/live/test这里几个参数值得说明。-re表示按文件的原始时间戳速率推送,模拟实时推流,不加的话FFmpeg会全速推完,服务器端反而看不到稳定码率;-stream_loop -1让输入文件无限循环,适合长时间测试;-c copy是关键,直接复制编码数据不做转码,避免Windows下CPU被占满;-f flv指定输出封装格式,rtmp://127.0.0.1:1935/live/test是目标地址,其中live是虚拟主机名,test是流ID,这两个共同组成流的标识。
如果你的源文件是带B帧的H.264,直接-c copy推流可能在某些播放器里出现卡顿。我遇到这种情况会把B帧去掉再推,但这个属于源视频参数问题,不是服务器故障。验证阶段只要能推上去,服务器日志能看到新流注册就说明链路通了。
3.2 拉流端:HTTP-FLV的低延迟优势与播放验证
推流成功后,服务器会生成多个协议入口。我优先用HTTP-FLV验证,原因是它在浏览器端兼容性最好,延迟通常在一秒以内,比HLS动辄三到五秒的切片延迟体验好很多。ZLMediaKit为同一条流生成地址有固定规律,我一般用下面这个组合去验证:
ffplay http://127.0.0.1:8080/live/test.live.flv这条命令在Windows命令行里直接弹出播放窗口。地址里的8080对应config.ini里[http]段的port,live是虚拟主机,test是推流时填的流ID,.live.flv是固定后缀,表示取HTTP-FLV格式。如果这个地址能播,说明HTTP-FLV链路没问题。
同时可以用VLC或者其他播放器验证RTSP链路:
ffplay rtsp://127.0.0.1:554/live/testRTSP地址比HTTP-FLV少一个端口参数,因为协议默认走554。我验证时会把两个地址都拉一遍,因为有些场景走的是RTSP接入、HTTP-FLV分发,两端都要确认。如果HTTP-FLV卡顿但RTSP正常,优先查服务器所在机器的网络带宽和防火墙,而不是急着调服务器参数。
3.3 用REST API接管流状态:关流、调参、看在线列表
ZLMediaKit的另一个优势是自带一套HTTP REST API,部署后不用登录服务器就能查看流列表、踢掉可疑的推流方、动态开流。这个功能在监控上墙类项目里特别实用,某个摄像头掉线或者画面异常,直接在管理端调用API处理。
curl "http://127.0.0.1:8080/index/api/getMediaList?secret=your_secret_here"这个接口返回当前所有在线流的JSON数组,包括流ID、协议类型、在线观看人数。secret参数对应config.ini里[api]段的secret值,没带或带错会返回401。拿到在线列表后,如果想关掉某一路流,常见做法是先调用getMediaList找到流的唯一标识,再调用close_streams接口按需关闭,避免一把梭把正在播放的用户全部闪断。
我部署的每个项目都会在代码里把这几个API包一层,因为后面做心跳检测、异常自动拉流重推都会依赖它们。刚开始用的时候容易漏掉token参数导致所有API请求都失败,这个和config.ini的secret没有同步是同一个问题,习惯是先确认secret值再调试API。
4. Windows部署常见问题排查:五个坑和对应的后悔药
这一章写的是我在Windows环境里实际踩过的坑。流媒体服务器不像普通Web服务,它同时占用多个端口、依赖多个dll、还要处理高并发下的网络栈行为,任何一个环节出问题都会体现为拉流失败或进程退出。每条按现象、原因、解决的顺序写,可以直接照查。
4.1 现象:MediaServer.exe启动后立刻闪退
双击exe或命令行启动后窗口一闪就消失,进程列表里找不到MediaServer。原因主要分三种:一是缺少运行依赖dll,常见的是把exe单独拷走而没带上同目录下的dll;二是config.ini路径不对,程序加载配置失败后直接终止;三是端口被系统其他服务占用导致bind失败,某些版本会放弃启动。
解决思路是按日志排查。前台运行时闪退前通常会打印一行错误,看不到的话去log目录翻最新日志,搜索“error”或“failed”。缺dll的话用进程监视或直接对比文件清单,把缺少的dll补回去。端口冲突则改config.ini里对应端口,或者用netstat -ano查占用端口的PID并换端口。我现在部署前会先建好独立目录、完整解压、手动执行一次确认日志正常,才做后续配置。
4.2 现象:本机拉流正常,局域网内其他机器拉不了流
服务器本机用ffplay拉http-flv没问题,换到同一局域网另一台电脑就转圈。这个问题大部分情况下不是ZLMediaKit的参数问题,而是Windows防火墙拦截了入站端口。服务器默认只放行常见的Web端口,像554这种RTSP端口或自定义的8080端口都不会自动放行。
解决方法是把ZLMediaKit用到的端口加进防火墙入站规则。以管理员身份执行:
netsh advfirewall firewall add rule name="ZLMediaKit-RTSP" dir=in action=allow protocol=TCP localport=554 netsh advfirewall firewall add rule name="ZLMediaKit-HTTP" dir=in action=allow protocol=TCP localport=8080 netsh advfirewall firewall add rule name="ZLMediaKit-RTMP" dir=in action=allow protocol=TCP localport=1935也可以直接用Windows防火墙图形界面新建入站规则,同时把exe路径加进去。我实际排查时发现,很多人为省事把服务器公网IP直接填进拉流地址,这在跨网段时没问题,但内网环境应先用IP,别用机器名,因为Windows的机器名解析在某些网络环境下会超时。
4.3 现象:推流成功但HTTP-FLV拉流返回404
用ffmpeg推RTMP到服务器返回正常,日志里也能看到流注册,但浏览器访问http-flv地址返回404或者flv文件不存在。原因通常是拉流地址里的虚拟主机、流ID或者端口和推流时不一致,尤其是配置文件里修改了http端口,但拉流地址还在用默认的80或8080。
排查路径是回到推流命令看地址结构。如果推的是rtmp://127.0.0.1:1935/live/test,那么HTTP-FLV地址应该完整保留live和test这两段,格式为http://服务器IP:你配置的http端口/live/test.live.flv。我见过有人把rtmp地址和http-flv地址混着写,少一个.live.flv后缀,服务器返回404就是必然的。对照推流日志确认虚拟主机名和流ID,再按固定格式拼地址就能解决。
4.4 现象:并发观看数上来后延迟越来越高
刚开始十几个观看者延迟正常,到几百路并发时延迟从几百毫秒漂到几秒甚至十几秒。这通常不是ZLMediaKit单点瓶颈,而是Windows系统本身对高并发网络优化的限制,加上播放器端缓冲设置过大,服务器发出的数据在链路上排队。
我先检查的是播放器端的缓冲参数,很多播放器默认缓冲5秒以上,这在低延迟直播场景里相当于人为加高延迟。可以先把播放器缓冲调到1到2秒再观察。服务器这边,我一般会确认config.ini里是否限制了最大TCP连接数或线程池,避免默认参数在Windows上偏保守。还有一个容易忽略的点:Windows系统对TCP连接的支持受注册表参数影响,不是改ZLMediaKit配置就能突破的。对小并发场景,当前默认配置完全够用,真到高并发还是建议把主服务部署到Linux环境用,Windows部署更适合内网中小规模分发。
4.5 现象:改完配置重启后不生效,又回到旧参数
config.ini改了端口和secret,重启服务后用netstat看端口没变,拉流行为也还是旧的。原因往往是工作目录不对。命令行在A目录启动MediaServer.exe,但程序的工作目录是B目录,系统在B目录里找到了另一份config.ini并加载了它,你改的那份根本没被读取。
解决方式很简单,启动前先cd到config.ini所在目录,或者启动时用-c指定绝对路径。我在这事上翻过车,后来养成的习惯是启动后第一时间看日志里打印的配置路径,确认加载的是哪一份文件。还有一个相关坑是Windows的快捷方式启动,右键快捷方式属性里的“起始位置”如果填错,也会出现同样的现象。
5. 拿来即用的小技巧:日志级别、证书更新与开机自启
这三个技巧是部署完以后才用得到的,属于日常工作里高频操作,每个都很轻量,但能省不少排查时间。
5.1 把日志级别调低:debug模式能救命的两个场景
正常运行时日志级别设为info足够,但遇到推流失败或拉流中断这种疑难问题,info级别提供的信息往往不够。我一般会临时用debug级别启动,排查完再切回来。
MediaServer.exe -c config.ini -l debug-l参数指定日志级别,debug会输出每个TCP连接的建立和断开、每个流的注册和注销细节。两个典型场景必须用debug:一是推流端显示成功但服务器没反应,debug日志会告诉你握手在哪一步断掉;二是HLS切片失败,debug能看到切片生成任务执行到哪一步报错。排查完记得改回info,debug日志在高并发下写盘很凶,长时间跑会拖累性能。
5.2 HTTPS证书过期:替换default.pem的正确姿势
包自带的default.pem是自签名证书,内网测试没问题,但有些页面或客户端会校验证书有效期,到期后出现HTTPS连不上但HTTP正常的情况。其实不用重新编译,自己生成一个新证书替换同名文件就行。
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes copy /b cert.pem + key.pem default.pem生成后把两个文件拼在一起覆盖原default.pem,重启MediaServer.exe。注意顺序是证书在前、私钥在后,顺序反了部分客户端会拒连。我每次更新完都会用浏览器访问一下https端口确认证书信息,避免服务起来了但握手失败。
5.3 做成Windows服务:计划任务保证掉线自动拉起
进程守护是流媒体服务器绕不开的问题,不然夜里服务器重启或者进程崩溃,第二天早上才发现流断了一整夜。不做服务注册的简单做法是用Windows计划任务,在任务计划程序里新建一个任务,触发器设置为系统启动时运行,操作设置为启动MediaServer.exe并带上-c参数,再把“如果任务失败,重新启动”设置成每隔1分钟尝试一次。
比手工建计划任务更省心的做法是把它注册成Windows服务,这样进程异常退出后由系统服务控制管理器自动拉起。注册服务的工具不唯一,我用过最顺手的方式是把exe交给服务包装工具托管,然后把服务启动类型设为自动。要注意的是,服务方式运行的工作目录和手动运行不一定相同,所以-c必须写成配置文件绝对路径,否则服务启动后加载的还是默认config.ini。注册完成后,用sc query确认服务状态是RUNNING,再重启一次服务器验证自动拉起是否生效。
这次部署之前,我每次改配置都会直接在服务器上手改,改完重启,直到有一次深夜排查到凌晨才发现加载的是另一份配置文件。从那以后我强制自己走完这套流程:改配置前先确认工作目录和配置路径,改完看日志核对实际监听端口,再做一次推拉流验证。这套习惯帮我省下的时间远超过花在流程上的那几分钟,希望帮到你。
本文还有配套的精品资源,点击获取