什么是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
: 流IDforce
(可选): 是否强制关闭(1/0)
响应示例:
json
{
"code": 0,
"msg": "success"
}
录制控制类API
6. 开始录制
API: /index/api/startRecord
方法: GET
参数:
type
: 0=hls, 1=mp4vhost
: 虚拟主机名app
: 应用名stream
: 流IDcustomized_path
(可选): 自定义录制路径
响应示例:
json
{
"code": 0,
"result": true,
"msg": "start record success"
}
7. 停止录制
API: /index/api/stopRecord
方法: GET
参数:
type
: 0=hls, 1=mp4vhost
: 虚拟主机名app
: 应用名stream
: 流ID
响应示例:
json
{
"code": 0,
"result": true,
"msg": "stop record success"
}
8. 获取录制状态
API: /index/api/isRecording
方法: GET
参数:
type
: 0=hls, 1=mp4vhost
: 虚拟主机名app
: 应用名stream
: 流ID
响应示例:
json
{
"code": 0,
"status": true
}
代理与转协议API
9. 添加FFmpeg代理
API: /index/api/addFFmpegSource
方法: GET/POST
参数:
src_url
: 源流URLdst_url
: 目标流URLtimeout_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
启动拉流代理(从远程拉流到 ZLMediaKit)
这是最常用的 "打开流推送" 方式,即让 ZLMediaKit 作为客户端主动拉取远程流,然后转发给本地客户端。
15. 开启拉流代理
API 接口
text
http://[ZLMediaKit_IP]:[HTTP端口]/index/api/addStreamProxy
请求参数
参数名 | 必选 | 说明 |
---|---|---|
secret |
是 | API 密钥(如果配置了 api.secret ) |
vhost |
否 | 虚拟主机,默认 __defaultVhost__ |
app |
是 | 本地应用名(如 live ) |
stream |
是 | 本地流 ID(如 test ) |
url |
是 | 远程流地址(如 rtmp://example.com/live/stream ) |
enable_hls |
否 | 是否生成 HLS(默认 false ) |
enable_mp4 |
否 | 是否录制 MP4(默认 false ) |
rtp_type |
否 | 拉流协议类型(rtmp /rtsp /hls /http ,默认自动判断) |
示例请求
bash
curl "http://127.0.0.1:80/index/api/addStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=live&stream=test&url=rtmp://example.com/live/origin_stream"
成功响应
json
{
"code": 0,
"msg": "success",
"data": {
"key": "__defaultVhost__/live/test"
}
}
16. 停止拉流代理
关闭已拉取的流。
API 接口
text
http://[ZLMediaKit_IP]:[HTTP端口]/index/api/delStreamProxy
请求参数
参数名 | 必选 | 说明 |
---|---|---|
secret |
是 | API 密钥 |
key |
是 | 流的 key(从 addStreamProxy 返回) |
示例请求
bash
curl "http://127.0.0.1:80/index/api/delStreamProxy?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&key=__defaultVhost__/live/test"
17. 主动推流到 ZLMediaKit
如果希望外部设备(如 FFmpeg、OBS)推流到 ZLMediaKit,可直接使用推流地址,无需调用 API。
推流地址格式
RTMP 推流
text
rtmp://[ZLMediaKit_IP]:1935/[app]/[stream]
示例:
bash
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://127.0.0.1/live/test
RTSP 推流
text
rtsp://[ZLMediaKit_IP]:554/[app]/[stream]
18. 查询流状态
检查流是否已成功打开。
API 接口
text
http://[ZLMediaKit_IP]:[HTTP端口]/index/api/getMediaInfo
请求参数
参数名 | 必选 | 说明 |
---|---|---|
secret |
是 | API 密钥 |
app |
是 | 应用名(如 live ) |
stream |
是 | 流 ID(如 test ) |
示例请求
bash
curl "http://127.0.0.1:80/index/api/getMediaInfo?secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc&app=live&stream=test"
成功响应(流存在时)
json
{
"code": 0,
"online": true,
"readerCount": 2 // 当前观看人数
}
注意事项
所有时间参数单位为毫秒,除非特别说明
返回的code为0表示成功,非0表示失败
生产环境建议使用HTTPS协议访问API
频繁调用的API建议添加适当的缓存机制
关键操作API(如关闭服务器)需要谨慎调用
确保端口开放:RTMP 默认
1935
,HTTP API 默认80
。API 密钥:如果配置了
api.secret
(在config.ini
中),必须在请求中携带。拉流重试:如果远程流断开,ZLMediaKit 默认会尝试重连。
流唯一性:
app
+stream
唯一标识一路流。
推流与播放
推流方式
1. 使用 FFmpeg 推流
基本推流命令:
bash
rtmp
rtmp://[ZLMediaKit_IP]:1935/[app]/[stream]
比如:
ffmpeg -re -i input.mp4 -c:v libx264 -preset ultrafast -tune zerolatency -c:a aac -f flv rtmp://服务器IP/live/流ID
rtsp rtsp://[ZLMediaKit_IP]:554/[app]/[stream]
常用参数说明:
-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服务器