ZLMediaKit 入门

发布于:2025-07-23 ⋅ 阅读:(29) ⋅ 点赞:(0)

什么是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 编译安装

  1. 安装Visual Studio 2017或更高版本

  2. 安装CMake

  3. 使用CMake生成Visual Studio项目文件

  4. 用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

启动拉流代理(从远程拉流到 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  // 当前观看人数
}

注意事项

  1. 所有时间参数单位为毫秒,除非特别说明

  2. 返回的code为0表示成功,非0表示失败

  3. 生产环境建议使用HTTPS协议访问API

  4. 频繁调用的API建议添加适当的缓存机制

  5. 关键操作API(如关闭服务器)需要谨慎调用

  6. 确保端口开放:RTMP 默认 1935,HTTP API 默认 80

  7. API 密钥:如果配置了 api.secret(在 config.ini 中),必须在请求中携带。

  8. 拉流重试:如果远程流断开,ZLMediaKit 默认会尝试重连。

  9. 流唯一性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 推流

  1. 打开OBS设置 → 推流

  2. 服务选择"自定义"

  3. 服务器填写:rtmp://服务器IP/live

  4. 流密钥填写任意流ID(如:test123)

  5. 点击"确定"后开始推流

3. 使用 SDK 推流

ZLMediaKit支持多种协议的推流,包括RTMP、RTSP、RTP等。开发者可以使用以下SDK进行推流:

播放方式

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"

延迟优化建议

  1. 推流端优化

    • 使用-tune zerolatency参数

    • 降低GOP长度(-g 30

    • 减少B帧数量(-bf 0

  2. 服务器端优化

    ini

    [rtmp]
    modifyStamp=1
    
    [hls]
    segDur=1
    segNum=3
  3. 播放端优化

    • 使用HTTP-FLV或WebRTC协议

    • 减少播放器缓冲时间

常见问题解决

1. 推流失败

  • 检查服务器端口是否开放(默认1935)

  • 检查防火墙设置

  • 查看ZLMediaKit日志

2. 播放卡顿

  • 检查网络带宽

  • 降低推流码率

  • 检查服务器负载

3. 高延迟

  • 避免使用HLS协议

  • 调整GOP大小

  • 使用低延迟协议(WebRTC或HTTP-FLV)

常见问题

  1. 如何提高性能?

    • 调整配置文件中的线程数

    • 启用TCP_NODELAY

    • 使用硬件加速编解码

  2. 如何实现鉴权?

    • 配置文件中设置[api]部分的secret

    • 实现on_rtsp_realmon_rtsp_auth回调

  3. 如何支持WebRTC?

    • 编译时开启ENABLE_WEBRTC选项

    • 配置STUN/TURN服务器

进阶学习

  1. 阅读官方文档:https://github.com/ZLMediaKit/ZLMediaKit/wiki


网站公告

今日签到

点亮在社区的每一天
去签到