尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

ZLMediaKit流媒体服务器搭建实战:从推流到拉流全流程

发布时间:2026/9/25 14:17:54

资讯中心
01
ARTICLE

ZLMediaKit流媒体服务器搭建实战:从推流到拉流全流程

ZLMediaKit流媒体服务器搭建实战:从推流到拉流全流程
做流媒体这行绕不开 ZLMediaKit 这个名字。我之前在一家做视频监控平台的公司待过早期用的方案是 Nginx 配 RTMP 模块再加一堆自研进程流一多就各种内存暴涨、断流重连后来排查问题查到凌晨两点是常有的事。换到 ZLMediaKit 之后第一感觉就是“这个项目是真的懂流媒体的人写的”。今天这篇东西我不打算给你念文档就按我实际走过的路从零开始把 ZLMediaKit 流媒体服务器搭起来再用 FFmpeg 推一路本地视频用 VLC 和浏览器分别拉流验证把这套完整闭环跑通。读完你应该能直接在自己电脑上动手复现Windows 和 Linux 都能用重点讲 Windows 下的快速上手版本。先说明一下这个项目完全开源C 写的核心就是一个高性能的流媒体服务器支持 RTSP、RTMP、HLS、HTTP-FLV、WebRTC 等主流协议还带一套完整的 HTTP API 和 Web Hook 机制。你不需要懂 C 也能把它跑起来只要会改配置文件、会推流命令就行。适合的场景包括直播中转、监控摄像头接入、本地视频点播测试、内部培训系统、甚至一些小型的在线课堂。如果你是刚接触流媒体的小白或者公司准备自建一套流媒体服务但不知道怎么选型这篇文章能帮你少走不少弯路。1. 为什么选 ZLMediaKit一个视频老兵的真实理由1.1 它真正解决了流媒体服务器的什么问题先聊点背景。传统方案里Nginx-RTMP 模块算是最常见的配置简单是它的优点但问题也很明显协议支持单一HLS 切片和回源逻辑基本要自己写并发上来以后事件模型不够好用而且没有现成的 API 管理流状态。你要是只做一两个测试流随便哪个方案都能扛住一旦要接几十上百路摄像头或者要同时给 Web 端和手机端输出不同协议的流服务器的设计和综合能力差距一下就出来了。ZLMediaKit 给我的核心感受是它是一个“流媒体网关”不只是“推流转发行”。它可以同时接收 RTSP/RTMP 推流然后自动转换成多种协议输出。比如说摄像头用 RTSP 推上来客户端可以用 RTMP 拉、可以用 HLS 拉、可以用 HTTP-FLV 拉、也可以用 WebRTC 拉整个过程不需要你提前规划好“这条流要转成哪几种格式”。它把所有协议统一成内部的一种流模型哪个协议有请求它就按需转出来。这种设计比传统方案“一个协议一对端口、一个端口一套配置”的模式清爽得多。另外它自带一套完善的 REST API可以查询流列表、踢掉某条流、动态开启转封装甚至可以在配置里打开 Web Hook在自己业务系统里监听“流上线/流断开”事件。我后来做设备接入平台就是靠这套接口接的日志和告警系统省去了大量轮询代码。如果你需要做一个带管理后台的流媒体平台选它而不是从零写转发逻辑开发成本会降一个量级。还有一点容易被忽略它支持多路流复用和按需转协议意味着没人看的流可以不被转封装省 CPU。这个“懒加载”思路在生产环境里很重要。我见过一些方案不管有没有人拉流都把一个流转成四五种格式挂着纯属浪费资源。ZLMediaKit 默认是拉流端来了请求才去转对应协议流空闲了自动回收整体消耗非常低。1.2 适合谁用、能用在哪一步从我接触过的使用者来看大概分这样几类第一类是做监控平台的人。摄像头一般走 RTSP/GB28181ZLMediaKit 官方其实有一个配套的 GB28181 实现可以把国标设备接进来然后再转成 Web 端能直接播放的 HTTP-FLV 或 WebRTC。第二类是搞直播或在线教育的技术人员需要接收主播推流并输出给观众同时要做录制和截图。第三类是自己折腾的家庭用户比如装了一套 NVR想把监控画面接到自己的 Home Assistant 或者网页上用它中转一下非常方便。第四类是做流媒体技术验证的同学不想用商业厂商的 SDK想研究协议转发和封装的底层逻辑。这几个方向我用下来都能覆盖。尤其是“Web 端免插件播放”这一点HTTP-FLV 配合 flv.js 在 PC 浏览器里延迟能做到一两秒移动端虽然 iOS 对 HTTP-FLV 支持有限但可以直接用 HLS 或者 WebRTC。反正协议是现成的你只需要在业务里做一次能力检测选择走哪条拉流通道就行。2. 环境准备从拿到安装包到能跑起来2.1 Windows 版本怎么拿别再用旧的编译包先说下载。ZLMediaKit 的官方源码托管在 GitHub 上项目发布页里会提供已经编译好的 Release 包。搜索“ZLMediaKit 最新版本下载”的时候你会发现很多老文章给的链接都已经过时了下载下来的还是两三年前的版本缺少新协议特性甚至有些已知 bug 都没修。我的建议是除非你要做二次开发否则直接用官方 Releases 里的现成包。以 Windows 为例发布包里通常包含一个类似Windows前缀的压缩包里面默认带好了可执行文件、依赖 DLL、默认 web 页面和配置文件。这里要说清楚Windows 上的“最新版本”不一定是以安装包形式出现的很多时候是一个.7z或者.zip压缩包解压之后直接运行即可不需要安装向导。下载之后放在一个单独的目录比如D:\ZLMediaKit路径里尽量不要有中文和空格避免后续一些工具在拼接路径时出问题。我见过有人放在C:\Program Files (x86)下面结果某些脚本和 FFmpeg 命令处理起来非常难受。同样如果你在文件资源管理器里看解压后的内容应该能看到bin、www、conf这样的目录如果没有说明下载的东西不对。2.2 目录结构和初始配置解压后你会看到大概这样一个结构ZLMediaKit/ ├─ bin/ # 可执行文件 │ ├─ MediaServer.exe │ └─ MediaServer ├─ www/ # 默认 HTTP 页面和静态资源 ├─ conf/ # 配置文件目录 │ └─ config.iniWindows 下重点是MediaServer.exe这个文件它是整个服务的入口ZLM 约定俗成的叫法就是 MediaServer。www目录用来放 HTTP 静态文件它自带的调试页面就在里面后面你会用http://127.0.0.1/index.html访问到那个页面。配置文件只认config.ini所有的端口、鉴权、日志级别、录制开关都在这一个文件里。这里插一句新手容易犯的错很多人以为配置文件是要生成或者编译出来的其实不是。Release 包已经带了一份能直接跑的默认配置你只需要按需改几个参数。真正重要的事情是做完任何修改后要重启 MediaServer 让配置生效很多“我改了怎么没用”的问题都是因为没重启Windows 下如果你用控制台窗口跑的直接 CtrlC 杀掉再重新启动就行。2.3 启动前的参数调整先用文本编辑器打开config.ini你不需要全部看懂这里只挑几个第一次启动前需要关注的[http] port80 sslport443 [rtsp] port554 [rtmp] port1935 [rtp_proxy] port10000 [api] apiDebug1 secret035c73f7-bb6b-4889-a715-d9eb2d1925cchttp.port是 HTTP 服务端口rtsp.port是 RTSP 端口rtmp.port是 RTMP 端口这几个端口如果你本机已经被占用可以改成 8080、10554、19350 之类的非常规端口但后面访问的地址也要跟着变。api.secret是调用 HTTP API 的密钥默认就有一串生产环境一定要改掉不然别人可以通过 API 把你的流踢了或者获取你的服务器信息。另外一个常见问题是端口权限在 Linux 上低于 1024 的端口需要 root 权限Windows 上相对宽松但如果你用的是非管理员权限跑可能还是会被占用问题拦一下。我习惯先把端口改成相对大一点的数字测试比如 HTTP 用 8080RTSP 用 10554等彻底跑通之后再改回标准的 80、554。3. 启动服务与验证连通性3.1 启动流程与控制台输出启动方法很简单进入bin目录双击或者在 cmd 里运行MediaServer.exe。如果你用的是 Linux就在同目录下执行./MediaServer -c ../conf/config.ini -l 0不过这篇文章以 Windows 为主命令行的差异后面会标注。正常启动后控制台会打印出一些关键日志包括“已加载配置”“监听端口”等信息。如果你用的是默认配置运行成功之后可以去浏览器访问http://127.0.0.1/index.html如果看到页面能正常打开说明 HTTP 服务和静态资源都没问题。这个页面是 ZLMediaKit 自带的调试页里面可以测试拉流、查看服务器版本甚至可以直接看到当前服务器上有哪些流。不过我要提醒一句双击 exe 跑出来的窗口一旦关闭窗口服务就停了。如果你想长期放在后台Windows 下可以用nssm把它注册成 Windows 服务这样开机自启、崩溃自动拉起都方便。或者你只是测试开一个 cmd 窗口放着就行。启动输出里还有一行很关键它会打印“http api 服务已经启动访问 http://127.0.0.1/index/api/getServerConfig 可以查看服务器配置”这行地址可以直接用来做健康检查。3.2 用 API 和页面确认服务正常验证服务是不是真的健康不要只看进程在不在要调一下它的 HTTP API。ZLMediaKit 提供了一套 JSON 接口最基础的两个GET /index/api/getServerConfig获取服务器配置GET /index/api/getMediaList获取当前流列表测试阶段这个接口会非常有用直接在浏览器访问http://127.0.0.1/index/api/getServerConfig?secret你的secret能返回一段 JSON 就说明核心服务正常、鉴权也通了。注意我刚才提到的secret如果你没改就用 config.ini 里默认的那串如果你改了所有 API 调用都要带上新的 secret 参数。我为什么强调这个步骤因为我见过太多人“服务能跑、页面能开”结果推流一上来就挂最后发现是 API 那条链路有问题。用 API 做一次摸底等于先确认了服务器的基础能力后面推拉流出问题排查范围能缩小很多。4. 跑通第一条流推流与拉流的完整闭环这是整篇最重要的一节。目标很简单让一段视频从“源端”进入 ZLMediaKit然后你从“播放端”把它拉出来。这个闭环你完整跑一遍就掌握了流媒体服务器最核心的工作原理。4.1 准备测试用视频源不需要真摄像头你只需要一个本地视频文件就行。找一段 mp4时长随意几秒钟的短视频也够但注意最好包含音频轨这样能顺便验证一下音视频同步。如果你手头没有现成视频可以用 FFmpeg 自己生成一个彩色渐变测试视频。FFmpeg 本身是流媒体调试的必修工具建议装一个后面推流全靠它。临时生成一条测试视频的命令ffmpeg -f lavfi -i testsrcsize1280x720:rate30 -t 10 -pix_fmt yuv420p test.mp4这条命令会生成一个 10 秒的 720p 测试视频明显能看到动态画面。生成的test.mp4就放在当前目录。还有一个小技巧如果你的源视频是远程 URL 或者摄像头 RTSP 地址也可以直接拿来做推流源。比如ffmpeg -re -i rtsp://你的摄像头地址 -c copy -f flv rtmp://127.0.0.1/live/cam这就是把摄像头变成一路直播流ZLM 收到之后你就能在任意端播放。本地文件推流和摄像头推流原理完全一致。4.2 用 RTMP 推流打开一个命令行窗口执行ffmpeg -re -i test.mp4 -c copy -f flv rtmp://127.0.0.1/live/test这条命令干了什么事情我拆开讲-re表示按视频本身的帧率匀速读取文件这样推流速度是“实时”的而不是瞬间推完。-i test.mp4指定输入文件。-c copy表示不重新编码音视频编码数据直接拷贝进 FLV 容器。因为是本地文件编码格式通常已经是 H.264/AAC直接拷贝性能极高CPU 占用几乎为零。-f flv指定输出格式为 FLVRTMP 使用的就是 FLV 封装。rtmp://127.0.0.1/live/test是推流地址其中127.0.0.1是 ZLM 所在地址live是应用名test是流 ID。注意如果你改了 RTMP 端口这里也要改成对应端口比如rtmp://127.0.0.1:19350/live/test。执行之后FFmpeg 会持续输出进度信息能看到总时长在走、速度保持在1x这就说明正在推流中。如果报错大概率是端口、防火墙或者路径问题后面排查部分我专门说。此时你可以去浏览器打开刚才的 APIhttp://127.0.0.1/index/api/getMediaList?secret你的secret正常情况下JSON 里会多出一条 media 记录里面的app为livestream为testoriginType可能是rtmp_push。看到这条数据说明 ZLM 已经成功接收并管理这路流了。4.3 用多种方式拉流验证流已经推上去了接下来验证能不能拉出来。推荐至少用下面三种方式各试一次因为每一种验证的是不同链路。第一种是 VLC 拉 RTMP。打开 VLC按 CtrlN输入rtmp://127.0.0.1/live/test回车之后如果画面出来说明 RTMP 拉流完整链路没有问题。这里要是播不出来先别急着怀疑 VLC去看一下 FFmpeg 那边有没有断流报错同时确认推流地址和拉流地址的端口一致。第二种是浏览器拉 HTTP-FLV。ZLMediaKit 的 HTTP-FLV 地址格式是http://127.0.0.1/live/test.flv你直接把这条地址放到浏览器里如果服务正常浏览器会尝试下载或者播放一个 FLV 文件但现代浏览器默认不一定支持直接播放 FLV。建议用 flv.js 的 demo 页面或者在 HTML 里引入 flv.js 播放script srchttps://cdn.jsdelivr.net/npm/flv.js/dist/flv.min.js/script video idvideo/video script if (flvjs.isSupported()) { var video document.getElementById(video); var flvPlayer flvjs.createPlayer({ type: flv, url: http://127.0.0.1/live/test.flv }); flvPlayer.attachMediaElement(video); flvPlayer.load(); flvPlayer.play(); } /script把url改成你的实际地址浏览器打开这个 HTML如果能看到画面说明 HTTP-FLV 链路也是通的。这个方案在 PC 端的延迟很低通常在一秒以内非常适合做监控调阅或直播观看。第三种是 HLS。HLS 地址格式一般是http://127.0.0.1/live/test/hls.m3u8在 VLC 或者支持 HLS 的浏览器里打开这个地址如果能看到画面说明切片转封装链路也没问题。HLS 的缺点是有几秒到十几秒的延迟但它兼容性最好iOS Safari 原生就能播放适合做移动端兼容兜底。如果你改了 HTTP 端口上面的127.0.0.1后面都要加端口比如http://127.0.0.1:8080/live/test.flv。5. 常见问题排查与运维心得5.1 端口占用与防火墙开起来不等于能访问我帮人排查时发现第一步卡住的大概率是端口。ZLM 默认用的 80、554、1935 都是常用端口你本机很容易已经被其他软件占用。最简单的判断方法是执行netstat -ano | findstr :80如果看到端口已经被 LISTENING说明有程序占用。改 config.ini 里的端口重启再推流这是第一优先级操作。第二优先级是防火墙。Windows 上如果 FFmpeg 推流时提示连接失败但本机能访问 ZLM 的 API那就很可能是 Windows 防火墙拦截了入站的 RTMP 连接。测试阶段最简单粗暴的方式是临时关闭防火墙验证但我不建议长期这样。更稳妥的做法是在防火墙高级设置里放行对应端口或者放行MediaServer.exe这个程序。RTMP 端口、RTSP 端口、HTTP 端口都放行。5.2 推流失败与播放失败的排查顺序先给一个排查原则从源端往播放端一层一层往后排除不要上来就改服务器配置。推流失败时按这个顺序查FFmpeg 命令本身有没有报错执行之后有没有立刻退出退出码是多少推流地址的 IP、端口是不是 ZLM 实际监听的地址如果你改了端口但命令里还是 1935肯定不通。抓一下服务器日志。ZLMediaKit 日志会打印收到的连接请求如果你看到accept了但没有后续数据说明连接是通的问题可能出在流内容本身。检查防火墙。播放失败时多了两种可能流确实已经断开了或者播放端不支持该协议。比如 iOS 的 Safari 不太支持直接播放 HTTP-FLV你就不能拿它来验证 FLV这不是服务器问题。另外要确认拉流地址里live/test这两段和推流时所用的app/stream完全一致大小写都要一致不能推流时是Live/test拉流时却写live/test。有个特别容易犯的错如果你用ffmpeg -re -i test.mp4 -c copy -f flv rtmp://127.0.0.1/live/test推流推的是 H.264AAC播放端基本通吃但如果你推的是一个编码格式特殊的视频比如 HEVC某些播放器可能不支持。测试阶段最好用标准的 H.264 视频避免把视频编码和服务器协议混在一起排查。5.3 配置改动后不生效和重启坑ZLM 的 config.ini 改动之后一定要重启进程这是最简单的道理但恰恰是最高频的失误。另外要注意config.ini里的分类层级是用[]包含的比如[http]下面的port才代表 HTTP 端口你如果把 RTMP 的端口写到了[http]下面服务启动可能直接报错或者出现很诡异的启动后端口对不上的情况。还有一个小坑是路径相关。ZLM 启动时会根据当前工作目录去找www和conf。我用 cmd 运行时习惯先cd /d D:\ZLMediaKit\bin再执行MediaServer.exe这样日志和配置路径都相对可控。如果你从别的目录直接启动会出现“找不到配置文件”或者“页面样式加载不出来”的问题因为相对路径对不上了。5.4 我踩过的坑和给新手的建议最后分享几个我实际踩过的坑也许能帮你节省大量时间。第一个坑默认 RTMP 端口被某个国产软件占用导致推流一直失败但用netstat看的时候又因为权限不够看不到占用进程折腾了半天才发现是软件自带的某个服务占用了 1935。所以遇到端口问题建议先用管理员权限跑 netstat再把端口号改成一个冷门端口测试。第二个坑用 HTTP-FLV 播放时页面能打开但一直转圈后来发现是服务器的 HTTP 端口的sslport配错了导致 HTTPS 请求被拦截。如果你不需要 HTTPS直接把sslport留默认或者关掉监听别让两个端口互相干扰。第三个坑自己写 Web 页面拉流时流地址用的是内网 IP但页面通过外网域名访问跨域和网络路径导致播放失败。解决方案是确保页面和流地址在同一个网络可达域下或者把流地址也反代成同域路径加Access-Control-Allow-Origin头。Windows 下也可以直接在 Nginx 里反代 ZLM 的 HTTP 端口。还有一个建议如果你打算长期使用一定要把secret改掉并且开启apiDebug0避免生产环境把调试信息暴露出去。日志级别也不要一直开到最高否则磁盘会被刷满。日志文件定位到某个固定目录方便出问题的时候翻日志而不是在控制台里凭记忆找原因。我个人在使用中的体会是ZLMediaKit 是一个“搭起来容易、调优也不难”的服务器你不需要懂内部的 C 细节只需要理解推流、拉流、协议转换这条主线然后带着排查思路去碰问题。等这一条流彻底跑通之后你会自然产生更多的想法比如接入真实摄像头、把 HTTP-FLV 嵌入到自己的管理系统、加上鉴权和录制功能甚至把它对接给 WebRTC 网关。这些扩展方向ZLM 都已经帮你铺好了路。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。