ZLMediaKit 源代码入门
ZLMediaKit 是一个基于 C++11 开发的高性能流媒体服务器框架,支持 RTSP、RTMP、HLS、HTTP-FLV 等协议。以下是源代码入门的详细指南:
1. 源码结构概览
主要目录结构:
text
ZLMediaKit/
├── cmake/ # CMake 构建配置
├── release/ # 发布相关文件
├── src/ # 核心源代码
│ ├── Common/ # 公共工具类
│ ├── Device/ # 设备相关代码
│ ├── Http/ # HTTP 协议实现
│ ├── Player/ # 播放器相关
│ ├── Poller/ # 事件轮询器
│ ├── Protocol/ # 各种流媒体协议实现
│ ├── Rtmp/ # RTMP 协议实现
│ ├── Rtsp/ # RTSP 协议实现
│ ├── Shell/ # 命令行交互
│ ├── Util/ # 工具类
│ └── Web/ # Web 相关
├── tests/ # 测试代码
└── www/ # Web 界面资源
2. 核心模块分析
2.1 事件循环 (Poller)
-
EventPoller.h/cpp
: 事件轮询器核心,基于 epoll/kqueue -
Poller/Timer.h
: 定时器实现 -
采用多线程事件循环模型,每个线程独立运行一个事件循环
2.2 协议支持
-
Protocol/
目录下包含各种协议实现:-
Rtsp
: RTSP 协议实现 -
Rtmp
: RTMP 协议实现 -
Http
: HTTP/WebSocket 实现 -
Srt
: SRT 协议实现
-
2.3 媒体处理
-
Media/
目录包含媒体相关处理:-
MediaSource.h
: 媒体源抽象 -
MultiMediaSourceMuxer.h
: 多路复用器 -
HlsMaker.h
: HLS 生成器
-
3. 代码阅读
3.1 关键代码阅读
-
src/main.cpp,
入口文件,程序初始化流程。 -
src/Rtsp/
目录下的会话管理 -
src/Media/
下的多路复用器实现 -
src/Poller/
中的事件循环核心
3.2 核心类关系
-
EventPoller: 事件循环核心
-
Socket: 网络套接字封装
-
MediaSource: 媒体源基类
-
RtmpSession/RtspSession: 协议会话实现
3.3 关键流程
-
服务器启动流程:
-
创建事件轮询器
-
初始化各协议服务器
-
绑定端口开始监听
-
-
客户端连接处理流程:
-
接受新连接
-
创建对应的 Session 对象
-
处理协议交互
-
4. 核心架构解析
4.1 高性能网络模型
多线程 Reactor 模式增强版:
-
每个 EventPoller 线程独立运行事件循环
-
采用无锁队列进行线程间通信
-
智能的任务负载均衡算法
// 典型事件循环核心代码片段 (EventPoller.cpp)
void EventPoller::runLoop() {while (!_exit_flag) {_timer_map->getMinimalTimer(); // 处理定时器int64_t minDelay = _timer_map->getMinimalTimer();int ret = _epoller.waitEvent(minDelay); // epoll_waithandleEventResult(ret); // 处理IO事件_async_task_queue->inputOtherThread(...); // 处理跨线程任务}
}
性能优化关键点:
-
使用 EPOLLEXCLUSIVE 避免惊群效应
-
采用时间轮(TimingWheel)管理定时器
-
零拷贝技术减少内存拷贝
4.2 媒体处理流水线
多级媒体处理架构:
text
[ 采集源 ] -> [ 协议解封装 ] -> [ 转码/转封装 ] -> [ 协议封装 ] -> [ 发送 ]
关键类关系:
5. 调试与开发环境搭建
5.1 编译环境
bash
git clone https://github.com/ZLMediaKit/ZLMediaKit.git
cd ZLMediaKit
git submodule update --init
mkdir build
cd build
cmake ..
make -j4
5.2 调试技巧
-
使用 GDB/LLDB 调试
# 查看事件循环状态 p *(EventPoller*)0x7fffffff# 追踪媒体帧流转 watch *(uint8_t*)media_frame_ptr->data()# 分析内存池状态 p toolkit::ResourcePool<BufferRaw>::Instance()
-
开启 DEBUG 级别日志
-
使用 Wireshark 抓包分析协议交互
# 使用tcpdump抓取特定流 tcpdump -i eth0 'port 1935 and host 192.168.1.100' -w rtmp.pcap# 使用ffmpeg测试极端情况 ffmpeg -re -f lavfi -i testsrc -c:v libx264 -f flv \'rtmp://localhost/live/stream?token=secure_key'
-
通过内置API获取运行时状态
# 获取媒体源列表 curl http://127.0.0.1:8080/api/getMediaList# 获取线程负载 curl http://127.0.0.1:8080/api/getThreadsLoad# 获取内存信息 curl http://127.0.0.1:8080/api/getStatistic
6. 常见扩展开发
6.1 添加新协议
-
在
Protocol/
下创建新目录 -
继承
TcpSession
或UdpSession
-
实现协议解析逻辑
-
在服务器初始化时注册新协议
示例:
-
继承 TcpSession 实现协议解析
class MyProtocolSession : public TcpSession { public:void onRecv(const Buffer::Ptr &buf) override {// 自定义协议解析逻辑if (parseComplete(buf)) {processMediaFrame(buf);}} };
-
注册协议到服务器
// 在main函数中注册 auto server = std::make_shared<TcpServer>(); server->start<MyProtocolSession>(port);
6.2 自定义媒体处理
-
继承
MediaSource
实现自定义媒体源 -
实现帧数据生成逻辑
-
注册到
MediaRegistry
示例:实现视频滤镜
class VideoFilter : public Frame {
public:Frame::Ptr filter(const Frame::Ptr &frame) {// 获取原始数据auto data = frame->data();// 处理视频帧 (示例:简单的灰度处理)if (frame->getCodecId() == CodecH264) {processYUV(data, frame->size());}return std::make_shared<Frame>(...);}
};// 在MediaSource中应用
source->setFilter([](const Frame::Ptr &frame) {return VideoFilter().filter(frame);
});
7. 性能调优指南
7.1 关键性能指标
指标 | 优化方向 | 相关配置项 |
---|---|---|
连接数 | 线程数/文件描述符限制 | thread_num, max_connections |
延迟 | 缓冲区大小/发送策略 | send_rtp_packet_size |
CPU占用 | 编解码优化/线程绑定 | enable_affinity |
内存占用 | 对象池/缓存策略 | media_timeout_ms |
7.2 高级配置示例
ini
; config.ini 关键配置
[api]
secret=your_api_key ; 安全API访问[rtmp]
handshakeSecond=10 ; RTMP握手超时
keepAliveSecond=15 ; 保活时间[hls]
fileBufSize=65536 ; HLS文件缓冲区
segDur=2 ; 分片时长(秒)
7.3 性能分析工具
-
perf 进行热点分析
-
valgrind 检查内存问题
-
gperftools 分析CPU使用
8. 二次开发案例
8.1 集成 AI 分析功能
// 在FrameDispatcher中添加AI处理
class AIVideoAnalyzer : public FrameDispatcher {
public:void inputFrame(const Frame::Ptr &frame) override {auto result = _ai_model->analyze(frame->data());if (result.alarm) {triggerAlarm(result);}// 继续传递帧数据FrameDispatcher::inputFrame(frame);}
};// 注册到媒体源
source->setFrameDispatcher(std::make_shared<AIVideoAnalyzer>());
8.2 自定义负载均衡策略
// 继承LoadBalancer实现自定义策略
class CustomLoadBalancer : public LoadBalancer {
public:EventPoller::Ptr getPoller() override {// 基于CPU温度选择的策略auto temp = getCPUTemperature();return selectCoolestPoller(temp);}
};// 替换默认实现
EventPollerPool::setLoadBalancer(std::make_shared<CustomLoadBalancer>());
9. 学习资源
-
官方文档: ZLMediaKit Wiki
-
示例代码:
tests/
目录