ZLMediaKit/README.md

415 lines
15 KiB
Markdown
Raw Normal View History

2020-01-07 15:16:01 +08:00
![logo](https://raw.githubusercontent.com/zlmediakit/ZLMediaKit/master/logo.png)
[english readme](https://github.com/xiongziliang/ZLMediaKit/blob/master/README_en.md)
2019-12-24 18:35:46 +08:00
# 一个基于C++11的高性能运营级流媒体服务框架
2020-01-07 15:16:01 +08:00
[![Build Status](https://travis-ci.org/xiongziliang/ZLMediaKit.svg?branch=master)](https://travis-ci.org/xiongziliang/ZLMediaKit)
2017-05-03 00:00:15 +08:00
2017-04-01 16:42:00 +08:00
2020-01-07 15:16:01 +08:00
## 国内用户请使用gitee镜像下载
```
git clone --depth 1 https://gitee.com/xiahcu/ZLMediaKit
cd ZLMediaKit
git submodule update --init
```
2019-12-24 18:35:46 +08:00
## 项目特点
- 基于C++11开发避免使用裸指针代码稳定可靠同时跨平台移植简单方便代码清晰简洁。
- 打包多种流媒体协议(RTSP/RTMP/HLS/HTTP-FLV/Websocket-FLV支持协议间的互相转换提供一站式的服务。
- 使用epoll+线程池+异步网络IO模式开发并发性能优越。
- 已实现主流的的H264/H265+AAC流媒体方案代码精简,脉络清晰,适合学习。
- 编码格式与框架代码解耦,方便自由简洁的添加支持其他编码格式。
- 代码经过大量的稳定性、性能测试,可满足商用服务器项目。
- 支持linux、macos、ios、android、windows平台。
- 支持画面秒开(GOP缓存)、极低延时([500毫秒内最低可达100毫秒](https://github.com/zlmediakit/ZLMediaKit/wiki/%E5%BB%B6%E6%97%B6%E6%B5%8B%E8%AF%95))。
- [ZLMediaKit高并发实现原理](https://github.com/xiongziliang/ZLMediaKit/wiki/ZLMediaKit%E9%AB%98%E5%B9%B6%E5%8F%91%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86)。
2019-12-25 11:33:31 +08:00
- 提供完善的标准[C API](https://github.com/xiongziliang/ZLMediaKit/tree/master/api/include),可以作SDK用或供其他语言调用。
- 提供完整的[MediaServer](https://github.com/xiongziliang/ZLMediaKit/tree/master/server)服务器,可以免开发直接部署为商用服务器。
2019-12-24 18:35:46 +08:00
## 项目定位
- 移动嵌入式跨平台流媒体解决方案。
- 商用级流媒体服务器。
- 网络编程二次开发SDK。
## 功能清单
2017-04-22 21:45:58 +08:00
- RTSP
2020-01-06 14:19:15 +08:00
- RTSP 服务器支持RTMP/MP4转RTSP
2019-12-24 18:35:46 +08:00
- RTSPS 服务器支持亚马逊echo show这样的设备
- RTSP 播放器支持RTSP代理支持生成静音音频
- RTSP 推流客户端与服务器
2020-01-06 14:19:15 +08:00
- 支持 `rtp over udp` `rtp over tcp` `rtp over http` `rtp组播` 四种RTP传输方式
- 服务器/客户端完整支持Basic/Digest方式的登录鉴权全异步可配置化的鉴权接口
2019-12-24 18:35:46 +08:00
- 支持H265编码
- 服务器支持RTSP推流(包括`rtp over udp` `rtp over tcp`方式)
- 支持任意编码格式的rtsp推流只是除H264/H265+AAC外无法转协议
2017-04-22 21:45:58 +08:00
- RTMP
2020-01-06 14:19:15 +08:00
- RTMP 播放服务器支持RTSP/MP4转RTMP
- RTMP 发布服务器,支持录制发布流
2019-12-24 18:35:46 +08:00
- RTMP 播放器支持RTMP代理支持生成静音音频
2020-01-06 14:19:15 +08:00
- RTMP 推流客户端
- 支持http[s]-flv直播
- 支持websocket-flv直播
2019-12-24 18:35:46 +08:00
- 支持任意编码格式的rtmp推流只是除H264/H265+AAC外无法转协议
2017-04-22 21:45:58 +08:00
- HLS
2020-01-06 14:19:15 +08:00
- 支持HLS文件生成自带HTTP文件服务器
- 通过cookie追踪技术可以模拟HLS播放为长连接实现丰富的业务逻辑
- 支持完备的HLS用户追踪、播放统计等业务功能可以实现HLS按需拉流等业务
2018-12-21 11:09:39 +08:00
2017-05-06 00:07:32 +08:00
- HTTP[S]
2020-01-06 14:19:15 +08:00
- 服务器支持`目录索引生成`,`文件下载`,`表单提交请求`
- 客户端提供`文件下载器(支持断点续传)`,`接口请求器`,`文件上传器`
- 完整HTTP API服务器可以作为web后台开发框架
- 支持跨域访问
2019-12-24 18:35:46 +08:00
- 支持http客户端、服务器cookie
- 支持WebSocket服务器和客户端
- 支持http文件访问鉴权
2020-01-06 14:19:15 +08:00
- GB28181
2020-01-06 14:23:23 +08:00
- 支持UDP/TCP国标RTP推流可以转换成RTSP/RTMP/HLS等协议
2020-01-06 14:19:15 +08:00
- 点播
- 支持录制为FLV/HLS/MP4
- RTSP/RTMP/HTTP-FLV/WS-FLV支持MP4文件点播支持seek
2019-12-24 18:35:46 +08:00
- 其他
2020-01-06 14:23:23 +08:00
- 支持丰富的restful api以及web hook事件
2020-01-06 14:19:15 +08:00
- 支持简单的telnet调试
2019-12-24 18:35:46 +08:00
- 支持配置文件热加载
2020-01-06 14:19:15 +08:00
- 支持流量统计、推拉流鉴权等事件
- 支持虚拟主机,可以隔离不同域名
2019-12-24 18:35:46 +08:00
- 支持按需拉流,无人观看自动关断拉流
- 支持先拉流后推流,提高及时推流画面打开率
2020-01-06 14:19:15 +08:00
- 提供c api sdk
2019-12-24 18:35:46 +08:00
## 其他功能细节表
- 转协议:
| 功能/编码格式 | 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++11GCC4.8/Clang3.3/VC2015或以上
- cmake3.2或以上
## 编译前必看!!!
- **必须使用git下载完整的代码不要使用下载zip包的方式下载源码否则子模块代码默认不下载你可以像以下这样操作:**
2019-08-20 09:45:21 +08:00
```
git clone https://github.com/zlmediakit/ZLMediaKit.git
cd ZLMediaKit
git submodule update --init
```
2019-06-25 18:46:47 +08:00
2019-12-24 18:35:46 +08:00
## 编译(Linux)
- 我的编译环境
- Ubuntu16.04 64 bit + gcc5.4
2017-05-03 00:00:15 +08:00
- cmake 3.5.1
2019-12-24 18:35:46 +08:00
- 编译
2017-05-03 00:16:53 +08:00
2017-05-11 23:20:31 +08:00
```
2019-12-24 18:35:46 +08:00
//如果是centos6.x,需要先安装较新版本的gcc以及cmake然后打开脚本build_for_linux.sh手动编译
//如果是ubuntu这样的比较新的系统版本可以直接操作第4步
1、安装GCC5.2(如果gcc版本高于4.7可以跳过此步骤)
2019-03-28 15:08:25 +08:00
sudo yum install centos-release-scl -y
2019-06-25 18:49:18 +08:00
sudo yum install devtoolset-4-toolchain -y
2019-03-28 15:08:25 +08:00
scl enable devtoolset-4 bash
2019-12-24 18:35:46 +08:00
2、安装cmake
#需要安装新版本cmake,当然你也可以通过yum或者apt-get方式安装(前提是版本够新)
tar -xvf cmake-3.10.0-rc4.tar.gz
2019-03-28 15:08:25 +08:00
cd cmake-3.10.0-rc4
./configure
make -j4
2019-06-25 18:49:18 +08:00
sudo make install
2019-12-24 18:35:46 +08:00
3、切换高版本gcc
2019-06-25 18:49:18 +08:00
scl enable devtoolset-4 bash
2019-12-24 18:35:46 +08:00
4、编译
2019-03-28 15:08:25 +08:00
cd ZLMediaKit
2019-06-25 18:50:01 +08:00
./build_for_linux.sh
2018-12-21 11:09:39 +08:00
```
2019-12-24 18:35:46 +08:00
## 编译(macOS)
- 我的编译环境
2017-05-11 23:20:31 +08:00
- macOS Sierra(10.12.1) + xcode8.3.1
- Homebrew 1.1.3
- cmake 3.8.0
2019-12-24 18:35:46 +08:00
- 编译
2017-05-03 00:16:53 +08:00
2017-05-11 23:20:31 +08:00
```
cd ZLMediaKit
./build_for_mac.sh
```
2018-12-21 11:09:39 +08:00
2019-12-24 18:35:46 +08:00
## 编译(iOS)
- 编译环境:`请参考macOS的编译指导。`
2020-02-05 23:34:51 +08:00
- 生成Xcode工程再编译,[了解更多](https://github.com/leetal/ios-cmake):
2017-05-11 23:20:31 +08:00
2017-05-03 00:00:15 +08:00
```
cd ZLMediaKit
mkdir -p build
cd build
2019-12-24 18:35:46 +08:00
# 生成Xcode工程工程文件在build目录下
2019-12-16 17:12:24 +08:00
cmake .. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../cmake/ios.toolchain.cmake -DPLATFORM=OS64COMBINED
2017-05-11 23:20:31 +08:00
```
2017-06-03 11:14:27 +08:00
2019-12-24 18:35:46 +08:00
## 编译(Android)
- 我的编译环境
2017-06-03 11:14:27 +08:00
- macOS Sierra(10.12.1) + xcode8.3.1
- Homebrew 1.1.3
- cmake 3.8.0
- [android-ndk-r14b](https://dl.google.com/android/repository/android-ndk-r14b-darwin-x86_64.zip)
2019-12-24 18:35:46 +08:00
- 编译
2017-04-22 21:45:58 +08:00
2017-06-03 11:14:27 +08:00
```
cd ZLMediaKit
export ANDROID_NDK_ROOT=/path/to/ndk
./build_for_android.sh
```
2019-12-24 18:35:46 +08:00
## 编译(Windows)
- 我的编译环境
2017-08-10 16:56:13 +08:00
- windows 10
- visual studio 2017
2017-10-09 11:06:59 +08:00
- [cmake-gui](https://cmake.org/files/v3.10/cmake-3.10.0-rc1-win32-x86.msi)
2017-08-10 16:56:13 +08:00
2019-12-24 18:35:46 +08:00
- 编译
2017-08-10 16:56:13 +08:00
```
2019-12-24 18:35:46 +08:00
1 进入ZLMediaKit目录执行 git submodule update --init 以下载ZLToolKit的代码
2 使用cmake-gui打开工程并生成vs工程文件.
  3 找到工程文件(ZLMediaKit.sln),双击用vs2017打开.
  4 选择编译Release 版本.
5 找到目标文件并运行测试用例.
2017-08-10 16:56:13 +08:00
```
2020-02-05 23:34:51 +08:00
## Docker Image
You can pull a pre-built docker image from Docker Hub and run with
```bash
docker run -id -p 1935:1935 -p 8080:80 gemfield/zlmediakit
```
Dockerfile is also supplied to build images on Ubuntu 16.04
```bash
cd docker
docker build -t zlmediakit .
```
2019-12-24 18:35:46 +08:00
## 使用方法
- 作为服务器:
2019-08-20 09:54:23 +08:00
```cpp
2018-02-23 15:36:51 +08:00
TcpServer::Ptr rtspSrv(new TcpServer());
TcpServer::Ptr rtmpSrv(new TcpServer());
TcpServer::Ptr httpSrv(new TcpServer());
TcpServer::Ptr httpsSrv(new TcpServer());
2017-06-05 17:53:58 +08:00
2018-02-23 15:36:51 +08:00
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]);
2017-06-05 18:08:31 +08:00
```
2017-06-05 17:53:58 +08:00
2019-12-24 18:35:46 +08:00
- 作为播放器:
2019-08-20 09:54:23 +08:00
```cpp
2018-10-29 14:09:29 +08:00
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) {
2019-12-24 18:35:46 +08:00
WarnL << "没有视频Track!";
2018-10-29 14:09:29 +08:00
return;
}
viedoTrack->addDelegate(std::make_shared<FrameWriterInterfaceHelper>([](const Frame::Ptr &frame) {
2019-12-24 18:35:46 +08:00
//此处解码并播放
2018-10-29 14:09:29 +08:00
}));
});
player->setOnShutdown([](const SockException &ex) {
ErrorL << "OnShutdown:" << ex.what();
});
2019-12-24 18:35:46 +08:00
//支持rtmp、rtsp
2019-04-01 16:11:32 +08:00
(*player)[Client::kRtpType] = Rtsp::RTP_TCP;
2018-10-29 14:09:29 +08:00
player->play("rtsp://admin:jzan123456@192.168.0.122/");
2017-06-05 18:08:31 +08:00
```
2019-12-24 18:35:46 +08:00
- 作为代理服务器:
2019-08-20 09:54:23 +08:00
```cpp
2017-06-05 18:08:31 +08:00
//support rtmp and rtsp url
2017-06-05 17:53:58 +08:00
//just support H264+AAC
auto urlList = {"rtmp://live.hkstv.hk.lxdns.com/live/hks",
"rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov"};
2017-06-05 18:13:49 +08:00
map<string , PlayerProxy::Ptr> proxyMap;
int i=0;
for(auto url : urlList){
2019-12-24 18:35:46 +08:00
//PlayerProxy构造函数前两个参数分别为应用名app,流idstreamId
//比如说应用为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
2017-06-05 18:13:49 +08:00
PlayerProxy::Ptr player(new PlayerProxy("live",to_string(i++).data()));
player->play(url);
proxyMap.emplace(string(url),player);
}
2017-06-05 18:08:31 +08:00
```
2017-06-06 20:15:08 +08:00
2019-12-24 18:35:46 +08:00
- 作为推流客户端器:
2019-08-20 09:54:23 +08:00
```cpp
2017-06-06 20:15:08 +08:00
PlayerProxy::Ptr player(new PlayerProxy("app","stream"));
2019-12-24 18:35:46 +08:00
//拉一个流生成一个RtmpMediaSource源的名称是"app/stream"
//你也可以以其他方式生成RtmpMediaSource比如说MP4文件请研读MediaReader代码
2017-06-06 20:15:08 +08:00
player->play("rtmp://live.hkstv.hk.lxdns.com/live/hks");
2019-12-24 18:35:46 +08:00
2017-06-06 20:15:08 +08:00
RtmpPusher::Ptr pusher;
2019-12-24 18:35:46 +08:00
//监听RtmpMediaSource注册事件,在PlayerProxy播放成功后触发。
2019-06-25 18:49:18 +08:00
NoticeCenter::Instance().addListener(nullptr,Config::Broadcast::kBroadcastRtmpSrcRegisted,
2017-06-06 20:15:08 +08:00
[&pusher](BroadcastRtmpSrcRegistedArgs){
2019-12-24 18:35:46 +08:00
//媒体源"app/stream"已经注册这时方可新建一个RtmpPusher对象并绑定该媒体源
2017-06-06 20:15:08 +08:00
const_cast<RtmpPusher::Ptr &>(pusher).reset(new RtmpPusher(app,stream));
2019-12-24 18:35:46 +08:00
//推流地址,请改成你自己的服务器。
//这个范例地址也是基于mediakit是可用的但是带宽只有1mb访问可能很卡顿。
2017-06-06 20:15:08 +08:00
pusher->publish("rtmp://jizan.iok.la/live/test");
});
2019-12-24 18:35:46 +08:00
2017-06-06 20:15:08 +08:00
```
2019-12-24 18:35:46 +08:00
## QA
- 怎么测试服务器性能?
2019-11-08 16:50:23 +08:00
2019-12-24 18:35:46 +08:00
ZLMediaKit提供了测试性能的示例代码在tests/test_benchmark.cpp。
2017-06-05 17:53:58 +08:00
2019-12-24 18:35:46 +08:00
这里是测试报告:[benchmark.md](https://github.com/xiongziliang/ZLMediaKit/blob/master/benchmark.md)
2018-12-21 11:09:39 +08:00
2019-12-24 18:35:46 +08:00
- github下载太慢了有其他下载方式吗
2018-12-21 11:09:39 +08:00
2019-12-24 18:35:46 +08:00
你可以在通过开源中国获取最新的代码,地址为:
2018-12-21 11:09:39 +08:00
2019-12-24 18:35:46 +08:00
[ZLToolKit](http://git.oschina.net/xiahcu/ZLToolKit)
2018-12-21 11:09:39 +08:00
2019-12-24 18:35:46 +08:00
[ZLMediaKit](http://git.oschina.net/xiahcu/ZLMediaKit)
2017-06-05 17:53:58 +08:00
2019-12-06 11:54:10 +08:00
2019-12-24 18:35:46 +08:00
- 在windows下编译很多错误
由于本项目主体代码在macOS/linux下开发部分源码采用的是无bom头的UTF-8编码由于windows对于utf-8支持不甚友好所以如果发现编译错误请先尝试添 加bom头再编译。
也可以通过参考这篇博客解决:
[vs2015:/utf-8选项解决UTF-8 without BOM 源码中文输出乱码问题](https://blog.csdn.net/10km/article/details/80203286)
## 参考案例
- [IOS摄像头实时录制,生成rtsp/rtmp/hls/http-flv](https://gitee.com/xiahcu/IOSMedia)
- [IOS rtmp/rtsp播放器视频推流器](https://gitee.com/xiahcu/IOSPlayer)
- [支持linux、windows、mac的rtmp/rtsp播放器](https://github.com/xiongziliang/ZLMediaPlayer)
上述工程可能在最新的代码的情况下编译不过,请手动修改
## 授权协议
本项目自有代码使用宽松的MIT协议在保留版权信息的情况下可以自由应用于各自商用、非商业的项目。
但是本项目也零碎的使用了一些其他的开源代码,在商用的情况下请自行替代或剔除;
由于使用本项目而产生的商业纠纷或侵权行为一概与本项项目及开发者无关,请自行承担法律风险。
## 联系方式
2020-01-07 15:16:01 +08:00
- 邮箱:<771730766@qq.com>(本项目相关或流媒体相关问题请走issue流程否则恕不邮件答复)
- QQ群542509000
2019-12-24 18:35:46 +08:00
## 怎么提问?
如果要对项目有相关疑问,建议您这么做:
- 1、仔细看下readme、wiki如果有必要可以查看下issue.
- 2、如果您的问题还没解决可以提issue.
- 3、有些问题如果不具备参考性的无需在issue提的可以在qq群提.
- 4、QQ私聊一般不接受无偿技术咨询和支持(谈谈人生理想还是可以的😂),毕竟精力有限,谢谢理解.
2020-01-09 10:06:30 +08:00
## 致谢
感谢以下各位对本项目包括但不限于代码贡献、问题反馈、资金捐赠等各种方式的支持!以下排名不分先后:
[老陈](https://github.com/ireader)
[Gemfield](https://github.com/gemfield)
[南冠彤](https://github.com/nanguantong2)
[凹凸慢](https://github.com/tsingeye)
[chenxiaolei](https://github.com/chenxiaolei)
[史前小虫](https://github.com/zqsong)
[清涩绿茶](https://github.com/baiyfcu)
[3503207480](https://github.com/3503207480)
[DroidChow](https://github.com/DroidChow)
[阿塞](https://github.com/HuoQiShuai)
[火宣](https://github.com/ChinaCCF)
[γ瑞γミ](https://github.com/JerryLinGd)
[linkingvision](https://www.linkingvision.com/)
[茄子](https://github.com/taotaobujue2008)
[好心情](<409257224@qq.com>)
2019-12-24 18:35:46 +08:00
2020-01-07 15:16:01 +08:00
## 捐赠
欢迎捐赠以便更好的推动项目的发展,谢谢您的支持!
[支付宝](https://raw.githubusercontent.com/xiongziliang/other/master/IMG_3919.JPG)
[微信](https://raw.githubusercontent.com/xiongziliang/other/master/IMG_3920.JPG)
2018-09-07 17:24:34 +08:00
2018-12-21 11:09:39 +08:00
2017-04-22 22:52:29 +08:00