CentOS 7.9 编译部署 ZLMediaKit 流媒体服务器全攻略
2026/8/6 16:49:03 网站建设 项目流程

1. 项目缘起与目标定位

最近在折腾一个需要处理实时音视频流的内部项目,选型时把目光投向了 ZLMediaKit。这玩意儿在开源流媒体服务器圈子里名气不小,主打高性能和低延迟,支持 RTSP、RTMP、HLS、HTTP-FLV 等多种协议,对于需要自建流媒体服务或者做二次开发的场景来说,是个相当不错的起点。不过,官方文档虽然详尽,但更多是面向已经搭好环境的“下一步”操作。真正从零开始,在一台干净的 CentOS 7.9 机器上把它编译出来并跑通基础测试,这个过程里藏着不少需要自己趟过去的“坑”。这篇文章,就是记录我这次从编译环境准备到功能验证的完整实操过程,目标很明确:给你一份能在 CentOS 7.9 上复现的、带避坑指南的“保姆级”操作手册。

为什么是 CentOS 7.9?虽然它已经停止维护,但在很多企业内网、存量服务器上依然有广泛部署,稳定性经过长期考验。在这个环境下成功编译和测试 ZLMediaKit,意味着你能在大量现有服务器资源上快速部署一套可用的流媒体服务,无需为升级系统大动干戈。整个过程涉及从系统依赖、编译工具链的配置,到源码获取、编译参数调整,最后到服务启动和基础功能测试。我会把每一步的操作意图、可能遇到的问题以及我的解决方案都掰开揉碎了讲清楚,特别是那些官方文档可能一笔带过,但实际操作中却会卡住你的细节。

2. CentOS 7.9 基础环境准备与依赖库安装

编译 ZLMediaKit 的第一步,不是急着去git clone代码,而是确保你的 CentOS 7.9 系统已经具备了所有必要的编译环境和依赖库。一台刚装好的最小化安装(Minimal Install)的 CentOS 7.9,很多东西都是缺的。

2.1 系统更新与基础开发工具链

首先,确保系统是最新状态,并安装最核心的开发工具包。这能避免因为gccg++make等工具版本过低或缺失导致的编译错误。

# 更新系统已有的软件包到最新版本 sudo yum update -y # 安装 EPEL 扩展仓库,很多后续的依赖包需要从这里获取 sudo yum install -y epel-release # 安装开发工具组,这包含了 gcc, g++, make, autoconf 等一整套编译工具 sudo yum groupinstall -y "Development Tools" # 安装一些必要的工具和库 sudo yum install -y wget git cmake3 pkgconfig

这里有个细节:CentOS 7 默认的cmake版本是 2.8,对于 ZLMediaKit 来说太老了。所以我们安装cmake3。但后续调用时,命令是cmake3而不是cmake,这点需要注意,或者在系统里做个软链接ln -s /usr/bin/cmake3 /usr/local/bin/cmake来统一命令。

2.2 安装 ZLMediaKit 的核心依赖库

ZLMediaKit 的编译依赖几个关键的第三方库,主要是 OpenSSL、libsrtp 和 ffmpeg。我们必须手动编译安装它们,以确保版本的兼容性和功能的完整性。Yum 仓库里的版本往往不是太老就是功能不全。

安装 OpenSSL 1.1.1:ZLMediaKit 强烈推荐使用 OpenSSL 1.1.1 及以上版本,以支持更安全的加密协议(如 DTLS)。CentOS 7.9 默认的 OpenSSL 是 1.0.2,我们需要手动升级。

# 安装编译 OpenSSL 所需的依赖 sudo yum install -y perl-IPC-Cmd # 下载 OpenSSL 1.1.1 源码 (以 1.1.1w 为例,请检查官网获取最新稳定版) wget https://www.openssl.org/source/openssl-1.1.1w.tar.gz tar -zxvf openssl-1.1.1w.tar.gz cd openssl-1.1.1w # 配置、编译并安装到 /usr/local/openssl 目录,避免覆盖系统自带的 OpenSSL ./config --prefix=/usr/local/openssl --openssldir=/usr/local/openssl shared zlib make -j$(nproc) # 使用多核编译加速 sudo make install # 将新安装的 OpenSSL 库路径添加到系统库搜索路径 echo '/usr/local/openssl/lib' | sudo tee /etc/ld.so.conf.d/openssl-1.1.1.conf sudo ldconfig # 验证新安装的 OpenSSL 版本 /usr/local/openssl/bin/openssl version

这一步完成后,你应该看到输出OpenSSL 1.1.1w ...--prefix参数指定了安装目录,将其与系统默认路径隔离是更安全稳妥的做法,防止影响其他系统服务。

安装 libsrtp:SRTP(安全实时传输协议)用于对 RTP 流进行加密。ZLMediaKit 的 WebRTC 等功能需要它。

# 下载 libsrtp 源码 git clone https://github.com/cisco/libsrtp.git cd libsrtp git checkout v2.5.0 # 选择一个稳定的版本,如 2.5.0 # 配置并编译安装 ./configure --prefix=/usr/local --enable-openssl make -j$(nproc) sudo make install sudo ldconfig

--enable-openssl参数很重要,它让 libsrtp 使用我们刚刚安装的 OpenSSL 1.1.1 进行加密操作。

安装 FFmpeg:ZLMediaKit 的转码、滤镜等功能依赖于 FFmpeg。我们需要编译一个包含常用编码器(如 H.264)的版本。

# 安装 FFmpeg 编译依赖 sudo yum install -y yasm nasm libass-devel freetype-devel # 下载 FFmpeg 源码 (以 n6.0 为例) wget https://ffmpeg.org/releases/ffmpeg-6.0.tar.xz tar -xJf ffmpeg-6.0.tar.xz cd ffmpeg-6.0 # 配置编译选项。这里启用了一些常用编码器和协议支持。 ./configure --prefix=/usr/local/ffmpeg \ --enable-gpl \ --enable-nonfree \ --enable-libx264 \ --enable-libx265 \ --enable-libvpx \ --enable-libmp3lame \ --enable-libfdk-aac \ --enable-openssl \ --extra-cflags="-I/usr/local/openssl/include" \ --extra-ldflags="-L/usr/local/openssl/lib" make -j$(nproc) sudo make install sudo ldconfig # 验证安装 /usr/local/ffmpeg/bin/ffmpeg -version

注意:--enable-libx264等选项需要你先安装对应的开发库(如x264-devel)。如果遇到报错,可以先sudo yum install -y x264-devel等。为了简化流程,上述配置命令是目标状态,实际可能需要分步安装更多-devel包。一个更省事的办法是使用预编译的 FFmpeg,但自编译能更好地控制功能和路径。

2.3 解决潜在的依赖冲突与路径问题

在安装完上述核心依赖后,可能会遇到一些路径冲突。最常见的是系统自带的旧 OpenSSL 与我们新安装的版本冲突。我们需要确保编译 ZLMediaKit 时,cmake能找到正确的库。

可以设置环境变量来明确指定路径:

export OPENSSL_ROOT_DIR=/usr/local/openssl export FFMPEG_ROOT=/usr/local/ffmpeg

你可以将这些行添加到~/.bashrc文件中,然后执行source ~/.bashrc使其永久生效。这样,在后续的编译步骤中,CMake 就会优先在这些路径下查找依赖库。

3. ZLMediaKit 源码获取与编译配置

环境准备妥当后,我们就可以开始处理 ZLMediaKit 本体了。

3.1 克隆源码与初始化子模块

# 克隆 ZLMediaKit 的主仓库 git clone --depth 1 https://github.com/ZLMediaKit/ZLMediaKit.git cd ZLMediaKit # 非常重要!初始化并更新子模块,很多核心代码(如 mediakit)在子模块里 git submodule update --init --recursive

--depth 1只克隆最近一次提交,速度更快。但切记,git submodule update --init --recursive这一步绝对不能省略。我见过不止一个人因为漏了这一步,编译时疯狂报“找不到头文件”的错误,折腾半天才发现是子模块没拉下来。

3.2 使用 CMake 生成构建系统

进入源码目录,我们创建一个独立的构建目录,这是一种良好的“源代码外构建”实践,保持源码树的干净。

# 在 ZLMediaKit 源码根目录下 mkdir build cd build

接下来是关键的 CMake 配置步骤。我们需要通过参数告诉 CMake 我们自定义的依赖库路径。

# 使用 cmake3 进行配置 cmake3 .. \ -DCMAKE_BUILD_TYPE=Release \ -DOPENSSL_ROOT_DIR=/usr/local/openssl \ -DOPENSSL_LIBRARIES=/usr/local/openssl/lib \ -DENABLE_WEBRTC=ON \ -DENABLE_SRT=OFF \ # 根据需求开启,SRT需要额外依赖 -DENABLE_RTPPROXY=ON \ -DENABLE_API=ON \ -DENABLE_FFMPEG=ON \ -DFFMPEG_ROOT=/usr/local/ffmpeg

参数解析:

  • -DCMAKE_BUILD_TYPE=Release:生成 Release(发布)版本,编译器会进行优化,去掉调试信息,性能更好,体积更小。如果是调试,可以用Debug
  • -DOPENSSL_ROOT_DIR-DOPENSSL_LIBRARIES:明确指向我们手动安装的 OpenSSL 1.1.1。这是避免链接到系统旧版 OpenSSL 的关键。
  • -DENABLE_WEBRTC=ON:开启 WebRTC 支持。如果你需要浏览器无插件播放,这个必须开。
  • -DENABLE_FFMPEG=ON-DFFMPEG_ROOT:开启 FFmpeg 支持并指定路径,用于转码等功能。
  • 其他如ENABLE_SRT,ENABLE_RTPPROXY,ENABLE_API等,可以根据你的实际需求开关。初次测试建议保持默认或全部开启,以验证完整功能。

执行完cmake3命令后,仔细查看终端输出。理想情况下,最后几行应该会显示Configuring doneGenerating done,并且没有红色的错误(ERROR)信息。可能会有一些黄色的警告(WARNING),通常是关于找不到某些可选依赖(如libsdptransform),只要不是核心依赖,一般不影响编译。

3.3 编译源码并处理常见错误

配置成功后,就可以开始编译了。

# 使用多核并行编译,大幅缩短时间。$(nproc) 会自动获取你CPU的核心数。 make -j$(nproc)

这个过程视机器性能,可能需要几分钟到十几分钟。如果一切顺利,你会在build目录下看到生成的可执行文件,最主要的是MediaServer

编译过程中可能遇到的坑及解决方案:

  1. 错误:找不到 OpenSSL 的EVP_*SSL_*相关函数

    • 现象:链接阶段报错,提示undefined reference toEVP_...``。
    • 原因:CMake 仍然链接到了系统旧的 OpenSSL 库。
    • 解决:首先确认cmake3命令中OPENSSL_ROOT_DIR参数是否正确。然后,可以手动检查 CMake 缓存文件CMakeCache.txt,搜索OPENSSL_开头的变量,看其值是否指向/usr/local/openssl。如果不正确,最彻底的方法是删除整个build目录,重新执行cmake3配置命令。
  2. 错误:找不到libsrtp2

    • 现象CMake Error at CMakeLists.txt:xxx (find_package): Could not find a package configuration file provided by "libsrtp2"...
    • 原因libsrtp默认安装可能没有提供 CMake 所需的配置文件。
    • 解决:ZLMediaKit 的 CMake 脚本其实自带了libsrtp的查找逻辑。通常只要libsrtp安装到了/usr/local下,并且执行了sudo ldconfig,CMake 就能通过find_library找到它。如果还是找不到,可以尝试在cmake3命令中显式指定:-DLIBSRTP2_ROOT=/usr/local
  3. 错误:FFmpeg 相关函数未定义

    • 现象:链接时报告av_...等函数未定义。
    • 原因:FFmpeg 路径未正确识别或版本不兼容。
    • 解决:确保-DFFMPEG_ROOT参数正确指向了你安装 FFmpeg 的目录(例如/usr/local/ffmpeg)。同时,检查该目录下的libinclude子目录是否存在且包含文件。

如果编译成功,最后你会看到类似[100%] Built target MediaServer的输出。此时,在build/release/linux/Debugbuild/release/linux/Release目录下(取决于你的CMAKE_BUILD_TYPE),就能找到MediaServer这个核心可执行文件了。

4. 服务启动、基础功能测试与验证

编译产出不是终点,能跑起来、能用才是。接下来我们启动服务并进行最基本的推流、拉流测试。

4.1 启动 MediaServer 服务

首先,将编译好的MediaServer复制到一个方便的位置,并准备其配置文件。

# 假设我们在 build 目录下 cd release/linux/Release/ # 或 Debug,根据你的编译类型 cp MediaServer /usr/local/bin/ # 复制到系统路径,方便全局调用 cp -r conf /etc/zlmediakit/ # 复制配置文件目录 # 切换到配置文件目录,并启动服务(默认前台运行,方便看日志) cd /etc/zlmediakit/ MediaServer -c conf/config.ini -s conf/default.pem
  • -c指定主配置文件路径。
  • -s指定 SSL/TLS 证书路径(用于 HTTPS、WSS 等)。default.pem是自签名证书,仅用于测试。

如果启动成功,你应该能在终端看到大量的日志输出,最后会有类似MediaServer started!的信息,并且服务不会退出。这表明 ZLMediaKit 的服务进程已经正常运行,在监听配置文件(默认是config.ini)中指定的端口,例如 80(HTTP)、443(HTTPS)、554(RTSP)、1935(RTMP)等。

4.2 使用 FFmpeg 进行推流与拉流测试

我们以最常用的 RTMP 协议为例,进行一个完整的推流->服务转发->拉流测试链。

第一步:使用 FFmpeg 模拟一个视频源并向 ZLMediaKit 推送 RTMP 流。

打开一个新的终端窗口,执行以下命令:

# 使用 FFmpeg 生成一个测试图案(color=红色),并以 H.264 编码,通过 RTMP 推送到本地的 ZLMediaKit 服务器 /usr/local/ffmpeg/bin/ffmpeg -re -f lavfi -i testsrc=size=640x480:rate=30 -vcodec libx264 -preset ultrafast -tune zerolatency -f flv rtmp://127.0.0.1/live/teststream

命令拆解:

  • -re:以原始帧率读取输入,模拟实时流。
  • -f lavfi -i testsrc...:使用lavfi(Libavfilter)虚拟设备生成一个 640x480、30fps 的测试彩条图案。
  • -vcodec libx264:使用 H.264 编码。
  • -preset ultrafast -tune zerolatency:为了极低延迟的测试,选用最快的编码预设和零延迟调优。
  • -f flv:输出格式为 FLV,这是 RTMP 常用的封装格式。
  • rtmp://127.0.0.1/live/teststream:推流地址。127.0.0.1是本地 IP,live是应用名(App),teststream是流名(Stream)。

如果推流成功,这个终端会持续输出编码和发送的帧信息。同时,在运行MediaServer的终端里,你应该能看到类似[RTMP推流器] 推流成功的日志。

第二步:使用 FFplay(FFmpeg 套件中的播放器)从 ZLMediaKit 拉取 RTMP 流进行播放。

再打开一个新的终端窗口,执行:

# 从 RTMP 地址拉流并播放 /usr/local/ffmpeg/bin/ffplay rtmp://127.0.0.1/live/teststream

如果一切正常,会弹出一个播放窗口,显示动态的彩条图案。这就完成了一个最基本的“推流-服务器转发-拉流”的闭环测试,证明了 ZLMediaKit 的 RTMP 模块工作正常。

第三步:测试 HTTP-FLV 和 HLS 拉流。

ZLMediaKit 的强大之处在于协议互转。我们推了 RTMP 流,它自动生成了其他协议的拉流地址。你可以通过以下方式测试:

  • HTTP-FLV(低延迟):在浏览器(需支持 Flash,或使用 VLC 等播放器)中打开http://你的服务器IP:80/live/teststream.flv。更现代的方式是使用flv.js等前端库,在无插件的网页中播放。你可以用ffplay测试:ffplay http://127.0.0.1/live/teststream.flv
  • HLS(自适应码率,兼容性好):HLS 是切片传输,会有一定延迟。拉流地址是http://你的服务器IP:80/live/teststream/hls.m3u8。你可以用ffplay或支持 HLS 的播放器(如 VLC)打开这个.m3u8文件地址。

MediaServer的日志中,当你访问这些地址时,会看到对应的协议访问日志。

4.3 通过管理接口与 Web 界面查看状态

ZLMediaKit 提供了一个 HTTP API 接口和一个简单的 Web 管理界面,方便查看服务器状态和流信息。

确保配置文件中[api]段是启用的(默认是enable=1),并且secret有设置(默认是035c73f7-bb6b-4889-a715-d9eb2d1925cc生产环境一定要改!)。

  • 获取服务器配置和版本信息

    curl http://127.0.0.1:80/index/api/getServerConfig?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc
  • 获取当前所有的流列表

    curl http://127.0.0.1:80/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc

    如果之前推流成功,这个接口会返回teststream的相关信息。

  • 访问 Web 管理界面:在浏览器中打开http://你的服务器IP:80/,你会看到一个简单的页面,上面有服务器状态、API 文档链接以及一个内置的播放器测试页面。你可以在这个测试页面输入live/teststream.flv来测试 HTTP-FLV 播放(需要浏览器环境支持)。

5. 生产环境部署考量与性能调优建议

通过上述步骤,我们已经成功在 CentOS 7.9 上编译并验证了 ZLMediaKit 的基本功能。但如果要用于生产环境,还有一些重要的步骤和考量。

5.1 以系统服务方式运行

前台运行MediaServer不适合生产环境。我们需要将其配置为 systemd 服务,实现开机自启、故障重启和日志管理。

创建服务文件/etc/systemd/system/zlmediakit.service

[Unit] Description=ZLMediaKit Media Server After=network.target [Service] Type=simple User=nobody # 建议使用非root用户运行,提升安全性 Group=nobody WorkingDirectory=/etc/zlmediakit ExecStart=/usr/local/bin/MediaServer -c /etc/zlmediakit/conf/config.ini -s /etc/zlmediakit/conf/default.pem Restart=on-failure RestartSec=5s # 资源限制可选 LimitNOFILE=65536 LimitCORE=infinity [Install] WantedBy=multi-user.target

然后启用并启动服务:

sudo systemctl daemon-reload sudo systemctl enable zlmediakit sudo systemctl start zlmediakit sudo systemctl status zlmediakit # 查看状态

日志可以通过journalctl -u zlmediakit -f来实时查看。

5.2 配置文件关键项调优

默认的config.ini配置文件适用于测试。生产环境需要根据实际负载调整。以下几个部分需要重点关注:

  • [general]

    • maxStreamWaitMS:等待流注册的超时时间,网络不好可适当调大。
    • streamNoneReaderDelayMS:流无观众时的延迟关闭时间,节省资源。
    • addMuteAudio:是否在转协议时添加静音音频轨道,确保某些播放器兼容性。
    • resetWhenRePlay:重复播放时是否重置时间戳。
  • [shell]:可以启用enable=1,并设置maxReqSizeauthSecret,用于通过 API 执行服务器命令(如重启某个协议)。

  • [protocol]各子段:如[rtmp],[rtsp],[hls]等,可以修改port(端口号)、sslport(SSL端口号)。务必检查并修改默认端口,特别是如果服务器有公网 IP。

  • [hls]broadcastRecordTs是否广播录制 ts 文件,deleteDelaySec切片文件删除延迟,segNumsegRetain控制切片数量和保留策略,直接影响存储空间和延迟。

  • [record]:如果启用录制,appNamefastStart等参数需要配置,filePath要指向一个有足够空间和写入权限的目录。

  • [http]charSet字符集,keepAliveSecond连接保持时间,maxReqSize最大请求大小,rootPath静态文件根目录(Web管理界面文件在此)。

最重要的安全项:修改[api]段的secret密钥,使用一个你自己生成的复杂字符串,不要使用默认值。

5.3 性能监控与问题排查思路

当服务运行起来后,监控和排查是运维的日常。

  1. 资源监控:使用tophtopnmon监控MediaServer进程的 CPU 和内存占用。流媒体服务通常是 I/O 和 CPU 密集型,特别是开启转码时。
  2. 网络监控:使用iftopnethogs查看网络带宽使用情况,确认推流和拉流带宽是否符合预期。
  3. 日志分析MediaServer的日志级别可以在配置文件中通过logLevel调整。遇到问题时,可以临时调整为DebugTrace级别,获取更详细的信息。重点关注错误(ERROR)和警告(WARN)日志。
  4. 流状态查询:熟练使用前面提到的getMediaListgetMediaInfo等 API,实时了解服务器上所有流的状态(如发布者 IP、观看人数、产生时间、编码信息等)。
  5. 常见问题速查
    • 推流失败:检查防火墙是否放行了对应的端口(如 1935)。检查推流地址的 AppName 和 StreamName 是否正确。查看服务器日志是否有鉴权失败等信息。
    • 拉流失败(404):确认流是否还存在(通过getMediaListAPI)。检查拉流地址的协议、AppName、StreamName 后缀(如.flv,.m3u8)是否正确。
    • 播放卡顿或延迟大:检查服务器带宽是否充足。检查播放器设置,如果是 HLS,延迟本身较大。如果是 HTTP-FLV 还卡顿,可能是网络抖动或服务器性能瓶颈。可以尝试降低推流码率或分辨率。
    • 内存缓慢增长:可能是流没有正常关闭,检查streamNoneReaderDelayMS设置是否合理,或者是否存在播放器异常断开连接没有发送close事件的情况。

5.4 关于 Docker 部署的补充

虽然本文主题是编译,但网络热词中提到了zlmediakit docker compose。对于生产环境,使用 Docker 部署确实是更优雅和一致的选择。ZLMediaKit 官方提供了 Docker 镜像zlmediakit/zlmediakit。使用 Docker Compose 可以轻松定义服务、配置文件和数据卷。

一个简单的docker-compose.yml示例如下:

version: '3' services: zlmediakit: image: zlmediakit/zlmediakit:latest container_name: zlmediakit restart: always ports: - "1935:1935" # RTMP - "80:80" # HTTP/HTTP-FLV/HLS/API - "443:443" # HTTPS/WebSocket-FLV - "554:554" # RTSP - "10000:10000/tcp" # RTP over TCP - "10000:10000/udp" # RTP over UDP volumes: - ./conf:/opt/zlmediakit/conf # 挂载自定义配置文件 - ./logs:/opt/zlmediakit/logs # 挂载日志目录 - ./record:/opt/zlmediakit/record # 挂载录制文件目录 environment: - TZ=Asia/Shanghai # 设置时区

使用 Docker 的好处是环境隔离、依赖统一、升级回滚方便。你需要做的就是把编译环节中手动调整的config.ini配置文件,放到宿主机的./conf目录下,然后docker-compose up -d即可。这相当于把编译的复杂性交给了镜像维护者,你只需要关注配置和运行。对于快速部署和维护来说,这是更推荐的方式。当然,理解本文的编译过程,能让你在需要自定义依赖、深度定制或排查底层问题时,更有底气。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询