ZLMediaKit/README.md
2017-10-10 00:07:49 +08:00

244 lines
8.3 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 一个基于C++11简单易用的轻量级流媒体库
平台|编译状态
----|-------
Linux | [![Build Status](https://travis-ci.org/xiongziliang/ZLMediaKit.svg?branch=master)](https://travis-ci.org/xiongziliang/ZLMediaKit)
macOS | [![Build Status](https://travis-ci.org/xiongziliang/ZLMediaKit_build_for_mac.svg?branch=master)](https://travis-ci.org/xiongziliang/ZLMediaKit_build_for_mac)
iOS | [![Build Status](https://travis-ci.org/xiongziliang/ZLMediaKit-build_for_ios.svg?branch=master)](https://travis-ci.org/xiongziliang/ZLMediaKit-build_for_ios)
Android | [![Build Status](https://travis-ci.org/xiongziliang/ZLMediaKit_build_for_android.svg?branch=master)](https://travis-ci.org/xiongziliang/ZLMediaKit_build_for_android)
Windows | 已经完成移植
## 项目特点
- 基于C++11开发避免使用裸指针代码稳定可靠同时跨平台移植简单方便代码清晰简洁。
- 打包多种流媒体协议(RTSP/RTMP/HLS支持协议间的互相转换提供一站式的服务。
- 使用epoll+线程池+异步网络IO模式开发并发性能优越。
- 只实现主流的的H264+AAC流媒体方案代码精简,脉络清晰,适合学习。
## 功能清单
- RTSP
- RTSP 服务器支持RTMP/MP4转RTSP。
- RTSP 播放器支持RTSP代理。
- 支持 `rtp over udp` `rtp over tcp` `rtp over http` `rtp组播` 四种RTP传输方式 。
- RTMP
- RTMP 播放服务器支持RTSP/MP4转RTMP。
- RTMP 发布服务器,支持录制发布流。
- RTMP 播放器支持RTMP代理。
- RTMP 推流客户端。
- HLS
- 支持HLS文件生成自带HTTP文件服务器。
- HTTP[S]
- 服务器支持`目录索引生成`,`文件下载`,`表单提交请求`。
- 客户端提供`文件下载器(支持断点续传)`,`接口请求器`。
- 其他
- 支持输入YUV+PCM自动生成RTSP/RTMP/HLS/MP4.
- 支持简单的telnet调试。
- 支持H264的解析支持B帧的POC计算排序。
## 后续任务
- 提供更多的示例代码
## 编译(Linux)
- 我的编译环境
- Ubuntu16.04 64 bit + gcc5.4(最低gcc4.7)
- cmake 3.5.1
- 编译
```
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](https://dl.google.com/android/repository/android-ndk-r14b-darwin-x86_64.zip)
- 编译
```
cd ZLMediaKit
export ANDROID_NDK_ROOT=/path/to/ndk
./build_for_android.sh
```
## 编译(Windows)
- 我的编译环境
- windows 10
- visual studio 2017
- [ZLToolKit](https://github.com/xiongziliang/ZLToolKit)
- [cmake-gui](https://cmake.org/files/v3.10/cmake-3.10.0-rc1-win32-x86.msi)
- 编译
```
  1 请先编译安装ZLToolKit
  2 使用cmake-gui打开工程并生成vs工程文件(配置时可能需要指定ZLTookKit的路径).
  3 找到工程文件(ZLMediaKit.sln),双击用vs2017打开.
  4 选择编译Release 版本.
  5 依次编译 ZLMediaKit_static、ZLMediaKit_shared、ALL_BUILD、INSTALL.
6 找到目标文件并运行测试用例.
  7 找到安装的头文件及库文件(在源码所在分区根目录).
```
## 使用方法
- 作为服务器:
```
TcpServer<RtspSession>::Ptr rtspSrv(new TcpServer<RtspSession>());
TcpServer<RtmpSession>::Ptr rtmpSrv(new TcpServer<RtmpSession>());
TcpServer<HttpSession>::Ptr httpSrv(new TcpServer<HttpSession>());
TcpServer<HttpsSession>::Ptr httpsSrv(new TcpServer<HttpsSession>());
rtspSrv->start(mINI::Instance()[Config::Rtsp::kPort]);
rtmpSrv->start(mINI::Instance()[Config::Rtmp::kPort]);
httpSrv->start(mINI::Instance()[Config::Http::kPort]);
httpsSrv->start(mINI::Instance()[Config::Http::kSSLPort]);
EventPoller::Instance().runLoop();
```
- 作为播放器:
```
MediaPlayer::Ptr player(new MediaPlayer());
player->setOnPlayResult([](const SockException &ex) {
InfoL << "OnPlayResult:" << ex.what();
});
player->setOnShutdown([](const SockException &ex) {
ErrorL << "OnShutdown:" << ex.what();
});
player->setOnVideoCB([&](const H264Frame &frame){
//在这里解码H264并显示
});
player->setOnAudioCB([&](const AdtsFrame &frame){
//在这里解码AAC并播放
});
//支持rtmp、rtsp
(*player)[RtspPlayer::kRtpType] = PlayerBase::RTP_TCP;
player->play("rtsp://admin:jzan123456@192.168.0.122/");
EventPoller::Instance().runLoop();
```
- 作为代理服务器:
```
//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,流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
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");
});
EventPoller::Instance().runLoop();
```
## QA
- 为什么VLC播放一段时间就停止了
由于ZLMediaKit在实现RTSP协议时采用OPTIONS命令作为心跳包在RTP over UDP时有效如果播放器不持续发送OPTIONS指令那么ZLMediaKit会断开连接。如果你要用第三方播放器测试你可以改RTP over TCP方式或者修改ZLMediaKit的源码修改位置位置为src/Rtsp/RtspSession.cpp RtspSession::onManager函数,修改成如下所示:
```
void RtspSession::onManager() {
if (m_ticker.createdTime() > 10 * 1000) {
if (m_strSession.size() == 0) {
WarnL << "非法链接:" << getPeerIp();
shutdown();
return;
}
if (m_bListenPeerUdpPort) {
UDPServer::Instance().stopListenPeer(getPeerIp().data(), this);
m_bListenPeerUdpPort = false;
}
}
/*if (m_rtpType != PlayerBase::RTP_TCP && m_ticker.elapsedTime() > 15 * 1000) {
WarnL << "RTSP会话超时:" << getPeerIp();
shutdown();
return;
/*}
}
```
- 怎么测试服务器性能
ZLMediaKit提供了测试性能的示例代码在tests/test_benchmark.cpp由于ZLToolKit默认关闭了tcp客户端多线程的支持如果需要提高测试并发量需要在编译ZLToolKit时启用ENABLE_ASNC_TCP_CLIENT宏具体操作如下
```
#编译ZLToolKit
cd ZLToolKit
mkdir -p build
cd build
cmake .. -DENABLE_ASNC_TCP_CLIENT
make -j4
sudo make install
```
- github下载太慢了有其他下载方式吗
你可以在通过开源中国获取最新的代码地址为
[ZLToolKit](http://git.oschina.net/xiahcu/ZLToolKit)
[ZLMediaKit](http://git.oschina.net/xiahcu/ZLMediaKit)
## 联系方式
- 邮箱<771730766@qq.com>
- QQ群542509000