ZLMediaKit 入门
什么是ZLMediaKit?
ZLMediaKit 是一个基于C++11的高性能流媒体服务器框架,支持RTSP/RTMP/HLS/HTTP-FLV/WebSocket-FLV等多种流媒体协议。它具有以下特点:
-
跨平台支持(Linux、Windows、macOS)
-
高性能,支持高并发
-
低延迟
-
支持多种协议转换
-
开源免费(MIT许可证)
安装ZLMediaKit
Linux/macOS 编译安装
1.安装依赖项:
bash
# Ubuntu/Debian
sudo apt install build-essential cmake git
sudo apt install libssl-dev libsdl-dev libavcodec-dev libavutil-dev libavformat-dev# CentOS
sudo yum install -y gcc-c++ cmake git
sudo yum install -y openssl-devel SDL2-devel ffmpeg-devel# macOS (使用Homebrew)
brew install cmake openssl ffmpeg sdl2
2.克隆代码库:
bash
git clone --depth 1 https://github.com/ZLMediaKit/ZLMediaKit.git
cd ZLMediaKit
git submodule update --init
3.编译:
bash
mkdir build
cd build
cmake ..
make -j4
Windows 编译安装
-
安装Visual Studio 2017或更高版本
-
安装CMake
-
使用CMake生成Visual Studio项目文件
-
用Visual Studio打开并编译
基本使用
启动服务器
bash
# Linux/macOS
cd ZLMediaKit/release/linux/Debug
./MediaServer -d & # 后台运行# Windows
cd ZLMediaKit/release/windows/Debug
MediaServer.exe
配置文件
文件位置
-
默认路径:与
MediaServer
可执行文件同目录 -
指定路径:启动时通过
-c
参数指定,如./MediaServer -c /path/to/config.ini
配置文件结构
[api] 部分 - HTTP API 配置
ini
[api]
apiDebug=1 ; 是否启用API调试模式(1启用)
secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc ; API调用密钥
defaultSnap=./www/logo.png ; 截图默认图片
[ffmpeg] 部分 - FFmpeg 相关配置
ini
[ffmpeg]
bin=/usr/bin/ffmpeg ; ffmpeg路径
cmd=%s -i %s -c:a aac -strict -2 -ar 44100 -ab 48k -c:v libx264 -f flv %s
snap=%s -i %s -y -f mjpeg -frames:v 1 %s
log=/var/log/ffmpeg.log ; ffmpeg日志文件路径
[general] 部分 - 通用配置
ini
[general]
enableVhost=0 ; 是否启用虚拟主机(1启用)
flowThreshold=1024 ; 流量统计阈值(KB)
maxStreamWaitMS=15000 ; 等待流注册超时时间(毫秒)
streamNoneReaderDelayMS=20000 ; 无观众时流关闭延迟(毫秒)
addMuteAudio=1 ; 是否添加静音音频(当源只有视频时)
resetWhenRePlay=1 ; 断流后是否重新开始播放(1是)
publishToHls=1 ; 是否发布hls(1是)
publishToMP4=0 ; 是否发布mp4(1是)
[hls] 部分 - HLS 配置
ini
[hls]
fileBufSize=65536 ; HLS文件缓存大小
filePath=./www ; HLS文件保存路径
segDur=2 ; 分片时长(秒)
segNum=3 ; 保留分片数
segRetain=5 ; 分片保留时长(秒)
broadcastRecordTs=0 ; 是否广播录制ts(1是)
deleteDelaySec=10 ; 删除延迟(秒)
[http] 部分 - HTTP 协议配置
ini
[http]
allowCrossDomains=1 ; 是否允许跨域(1允许)
charSet=utf-8 ; HTTP字符集
dirMenu=1 ; 是否开启目录浏览(1开启)
keepAliveSecond=15 ; keep-alive超时(秒)
maxReqSize=4096 ; 最大请求头大小(KB)
port=80 ; HTTP服务器端口
rootPath=./www ; HTTP根目录
sslport=443 ; HTTPS服务器端口
[multicast] 部分 - 组播配置
ini
[multicast]
addrMax=239.255.255.255 ; 组播地址最大值
addrMin=239.0.0.0 ; 组播地址最小值
udpTTL=64 ; 组播TTL值
[record] 部分 - 录制配置
ini
[record]
appName=record ; 录制应用名
fileBufSize=65536 ; 文件缓存大小
filePath=./www ; 录制文件保存路径
sampleMS=500 ; 录制取样间隔(毫秒)
fastStart=0 ; 是否快速启动(1是)
fileRepeat=0 ; 是否循环录制(1是)
[rtmp] 部分 - RTMP 协议配置
ini
[rtmp]
handshakeSecond=15 ; 握手超时(秒)
keepAliveSecond=15 ; keep-alive超时(秒)
modifyStamp=1 ; 是否调整时间戳(1是)
port=1935 ; RTMP服务器端口
sslport=1936 ; RTMPS服务器端口
[rtp] 部分 - RTP 配置
ini
[rtp]
audioMtuSize=600 ; 音频MTU大小
videoMtuSize=1400 ; 视频MTU大小
rtpMaxSize=10 ; RTP最大缓存包数
[rtsp] 部分 - RTSP 协议配置
ini
[rtsp]
authBasic=0 ; 是否启用基本认证(1启用)
handshakeSecond=15 ; 握手超时(秒)
keepAliveSecond=15 ; keep-alive超时(秒)
port=554 ; RTSP服务器端口
sslport=322 ; RTSPS服务器端口
directProxy=1 ; 是否直接代理(1是)
[shell] 部分 - Shell 配置
ini
[shell]
maxReqSize=1024 ; 最大请求大小
port=9000 ; shell端口
[thread] 部分 - 线程池配置
ini
[thread]
thread_num=8 ; 线程池大小
高级配置
日志配置
ini
[log]
level=3 ; 日志级别(1-5, 1=verbose, 5=error)
logPath=./logs ; 日志目录
logDays=7 ; 日志保留天数
TCP/UDP 配置
ini
[tcp]
fast_open=1 ; 是否启用TCP快速打开(1启用)
sendBuf=4194304 ; 发送缓冲区大小(字节)
recvBuf=1048576 ; 接收缓冲区大小(字节)[udp]
sendBuf=1048576 ; 发送缓冲区大小(字节)
recvBuf=4194304 ; 接收缓冲区大小(字节)
性能调优配置
ini
[performance]
closeDelay=500 ; 关闭延迟(毫秒)
虚拟主机配置示例
ini
[vhost___defaultVhost__]
hls.segNum=5
hls.segDur=5
常用API
基础信息类API
1. 获取服务器配置
API: /index/api/getServerConfig
比如:http://127.0.0.1/index/api/getServerConfig
方法: GET
参数: 无
响应示例:
json
{"code": 0,"data": {"api.apiDebug": "1","api.secret": "035c73f7-bb6b-4889-a715-d9eb2d1925cc","ffmpeg.bin": "/usr/bin/ffmpeg","general.enableVhost": "0",// 更多配置项...}
}
2. 获取服务器版本信息
API: /index/api/version
方法: GET
参数: 无
响应示例:
json
{"code": 0,"data": {"buildTime": "2023-05-20 15:30:45","branchName": "master","commitHash": "a1b2c3d4","version": "10.0"}
}
流管理类API
3. 获取流列表
API: /index/api/getMediaList
方法: GET
参数:
-
schema
(可选): 协议类型,如rtsp/rtmp等 -
vhost
(可选): 虚拟主机名 -
app
(可选): 应用名
响应示例:
json
{"code": 0,"data": [{"app": "live","stream": "test","readerCount": 3,"totalReaderCount": 10,"originType": 0,"originTypeStr": "rtmp_push","createStamp": 1684567890,"aliveSecond": 3600}]
}
4. 检查流是否在线
API: /index/api/isMediaOnline
方法: GET
参数:
-
schema
: 协议类型,如rtsp/rtmp等 -
vhost
: 虚拟主机名 -
app
: 应用名 -
stream
: 流ID
响应示例:
json
{"code": 0,"online": true
}
5. 关闭流
API: /index/api/close_stream
方法: GET
参数:
-
schema
: 协议类型 -
vhost
: 虚拟主机名 -
app
: 应用名 -
stream
: 流ID -
force
(可选): 是否强制关闭(1/0)
响应示例:
json
{"code": 0,"msg": "success"
}
录制控制类API
6. 开始录制
API: /index/api/startRecord
方法: GET
参数:
-
type
: 0=hls, 1=mp4 -
vhost
: 虚拟主机名 -
app
: 应用名 -
stream
: 流ID -
customized_path
(可选): 自定义录制路径
响应示例:
json
{"code": 0,"result": true,"msg": "start record success"
}
7. 停止录制
API: /index/api/stopRecord
方法: GET
参数:
-
type
: 0=hls, 1=mp4 -
vhost
: 虚拟主机名 -
app
: 应用名 -
stream
: 流ID
响应示例:
json
{"code": 0,"result": true,"msg": "stop record success"
}
8. 获取录制状态
API: /index/api/isRecording
方法: GET
参数:
-
type
: 0=hls, 1=mp4 -
vhost
: 虚拟主机名 -
app
: 应用名 -
stream
: 流ID
响应示例:
json
{"code": 0,"status": true
}
代理与转协议API
9. 添加FFmpeg代理
API: /index/api/addFFmpegSource
方法: GET/POST
参数:
-
src_url
: 源流URL -
dst_url
: 目标流URL -
timeout_ms
: 超时时间(毫秒) -
enable_hls
: 是否启用HLS(1/0) -
enable_mp4
: 是否启用MP4录制(1/0)
响应示例:
json
{"code": 0,"msg": "success","key": "ffmpeg_key_123456"
}
10. 删除FFmpeg代理
API: /index/api/delFFmpegSource
方法: GET
参数:
-
key
: addFFmpegSource返回的key
响应示例:
json
{"code": 0,"msg": "success"
}
系统控制类API
11. 热加载配置文件
API: /index/api/reloadConfig
方法: GET
参数: 无
响应示例:
json
{"code": 0,"msg": "reload config success"
}
12. 关闭服务器
API: /index/api/closeServer
方法: GET
参数:
-
secret
: API密钥(必须与config.ini中的secret匹配)
响应示例:
json
{"code": 0,"msg": "server will close soon"
}
统计信息类API
13. 获取服务器负载情况
API: /index/api/getStatistic
方法: GET
参数: 无
响应示例:
json
{"code": 0,"data": {"online": {"streams": 5,"players": 23,"pushers": 3},"bytes": {"send": 1024000,"recv": 512000}}
}
14. 获取线程负载情况
API: /index/api/getThreadsLoad
方法: GET
参数: 无
响应示例:
json
{"code": 0,"data": [{"id": 0,"load": 45,"task": 1234}]
}
安全认证
所有API调用(除了version和getServerConfig)都需要添加secret参数或在HTTP头中添加Authorization:
bash
# 方法1:URL参数
http://127.0.0.1/index/api/getMediaList?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc# 方法2:HTTP头
curl -H "Authorization: 035c73f7-bb6b-4889-a715-d9eb2d1925cc" \http://127.0.0.1/index/api/getMediaList
注意事项
-
所有时间参数单位为毫秒,除非特别说明
-
返回的code为0表示成功,非0表示失败
-
生产环境建议使用HTTPS协议访问API
-
频繁调用的API建议添加适当的缓存机制
-
关键操作API(如关闭服务器)需要谨慎调用
推流与播放
推流方式
1. 使用 FFmpeg 推流
基本推流命令:
bash
ffmpeg -re -i input.mp4 -c:v libx264 -preset ultrafast -tune zerolatency -c:a aac -f flv rtmp://服务器IP/live/流ID
常用参数说明:
-
-re
:按照原始帧率推送 -
-i
:输入文件 -
-c:v
:视频编码器(libx264, h264等) -
-preset ultrafast
:最快编码预设 -
-tune zerolatency
:零延迟调优 -
-c:a
:音频编码器 -
-f flv
:输出格式为FLV
示例场景:
-
推送本地文件:
bash
ffmpeg -re -i test.mp4 -c:v libx264 -c:a aac -f flv rtmp://127.0.0.1/live/test
-
推送摄像头(Linux):
bash
ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -preset ultrafast -f flv rtmp://127.0.0.1/live/cam
-
推送屏幕(Windows):
bash
ffmpeg -f gdigrab -i desktop -c:v libx264 -preset ultrafast -f flv rtmp://127.0.0.1/live/screen
2. 使用 OBS 推流
-
打开OBS设置 → 推流
-
服务选择"自定义"
-
服务器填写:
rtmp://服务器IP/live
-
流密钥填写任意流ID(如:test123)
-
点击"确定"后开始推流
3. 使用 SDK 推流
ZLMediaKit支持多种协议的推流,包括RTMP、RTSP、RTP等。开发者可以使用以下SDK进行推流:
-
libZLToolKit(C++)
-
librtmp(C)
-
各语言封装的RTMP库(如Python的
pylibrtmp
)
播放方式
1. RTMP 播放
播放地址格式:
text
rtmp://服务器IP/live/流ID
播放工具:
-
VLC:媒体 → 打开网络串流 → 输入RTMP地址
-
FFplay:
bash
ffplay rtmp://127.0.0.1/live/test
-
网页播放(需Flash):使用JWPlayer等支持RTMP的网页播放器
2. HTTP-FLV 播放
播放地址格式:
text
http://服务器IP/live/流ID.flv
优势:
-
基于HTTP,穿透性好
-
延迟低(2-3秒)
-
支持网页端直接播放
播放工具:
-
VLC
-
FFplay:
bash
ffplay http://127.0.0.1/live/test.flv
-
网页播放(推荐flv.js):
html
<script src="https://cdn.jsdelivr.net/npm/flv.js@latest/dist/flv.min.js"></script> <video id="videoElement" controls></video> <script>if (flvjs.isSupported()) {var videoElement = document.getElementById('videoElement');var flvPlayer = flvjs.createPlayer({type: 'flv',url: 'http://127.0.0.1/live/test.flv'});flvPlayer.attachMediaElement(videoElement);flvPlayer.load();flvPlayer.play();} </script>
3. HLS 播放
播放地址格式:
text
http://服务器IP/live/流ID/hls.m3u8
特点:
-
高兼容性(所有浏览器原生支持)
-
高延迟(通常10-30秒)
-
适合点播和移动端
播放工具:
-
直接浏览器打开:
html
<video src="http://127.0.0.1/live/test/hls.m3u8" controls></video>
-
VLC/FFplay等播放器
4. WebRTC 播放(需启用WebRTC支持)
播放地址格式:
text
http://服务器IP/live/流ID.live.ts
特点:
-
超低延迟(<1秒)
-
需要浏览器支持WebRTC
网页播放示例:
html
<video id="video" autoplay controls></video>
<script>const video = document.getElementById('video');const pc = new RTCPeerConnection();pc.addTransceiver('video', { direction: 'recvonly' });pc.addTransceiver('audio', { direction: 'recvonly' });pc.ontrack = function(event) {if (event.track.kind === 'video') {video.srcObject = event.streams[0];}};fetch('http://127.0.0.1:8080/index/api/webrtc', {method: 'POST',body: JSON.stringify({type: 'play',app: 'live',stream: 'test',sdp: ''})}).then(res => res.json()).then(data => {pc.setRemoteDescription(new RTCSessionDescription(data.sdp));pc.createAnswer().then(answer => {pc.setLocalDescription(answer);});});
</script>
推流与播放状态管理
1. 检查流是否在线
bash
curl "http://127.0.0.1/index/api/isMediaOnline?app=live&stream=test"
2. 获取流信息
bash
curl "http://127.0.0.1/index/api/getMediaInfo?app=live&stream=test"
3. 断开指定推流
bash
curl "http://127.0.0.1/index/api/kick_session?type=0&id=客户端ID"
延迟优化建议
-
推流端优化:
-
使用
-tune zerolatency
参数 -
降低GOP长度(
-g 30
) -
减少B帧数量(
-bf 0
)
-
-
服务器端优化:
ini
[rtmp] modifyStamp=1[hls] segDur=1 segNum=3
-
播放端优化:
-
使用HTTP-FLV或WebRTC协议
-
减少播放器缓冲时间
-
常见问题解决
1. 推流失败
-
检查服务器端口是否开放(默认1935)
-
检查防火墙设置
-
查看ZLMediaKit日志
2. 播放卡顿
-
检查网络带宽
-
降低推流码率
-
检查服务器负载
3. 高延迟
-
避免使用HLS协议
-
调整GOP大小
-
使用低延迟协议(WebRTC或HTTP-FLV)
常见问题
-
如何提高性能?
-
调整配置文件中的线程数
-
启用TCP_NODELAY
-
使用硬件加速编解码
-
-
如何实现鉴权?
-
配置文件中设置
[api]
部分的secret
-
实现
on_rtsp_realm
和on_rtsp_auth
回调
-
-
如何支持WebRTC?
-
编译时开启
ENABLE_WEBRTC
选项 -
配置STUN/TURN服务器
-
进阶学习
-
阅读官方文档:https://github.com/ZLMediaKit/ZLMediaKit/wiki