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/
?目錄