> 技术文档 > ZLMediaKit 源代码入门

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 核心类关系

  1. EventPoller: 事件循环核心

  2. Socket: 网络套接字封装

  3. MediaSource: 媒体源基类

  4. RtmpSession/RtspSession: 协议会话实现

3.3 关键流程

  1. 服务器启动流程:

    • 创建事件轮询器

    • 初始化各协议服务器

    • 绑定端口开始监听

  2. 客户端连接处理流程:

    • 接受新连接

    • 创建对应的 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_wait handleEventResult(ret); // 处理IO事件 _async_task_queue->inputOtherThread(...); // 处理跨线程任务 }}

性能优化关键点

  • 使用 EPOLLEXCLUSIVE 避免惊群效应

  • 采用时间轮(TimingWheel)管理定时器

  • 零拷贝技术减少内存拷贝

4.2 媒体处理流水线

多级媒体处理架构

text

[ 采集源 ] -> [ 协议解封装 ] -> [ 转码/转封装 ] -> [ 协议封装 ] -> [ 发送 ]

关键类关系

5. 调试与开发环境搭建

5.1 编译环境

bash

git clone https://github.com/ZLMediaKit/ZLMediaKit.gitcd ZLMediaKitgit submodule update --initmkdir buildcd buildcmake ..make -j4

5.2 调试技巧

  1. 使用 GDB/LLDB 调试

    # 查看事件循环状态p *(EventPoller*)0x7fffffff# 追踪媒体帧流转watch *(uint8_t*)media_frame_ptr->data()# 分析内存池状态p toolkit::ResourcePool::Instance()
  2. 开启 DEBUG 级别日志

  3. 使用 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\'
  4. 通过内置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 添加新协议

  1. 在 Protocol/ 下创建新目录

  2. 继承 TcpSession 或 UdpSession

  3. 实现协议解析逻辑

  4. 在服务器初始化时注册新协议

示例:

  1. 继承 TcpSession 实现协议解析

    class MyProtocolSession : public TcpSession {public: void onRecv(const Buffer::Ptr &buf) override { // 自定义协议解析逻辑 if (parseComplete(buf)) { processMediaFrame(buf); } }};
  2. 注册协议到服务器

    // 在main函数中注册auto server = std::make_shared();server->start(port);

6.2 自定义媒体处理

  1. 继承 MediaSource 实现自定义媒体源

  2. 实现帧数据生成逻辑

  3. 注册到 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(...); }};// 在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());

8.2 自定义负载均衡策略

// 继承LoadBalancer实现自定义策略class CustomLoadBalancer : public LoadBalancer {public: EventPoller::Ptr getPoller() override { // 基于CPU温度选择的策略 auto temp = getCPUTemperature(); return selectCoolestPoller(temp); }};// 替换默认实现EventPollerPool::setLoadBalancer(std::make_shared());

9. 学习资源

  1. 官方文档: ZLMediaKit Wiki

  2. 示例代码: tests/ 目录