推薦一個比較好用的流媒體服務開源代碼:
ZLMediaKit: 實現RTSP/RTMP/HLS/HTTP協議的輕量級流媒體框架,支持大並發連接請求
https://gitee.com/xiahcu/ZLMediaKit
文章目錄

一個基於C++11的高性能運營級流媒體服務框架
項目特點
- 基於C++11開發,避免使用裸指針,代碼穩定可靠;同時跨平台移植簡單方便,代碼清晰簡潔。
- 打包多種流媒體協議(RTSP/RTMP/HLS),支持協議間的互相轉換,提供一站式的服務。
- 使用epoll+線程池+異步網絡IO模式開發,並發性能優越。
- 已實現主流的的H264/H265+AAC流媒體方案,代碼精簡,脈絡清晰,適合學習。
- 編碼格式與框架代碼解耦,方便自由簡潔的添加支持其他編碼格式
- 代碼經過大量的穩定性、性能測試,可滿足商用服務器項目。
- 支持linux、macos、ios、android、windows平台
- 支持畫面秒開(GOP緩存)、極低延時(500毫秒內,最低可達100毫秒)
- 支持websocket-flv直播
- ZLMediaKit高並發實現原理
項目定位
- 移動嵌入式跨平台流媒體解決方案。
- 商用級流媒體服務器。
- 網絡編程二次開發SDK。
功能清單
-
RTSP
- RTSP 服務器,支持RTMP/MP4轉RTSP。
- RTSPS 服務器,支持亞馬遜echo show這樣的設備
- RTSP 播放器,支持RTSP代理,支持生成靜音音頻
- RTSP 推流客戶端與服務器
- 支持
rtp over udp
rtp over tcp
rtp over http
rtp組播
四種RTP傳輸方式 。 - 服務器/客戶端完整支持Basic/Digest方式的登錄鑒權,全異步可配置化的鑒權接口。
- 支持H265編碼
- 服務器支持RTSP推流(包括
rtp over udp
rtp over tcp
方式) - 支持任意編碼格式的rtsp推流,只是除H264/H265+AAC外無法轉協議
-
RTMP
- RTMP 播放服務器,支持RTSP/MP4轉RTMP。
- RTMP 發布服務器,支持錄制發布流。
- RTMP 播放器,支持RTMP代理,支持生成靜音音頻
- RTMP 推流客戶端。
- 支持http-flv直播。
- 支持https-flv直播。
- 支持任意編碼格式的rtmp推流,只是除H264/H265+AAC外無法轉協議
-
HLS
- 支持HLS文件生成,自帶HTTP文件服務器。
- 支持播放鑒權,鑒權結果可以緩存為cookie
-
HTTP[S]
- 服務器支持
目錄索引生成
,文件下載
,表單提交請求
。 - 客戶端提供
文件下載器(支持斷點續傳)
,接口請求器
,文件上傳器
。 - 完整HTTP API服務器,可以作為web后台開發框架。
- 支持跨域訪問。
- 支持http客戶端、服務器cookie
- 支持WebSocket服務器和客戶端
- 支持http文件訪問鑒權
- 服務器支持
-
其他
- 支持輸入YUV+PCM自動生成RTSP/RTMP/HLS/MP4.
- 支持簡單的telnet調試。
- 支持H264的解析,支持B幀的POC計算排序。
- 支持配置文件熱加載
- 支持流量統計、推流播放鑒權等事件
- 支持rtsp/rtmp/http虛擬主機
- 支持flv、mp4文件錄制
- 支持rtps/rtmp協議的mp4點播,支持seek
- 支持按需拉流,無人觀看自動關斷拉流
- 支持先拉流后推流,提高及時推流畫面打開率
- 支持rtsp/rtmp/http-flv/hls播放鑒權(url參數方式)
其他功能細節表
-
轉協議:
功能/編碼格式 H264 H265 AAC other RTSP[S] --> RTMP/HTTP[S]-FLV/FLV Y N Y N RTMP --> RTSP[S] Y N Y N RTSP[S] --> HLS Y Y Y N RTMP --> HLS Y N Y N RTSP[S] --> MP4 Y Y Y N RTMP --> MP4 Y N Y N MP4 --> RTSP[S] Y N Y N MP4 --> RTMP Y N Y N -
流生成:
功能/編碼格式 H264 H265 AAC other RTSP[S]推流 Y Y Y Y RTSP拉流代理 Y Y Y Y RTMP推流 Y Y Y Y RTMP拉流代理 Y Y Y Y -
RTP傳輸方式:
功能/RTP傳輸方式 tcp udp http udp_multicast RTSP[S] Play Server Y Y Y Y RTSP[S] Push Server Y Y N N RTSP Player Y Y N Y RTSP Pusher Y Y N N -
支持的服務器類型列表
服務類型 Y/N RTSP[S] Play Server Y RTSP[S] Push Server Y RTMP Y HTTP[S]/WebSocket[S] Y -
支持的客戶端類型
客戶端類型 Y/N RTSP Player Y RTSP Pusher Y RTMP Player Y RTMP Pusher Y HTTP[S] Y WebSocket[S] Y
后續任務
- 完善支持H265
編譯要求
- 編譯器支持C++11,GCC4.8/Clang3.3/VC2015或以上
- cmake3.2或以上
- 必須使用git下載完整的代碼,不要使用下載zip包的方式下載源碼,否則子模塊代碼默認不下載!你可以像以下這樣操作:
git clone https://github.com/zlmediakit/ZLMediaKit.git
cd ZLMediaKit
git submodule update --init
編譯(Linux)
-
我的編譯環境
- Ubuntu16.04 64 bit + gcc5.4
- cmake 3.5.1
-
編譯
//如果是centos6.x,需要先安裝較新版本的gcc以及cmake,然后打開腳本build_for_linux.sh手動編譯 //如果是ubuntu這樣的比較新的系統版本可以直接操作第4步 1、安裝GCC5.2(如果gcc版本高於4.7可以跳過此步驟) sudo yum install centos-release-scl -y sudo yum install devtoolset-4-toolchain -y scl enable devtoolset-4 bash 2、安裝cmake #需要安裝新版本cmake,當然你也可以通過yum或者apt-get方式安裝(前提是版本夠新) tar -xvf cmake-3.10.0-rc4.tar.gz cd cmake-3.10.0-rc4 ./configure make -j4 sudo make install 3、切換高版本gcc scl enable devtoolset-4 bash 4、編譯 cd ZLMediaKit ./build_for_linux.sh
編譯(macOS)
-
我的編譯環境
- macOS Sierra(10.12.1) + xcode8.3.1
- Homebrew 1.1.3
- cmake 3.8.0
-
編譯
cd ZLMediaKit ./build_for_mac.sh
編譯(iOS)
-
編譯環境:
請參考macOS的編譯指導。
-
編譯
cd ZLMediaKit ./build_for_ios.sh
-
你也可以生成Xcode工程再編譯:
cd ZLMediaKit mkdir -p build cd build # 生成Xcode工程,工程文件在build目錄下 cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/iOS.cmake -DIOS_PLATFORM=SIMULATOR64 -G "Xcode"
編譯(Android)
-
我的編譯環境
- macOS Sierra(10.12.1) + xcode8.3.1
- Homebrew 1.1.3
- cmake 3.8.0
- android-ndk-r14b
-
編譯
cd ZLMediaKit export ANDROID_NDK_ROOT=/path/to/ndk ./build_for_android.sh
編譯(Windows)
-
我的編譯環境
- windows 10
- visual studio 2017
- cmake-gui
-
編譯
1 進入ZLMediaKit目錄執行 git submodule update --init 以下載ZLToolKit的代碼
2 使用cmake-gui打開工程並生成vs工程文件.
3 找到工程文件(ZLMediaKit.sln),雙擊用vs2017打開.
4 選擇編譯Release 版本.
5 找到目標文件並運行測試用例.
使用方法
-
作為服務器:
TcpServer::Ptr rtspSrv(new TcpServer()); TcpServer::Ptr rtmpSrv(new TcpServer()); TcpServer::Ptr httpSrv(new TcpServer()); TcpServer::Ptr httpsSrv(new TcpServer()); rtspSrv->start<RtspSession>(mINI::Instance()[Config::Rtsp::kPort]); rtmpSrv->start<RtmpSession>(mINI::Instance()[Config::Rtmp::kPort]); httpSrv->start<HttpSession>(mINI::Instance()[Config::Http::kPort]); httpsSrv->start<HttpsSession>(mINI::Instance()[Config::Http::kSSLPort]);
-
作為播放器:
MediaPlayer::Ptr player(new MediaPlayer()); weak_ptr<MediaPlayer> weakPlayer = player; player->setOnPlayResult([weakPlayer](const SockException &ex) { InfoL << "OnPlayResult:" << ex.what(); auto strongPlayer = weakPlayer.lock(); if (ex || !strongPlayer) { return; } auto viedoTrack = strongPlayer->getTrack(TrackVideo); if (!viedoTrack) { WarnL << "沒有視頻Track!"; return; } viedoTrack->addDelegate(std::make_shared<FrameWriterInterfaceHelper>([](const Frame::Ptr &frame) { //此處解碼並播放 })); }); player->setOnShutdown([](const SockException &ex) { ErrorL << "OnShutdown:" << ex.what(); }); //支持rtmp、rtsp (*player)[Client::kRtpType] = Rtsp::RTP_TCP; player->play("rtsp://admin:jzan123456@192.168.0.122/");
-
作為代理服務器:
//support rtmp and rtsp url //just support H264+AAC auto urlList = {"rtmp://live.hkstv.hk.lxdns.com/live/hks", "rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov"}; map<string , PlayerProxy::Ptr> proxyMap; int i=0; for(auto url : urlList){ //PlayerProxy構造函數前兩個參數分別為應用名(app),流id(streamId) //比如說應用為live,流id為0,那么直播地址為: //http://127.0.0.1/live/0/hls.m3u8 //rtsp://127.0.0.1/live/0 //rtmp://127.0.0.1/live/0 //錄像地址為: //http://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4 //rtsp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4 //rtmp://127.0.0.1/record/live/0/2017-04-11/11-09-38.mp4 PlayerProxy::Ptr player(new PlayerProxy("live",to_string(i++).data())); player->play(url); proxyMap.emplace(string(url),player); }
-
作為推流客戶端器:
PlayerProxy::Ptr player(new PlayerProxy("app","stream")); //拉一個流,生成一個RtmpMediaSource,源的名稱是"app/stream" //你也可以以其他方式生成RtmpMediaSource,比如說MP4文件(請研讀MediaReader代碼) player->play("rtmp://live.hkstv.hk.lxdns.com/live/hks"); RtmpPusher::Ptr pusher; //監聽RtmpMediaSource注冊事件,在PlayerProxy播放成功后觸發。 NoticeCenter::Instance().addListener(nullptr,Config::Broadcast::kBroadcastRtmpSrcRegisted, [&pusher](BroadcastRtmpSrcRegistedArgs){ //媒體源"app/stream"已經注冊,這時方可新建一個RtmpPusher對象並綁定該媒體源 const_cast<RtmpPusher::Ptr &>(pusher).reset(new RtmpPusher(app,stream)); //推流地址,請改成你自己的服務器。 //這個范例地址(也是基於mediakit)是可用的,但是帶寬只有1mb,訪問可能很卡頓。 pusher->publish("rtmp://jizan.iok.la/live/test"); });
QA
-
怎么測試服務器性能?
ZLMediaKit提供了測試性能的示例,代碼在tests/test_benchmark.cpp。
這里是測試報告:benchmark.md
-
github下載太慢了,有其他下載方式嗎?
你可以在通過開源中國獲取最新的代碼,地址為:
-
在windows下編譯很多錯誤?
由於本項目主體代碼在macOS/linux下開發,部分源碼采用的是無bom頭的UTF-8編碼;由於windows對於utf-8支持不甚友好,所以如果發現編譯錯誤請先嘗試添 加bom頭再編譯。
也可以通過參考這篇博客解決:
vs2015:/utf-8選項解決UTF-8 without BOM 源碼中文輸出亂碼問題
參考案例
-
支持linux、windows、mac的rtmp/rtsp播放器
上述工程可能在最新的代碼的情況下編譯不過,請手動修改
授權協議
本項目自有代碼使用寬松的MIT協議,在保留版權信息的情況下可以自由應用於各自商用、非商業的項目。
但是本項目也零碎的使用了一些其他的開源代碼,在商用的情況下請自行替代或剔除;
由於使用本項目而產生的商業糾紛或侵權行為一概與本項項目及開發者無關,請自行承擔法律風險。
作者聯系方式
- 郵箱:771730766@qq.com(本項目相關或流媒體相關問題請走issue流程,否則恕不郵件答復)
- QQ群:542509000
我的微信公眾號(不是開源流媒體代碼的作者哦)