ZLMediaKit 搭建流媒体服务:监控直播与录播完整方案
AI摘要
ZLMediaKit是一个基于C++11的流媒体服务框架,支持RTSP、RTMP、HLS等多种协议,适用于监控、直播和录播场景。本文详细介绍了如何使用ZLMediaKit搭建流媒体服务,包括Docker部署、配置文件说明、监控摄像头接入、直播推流、录播方案、多路监控批量接入、WebHook事件通知、WebRTC低延迟播放以及常见问题解答。通过ZLMediaKit,可以实现摄像头信号的多种场景服务,满足不同需求。
ZLMediaKit是什么
ZLMediaKit 是一个基于 C++11 的流媒体服务框架,核心能力是协议转换:摄像头推来的 RTSP、OBS 推来的 RTMP,统一转出 WebRTC/HLS/HTTP-FLV,让不同终端都能消费同一路流。
支持协议:RTSP、RTMP、HLS、HTTP-FLV、WebRTC、SRT
协议对比:RTSP vs RTMP vs WebRTC
先搞清楚三个协议分别在哪个环节用,之后选配置才不会蒙:
| 维度 | RTSP | RTMP | WebRTC |
|---|---|---|---|
| 传输层 | TCP/UDP | TCP | UDP(DTLS + SRTP) |
| 典型延迟 | 1~3 秒 | 1~3 秒 | < 500ms(亚秒级) |
| 浏览器支持 | 不支持 | 不支持(Flash 已死) | 原生支持 |
| 主要用途 | 摄像头/NVR 内网传输 | 直播推流(OBS等) | 低延迟播放、视频通话 |
| 防火墙穿透 | 差(需开 554 端口) | 一般(需开 1935) | 好(走 443/TURN) |
| 加密 | 可选(RTSPS) | 可选(RTMPS) | 强制加密 |
| 并发能力 | 中 | 中 | 中(信令开销较高) |
| 适用场景 | 监控设备接入、内网传输 | 直播推流端 | 浏览器实时播放、监控大屏 |
- RTSP:摄像头/NVR 的原生协议,用于设备到服务器的接入
- RTMP:直播推流端的标准,OBS/编码器用这个往服务器推
- WebRTC:浏览器端播放的最优解,延迟最低,无需插件
ZLMediaKit 接收前两者,输出成后面所有格式,一路摄像头信号同时服务多种终端。
一、部署 ZLMediaKit
1.1 Docker 部署(推荐)
# 拉取镜像
docker pull zlmediakit/zlmediakit:master
# 启动容器
docker run -d \
--name zlmediakit \
--restart=always \
-p 1935:1935 \ # RTMP
-p 554:554 \ # RTSP
-p 8080:80 \ # HTTP / HLS / HTTP-FLV
-p 8443:443 \ # HTTPS
-p 8554:8554 \ # RTSP over HTTP
-p 10000:10000/udp \ # RTP/RTCP
-p 8000:8000/udp \ # WebRTC(DTLS)
-p 10000-10100:10000-10100/udp \ # WebRTC 媒体端口范围
-v /opt/zlmediakit/config:/opt/config \
-v /opt/zlmediakit/record:/opt/record \
zlmediakit/zlmediakit:master1.2 源码编译(Linux)
# 安装依赖
apt-get install -y cmake gcc g++ git libssl-dev libsdl-dev libavcodec-dev libavutil-dev
# 克隆源码(含子模块)
git clone --depth 1 https://github.com/ZLMediaKit/ZLMediaKit.git
cd ZLMediaKit
git submodule update --init
# 编译
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
# 启动
cd release/linux/Release
./MediaServer -d &二、配置文件说明
配置文件为 config.ini,关键配置项:
[api]
# HTTP API 密钥,用于调用 REST 接口
secret=your_api_secret
[general]
# 流媒体文件存储根目录
mediaServerId=zlmediakit-server
[record]
# 录像文件保存路径
appName=record
# MP4 录制分片时长(秒)
mp4MaxSecond=3600
[hls]
# HLS 切片时长(秒)
segDur=2
# 切片数量
segNum=3
[rtsp]
# RTSP 服务端口
port=554
[rtmp]
# RTMP 服务端口
port=1935
[http]
# HTTP 服务端口(HLS/HTTP-FLV 分发)
port=80三、监控摄像头接入
3.1 拉取 RTSP 流并转发
ZLMediaKit 提供 HTTP API 可主动拉取摄像头的 RTSP 流:
# 调用 API 拉取 RTSP 流,自动转换为 RTMP/HLS/HTTP-FLV
curl "http://127.0.0.1:8080/index/api/addStreamProxy?secret=your_api_secret\
&vhost=__defaultVhost__\
&app=live\
&stream=camera01\
&url=rtsp://admin:password@192.168.1.100:554/h264/ch1/main/av_stream\
&rtp_type=0\
&enable_mp4=1"参数说明:
| 参数 | 说明 |
|---|---|
app | 应用名,自定义 |
stream | 流 ID,自定义 |
url | 摄像头 RTSP 地址 |
rtp_type | 0=TCP 1=UDP,推荐 TCP |
enable_mp4 | 是否录制为 MP4 |
3.2 拉流后访问地址
成功拉流后,同一路流自动转换为多种协议:
| 协议 | 访问地址 |
|---|---|
| RTSP | rtsp://your-server:554/live/camera01 |
| RTMP | rtmp://your-server:1935/live/camera01 |
| HTTP-FLV | http://your-server:8080/live/camera01.flv |
| HLS | http://your-server:8080/live/camera01/hls.m3u8 |
| WebRTC | http://your-server:8080/webrtc.html?url=webrtc://your-server/live/camera01 |
3.3 查看所有在线流
curl "http://127.0.0.1:8080/index/api/getMediaList?secret=your_api_secret"3.4 停止拉流
curl "http://127.0.0.1:8080/index/api/delStreamProxy?secret=your_api_secret\
&key=__defaultVhost__/live/camera01"四、直播推流
4.1 OBS / ffmpeg 推 RTMP 流
ffmpeg 推流示例:
# 推送本地视频文件
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://your-server:1935/live/stream01
# 推送摄像头(macOS)
ffmpeg -f avfoundation -framerate 30 -i "0:0" \
-c:v libx264 -preset ultrafast -tune zerolatency \
-c:a aac -f flv rtmp://your-server:1935/live/stream01OBS 推流设置:
- 服务器:
rtmp://your-server:1935 - 串流密钥:
live/stream01
4.2 推流后的播放地址
同 3.2 节,推流成功后自动生成多种协议地址。
五、录播方案
5.1 推流时自动录制
通过 API 触发录制,或在配置中开启自动录制:
# 对指定流开启 MP4 录制
curl "http://127.0.0.1:8080/index/api/startRecord?secret=your_api_secret\
&type=1\
&vhost=__defaultVhost__\
&app=live\
&stream=camera01\
&customized_path=/opt/record/camera01"| 参数 | 说明 |
|---|---|
type | 0=HLS录制 1=MP4录制 |
customized_path | 自定义录制路径(可选) |
5.2 停止录制
curl "http://127.0.0.1:8080/index/api/stopRecord?secret=your_api_secret\
&type=1\
&vhost=__defaultVhost__\
&app=live\
&stream=camera01"5.3 查询录制状态
curl "http://127.0.0.1:8080/index/api/isRecording?secret=your_api_secret\
&type=1\
&vhost=__defaultVhost__\
&app=live\
&stream=camera01"5.4 录制文件目录结构
/opt/record/
└── live/
└── camera01/
├── 2026-02-27/
│ ├── 08-00-00.mp4
│ ├── 09-00-00.mp4
│ └── ...默认按 mp4MaxSecond 分片,每小时一个文件(3600秒)。
5.5 录制文件回放
MP4 文件可通过 HTTP 直接访问(需配置 http 根目录指向录制目录):
http://your-server:8080/record/live/camera01/2026-02-27/08-00-00.mp4六、多路监控批量接入
多路摄像头用脚本批量拉流:
#!/bin/bash
SECRET="your_api_secret"
SERVER="http://127.0.0.1:8080"
cameras=(
"camera01|rtsp://admin:pass@192.168.1.100:554/stream"
"camera02|rtsp://admin:pass@192.168.1.101:554/stream"
"camera03|rtsp://admin:pass@192.168.1.102:554/stream"
)
for item in "${cameras[@]}"; do
name="${item%%|*}"
url="${item##*|}"
echo "Adding stream: $name"
curl -s "${SERVER}/index/api/addStreamProxy?secret=${SECRET}\
&vhost=__defaultVhost__\
&app=live\
&stream=${name}\
&url=${url}\
&rtp_type=0\
&enable_mp4=1" | python3 -m json.tool
echo ""
done七、WebHook 事件通知
ZLMediaKit 支持 Webhook,在流上线/下线/录制完成时回调你的业务系统:
[hook]
enable=1
# 流上线通知
on_publish=http://your-backend/hook/publish
# 流下线通知
on_stream_none_reader=http://your-backend/hook/no_reader
# MP4 录制完成通知
on_record_mp4=http://your-backend/hook/record_done录制完成回调 payload 示例:
{
"app": "live",
"stream": "camera01",
"file_path": "/opt/record/live/camera01/2026-02-27/08-00-00.mp4",
"file_name": "08-00-00.mp4",
"file_size": 104857600,
"folder": "/opt/record/live/camera01/2026-02-27/",
"start_time": 1740614400,
"time_len": 3600,
"url": "live/camera01"
}八、WebRTC 低延迟播放
8.1 为什么用 WebRTC 看监控
传统监控大屏用 HLS 延迟通常 5~10 秒,HTTP-FLV 还得靠特殊播放器。WebRTC 能把延迟压到 500ms 以内,浏览器原生跑,适合监控大屏和移动端 H5 实时预览,双向通话也行。
8.2 配置 WebRTC
config.ini 中启用 WebRTC:
[webrtc]
# WebRTC 监听端口(UDP)
port=8000
# 服务器公网 IP(必填,否则 ICE 协商失败)
externIP=your.public.ip注意:externIP 是 WebRTC 能否正常工作的关键。内网部署填内网 IP,公网部署必须填公网 IP。8.3 播放 WebRTC 流
ZLMediaKit 内置了一个 WebRTC 播放页面:
# 浏览器直接打开
http://your-server:8080/webrtc.html?url=webrtc://your-server/live/camera01也可以用 JavaScript 调用 ZLMediaKit 的 WebRTC API 自行集成:
// 1. 创建 RTCPeerConnection
const pc = new RTCPeerConnection();
// 2. 获取 ZLMediaKit 的 SDP offer
const response = await fetch('http://your-server:8080/index/api/webrtc?' +
'app=live&stream=camera01&type=play', {
method: 'POST',
body: new RTCSessionDescription(await pc.createOffer()).sdp
});
// 3. 设置远端 SDP
await pc.setRemoteDescription({
type: 'answer',
sdp: await response.text()
});
// 4. 绑定到 video 元素
pc.ontrack = (e) => {
document.querySelector('video').srcObject = e.streams[0];
};8.4 WebRTC 推流(浏览器推流)
ZLMediaKit 也支持从浏览器直接推流(无需 OBS):
http://your-server:8080/webrtc.html?url=webrtc://your-server/live/stream01&type=push九、常见问题
Q: 摄像头 RTSP 拉流失败?
- 确认摄像头 RTSP 地址正确,可先用 VLC 验证
- 尝试切换
rtp_type=1(UDP)或rtp_type=0(TCP) - 检查防火墙是否放行 554 端口
Q: HLS 延迟高?
- 调低
segDur(切片时长),如改为 1 秒 - 减少
segNum(切片数量),如改为 2
Q: MP4 录制文件损坏?
- 不要直接 kill 进程,使用 API
/index/api/kick_session或正常停止服务 - 确保磁盘空间充足
Q: 流媒体鉴权?
- 配置
[hook] on_play和on_publishWebhook,在业务后端做鉴权返回 allow/deny
Q: WebRTC 播放黑屏/无法连接?
- 检查
config.ini的externIP是否填写了正确的公网 IP - 确认 UDP 8000 端口和媒体端口范围(10000-10100)已在防火墙放行
- WebRTC 要求 HTTPS 或 localhost,HTTP 下浏览器会拒绝访问摄像头(推流场景)
Q: WebRTC 有延迟但比 HLS 好不了多少?
- 检查是否走了 TURN 中转(可在浏览器
chrome://webrtc-internals查看 ICE 候选) - 若服务器在内网/NAT 后面,需配置 TURN 服务器或确保
externIP正确
参考资料
- GitHub:https://github.com/ZLMediaKit/ZLMediaKit
- 官方 Wiki:https://github.com/ZLMediaKit/ZLMediaKit/wiki
- REST API 文档:https://github.com/ZLMediaKit/ZLMediaKit/wiki/MediaServer支持的HTTP-API