Commit 0c9dd568 by lyg1949 Committed by GitHub

Merge pull request #1 from xiongziliang/master

获取zlmediakit的最新提交
parents 3d25ede4 e24adfe9
[submodule "ZLToolKit"] [submodule "ZLToolKit"]
path = 3rdpart/ZLToolKit path = 3rdpart/ZLToolKit
url = https://gitee.com/xiahcu/ZLToolKit url = ../ZLToolKit
[submodule "3rdpart/media-server"] [submodule "3rdpart/media-server"]
path = 3rdpart/media-server path = 3rdpart/media-server
url = https://gitee.com/xiahcu/media-server url = ../media-server
...@@ -128,7 +128,7 @@ It is recommended to compile on Ubuntu or MacOS,compiling on windows is cumber ...@@ -128,7 +128,7 @@ It is recommended to compile on Ubuntu or MacOS,compiling on windows is cumber
### Before build ### Before build
- **You must use git to clone the complete code. Do not download the source code by downloading zip package. Otherwise, the sub-module code will not be downloaded by default.You can do it like this:** - **You must use git to clone the complete code. Do not download the source code by downloading zip package. Otherwise, the sub-module code will not be downloaded by default.You can do it like this:**
``` ```
git clone https://github.com/zlmediakit/ZLMediaKit.git git clone https://github.com/xiongziliang/ZLMediaKit.git
cd ZLMediaKit cd ZLMediaKit
git submodule update --init git submodule update --init
``` ```
......
...@@ -98,16 +98,15 @@ API_EXPORT void API_CALL mk_media_input_h265(mk_media ctx, void *data, int len, ...@@ -98,16 +98,15 @@ API_EXPORT void API_CALL mk_media_input_h265(mk_media ctx, void *data, int len,
*/ */
API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, uint32_t dts, void *adts); API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, uint32_t dts, void *adts);
#ifdef ENABLE_FAAC
/** /**
* 输入单帧PCM音频 * 输入单帧PCM音频,启用ENABLE_FAAC编译时,该函数才有效
* @param ctx 对象指针 * @param ctx 对象指针
* @param data 单帧PCM数据 * @param data 单帧PCM数据
* @param len 单帧PCM数据字节数 * @param len 单帧PCM数据字节数
* @param dts 时间戳,毫秒 * @param dts 时间戳,毫秒
*/ */
API_EXPORT void API_CALL mk_media_input_PCM(mk_media ctx, void *Data, int len, uint32_t pts); API_EXPORT void API_CALL mk_media_input_pcm(mk_media ctx, void *data, int len, uint32_t pts);
#endif //ENABLE_FAAC
/** /**
* 输入单帧G711音频 * 输入单帧G711音频
* @param ctx 对象指针 * @param ctx 对象指针
......
...@@ -157,14 +157,15 @@ API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, u ...@@ -157,14 +157,15 @@ API_EXPORT void API_CALL mk_media_input_aac(mk_media ctx, void *data, int len, u
(*obj)->getChannel()->inputAAC((char *) data, len, dts, (char *) adts); (*obj)->getChannel()->inputAAC((char *) data, len, dts, (char *) adts);
} }
API_EXPORT void API_CALL mk_media_input_pcm(mk_media ctx, void *data , int len, uint32_t pts){
#ifdef ENABLE_FAAC #ifdef ENABLE_FAAC
API_EXPORT void API_CALL mk_media_input_PCM(mk_media ctx, void *data , int len, uint32_t pts)
{
assert(ctx && data && len > 0); assert(ctx && data && len > 0);
MediaHelper::Ptr* obj = (MediaHelper::Ptr*) ctx; MediaHelper::Ptr* obj = (MediaHelper::Ptr*) ctx;
(*obj)->getChannel()->inputPCM((char*)data, len, pts); (*obj)->getChannel()->inputPCM((char*)data, len, pts);
} #else
WarnL << "aac编码未启用,该方法无效,编译时请打开ENABLE_FAAC选项";
#endif //ENABLE_FAAC #endif //ENABLE_FAAC
}
API_EXPORT void API_CALL mk_media_input_g711(mk_media ctx, void* data, int len, uint32_t dts){ API_EXPORT void API_CALL mk_media_input_g711(mk_media ctx, void* data, int len, uint32_t dts){
assert(ctx && data && len > 0); assert(ctx && data && len > 0);
......
...@@ -122,6 +122,8 @@ rootPath=./www ...@@ -122,6 +122,8 @@ rootPath=./www
sendBufSize=65536 sendBufSize=65536
#https服务器监听端口 #https服务器监听端口
sslport=443 sslport=443
#是否显示文件夹菜单,开启后可以浏览文件夹
dirMenu=1
[multicast] [multicast]
#rtp组播截止组播ip地址 #rtp组播截止组播ip地址
......
...@@ -176,6 +176,8 @@ bool DtsGenerator::getDts_l(uint32_t pts, uint32_t &dts){ ...@@ -176,6 +176,8 @@ bool DtsGenerator::getDts_l(uint32_t pts, uint32_t &dts){
_sorter_max_size = _frames_since_last_max_pts; _sorter_max_size = _frames_since_last_max_pts;
//我们记录P帧间时间间隔(也就是多个B帧时间戳增量累计) //我们记录P帧间时间间隔(也就是多个B帧时间戳增量累计)
_dts_pts_offset = (pts - _last_max_pts); _dts_pts_offset = (pts - _last_max_pts);
//除以2,防止dts大于pts
_dts_pts_offset /= 2;
} }
//遇到P帧或关键帧,连续B帧计数清零 //遇到P帧或关键帧,连续B帧计数清零
_frames_since_last_max_pts = 0; _frames_since_last_max_pts = 0;
......
...@@ -100,11 +100,15 @@ const string kCharSet = HTTP_FIELD"charSet"; ...@@ -100,11 +100,15 @@ const string kCharSet = HTTP_FIELD"charSet";
const string kRootPath = HTTP_FIELD"rootPath"; const string kRootPath = HTTP_FIELD"rootPath";
//http 404错误提示内容 //http 404错误提示内容
const string kNotFound = HTTP_FIELD"notFound"; const string kNotFound = HTTP_FIELD"notFound";
//是否显示文件夹菜单
const string kDirMenu = HTTP_FIELD"dirMenu";
onceToken token([](){ onceToken token([](){
mINI::Instance()[kSendBufSize] = 64 * 1024; mINI::Instance()[kSendBufSize] = 64 * 1024;
mINI::Instance()[kMaxReqSize] = 4*1024; mINI::Instance()[kMaxReqSize] = 4*1024;
mINI::Instance()[kKeepAliveSecond] = 15; mINI::Instance()[kKeepAliveSecond] = 15;
mINI::Instance()[kDirMenu] = true;
#if defined(_WIN32) #if defined(_WIN32)
mINI::Instance()[kCharSet] = "gb2312"; mINI::Instance()[kCharSet] = "gb2312";
#else #else
......
...@@ -193,6 +193,8 @@ extern const string kCharSet; ...@@ -193,6 +193,8 @@ extern const string kCharSet;
extern const string kRootPath; extern const string kRootPath;
//http 404错误提示内容 //http 404错误提示内容
extern const string kNotFound; extern const string kNotFound;
//是否显示文件夹菜单
extern const string kDirMenu;
}//namespace Http }//namespace Http
////////////SHELL配置/////////// ////////////SHELL配置///////////
......
...@@ -138,14 +138,18 @@ public: ...@@ -138,14 +138,18 @@ public:
if (_cfg.empty()) { if (_cfg.empty()) {
//未获取到aac_cfg信息 //未获取到aac_cfg信息
if (frame->prefixSize()) { if (frame->prefixSize()) {
//7个字节的adts头 //根据7个字节的adts头生成aac config
_cfg = makeAacConfig((uint8_t *) (frame->data()), frame->prefixSize()); _cfg = makeAacConfig((uint8_t *) (frame->data()), frame->prefixSize());
onReady(); onReady();
} else { } else {
WarnL << "无法获取adts头!"; WarnL << "无法获取adts头!";
} }
} }
AudioTrack::inputFrame(frame);
if (frame->size() > frame->prefixSize()) {
//除adts头外,有实际负载
AudioTrack::inputFrame(frame);
}
} }
private: private:
/** /**
......
...@@ -32,8 +32,10 @@ static string getAacCfg(const RtmpPacket &thiz) { ...@@ -32,8 +32,10 @@ static string getAacCfg(const RtmpPacket &thiz) {
bool AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) { bool AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) {
if (pkt->isCfgFrame()) { if (pkt->isCfgFrame()) {
_aac_cfg = getAacCfg(*pkt); _aac_cfg = getAacCfg(*pkt);
onGetAAC(nullptr, 0, 0);
return false; return false;
} }
if (!_aac_cfg.empty()) { if (!_aac_cfg.empty()) {
onGetAAC(pkt->strBuf.data() + 2, pkt->strBuf.size() - 2, pkt->timeStamp); onGetAAC(pkt->strBuf.data() + 2, pkt->strBuf.size() - 2, pkt->timeStamp);
} }
...@@ -42,7 +44,6 @@ bool AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) { ...@@ -42,7 +44,6 @@ bool AACRtmpDecoder::inputRtmp(const RtmpPacket::Ptr &pkt, bool) {
void AACRtmpDecoder::onGetAAC(const char* data, int len, uint32_t stamp) { void AACRtmpDecoder::onGetAAC(const char* data, int len, uint32_t stamp) {
auto frame = ResourcePoolHelper<AACFrame>::obtainObj(); auto frame = ResourcePoolHelper<AACFrame>::obtainObj();
//生成adts头 //生成adts头
char adts_header[32] = {0}; char adts_header[32] = {0};
auto size = dumpAacConfig(_aac_cfg, len, (uint8_t *) adts_header, sizeof(adts_header)); auto size = dumpAacConfig(_aac_cfg, len, (uint8_t *) adts_header, sizeof(adts_header));
...@@ -54,12 +55,16 @@ void AACRtmpDecoder::onGetAAC(const char* data, int len, uint32_t stamp) { ...@@ -54,12 +55,16 @@ void AACRtmpDecoder::onGetAAC(const char* data, int len, uint32_t stamp) {
frame->_prefix_size = 0; frame->_prefix_size = 0;
} }
//追加负载数据 if(len > 0){
frame->_buffer.append(data, len); //追加负载数据
frame->_dts = stamp; frame->_buffer.append(data, len);
frame->_dts = stamp;
}
//写入环形缓存 if(size > 0 || len > 0){
RtmpCodec::inputFrame(frame); //有adts头或者实际aac负载
RtmpCodec::inputFrame(frame);
}
} }
///////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////
......
...@@ -243,9 +243,8 @@ RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track, bool is_enc ...@@ -243,9 +243,8 @@ RtmpCodec::Ptr Factory::getRtmpCodecByTrack(const Track::Ptr &track, bool is_enc
AMFValue Factory::getAmfByCodecId(CodecId codecId) { AMFValue Factory::getAmfByCodecId(CodecId codecId) {
switch (codecId){ switch (codecId){
//此处用string标明rtmp编码类型目的是为了兼容某些android系统 case CodecAAC: return AMFValue(FLV_CODEC_AAC);
case CodecAAC: return AMFValue("mp4a"); case CodecH264: return AMFValue(FLV_CODEC_H264);
case CodecH264: return AMFValue("avc1");
case CodecH265: return AMFValue(FLV_CODEC_H265); case CodecH265: return AMFValue(FLV_CODEC_H265);
case CodecG711A: return AMFValue(FLV_CODEC_G711A); case CodecG711A: return AMFValue(FLV_CODEC_G711A);
case CodecG711U: return AMFValue(FLV_CODEC_G711U); case CodecG711U: return AMFValue(FLV_CODEC_G711U);
......
...@@ -195,6 +195,11 @@ static string searchIndexFile(const string &dir){ ...@@ -195,6 +195,11 @@ static string searchIndexFile(const string &dir){
} }
static bool makeFolderMenu(const string &httpPath, const string &strFullPath, string &strRet) { static bool makeFolderMenu(const string &httpPath, const string &strFullPath, string &strRet) {
GET_CONFIG(bool, dirMenu, Http::kDirMenu);
if(!dirMenu){
//不允许浏览文件夹
return false;
}
string strPathPrefix(strFullPath); string strPathPrefix(strFullPath);
string last_dir_name; string last_dir_name;
if(strPathPrefix.back() == '/'){ if(strPathPrefix.back() == '/'){
......
...@@ -257,8 +257,8 @@ void RtmpSession::sendPlayResponse(const string &err,const RtmpMediaSource::Ptr ...@@ -257,8 +257,8 @@ void RtmpSession::sendPlayResponse(const string &err,const RtmpMediaSource::Ptr
invoke.clear(); invoke.clear();
invoke << "onMetaData" << metadata; invoke << "onMetaData" << metadata;
sendResponse(MSG_DATA, invoke.data()); sendResponse(MSG_DATA, invoke.data());
auto duration = metadata["duration"].as_number(); auto duration = metadata["duration"];
if(duration > 0){ if(duration && duration.as_number() > 0){
//这是点播,使用绝对时间戳 //这是点播,使用绝对时间戳
_stamp[0].setPlayBack(); _stamp[0].setPlayBack();
_stamp[1].setPlayBack(); _stamp[1].setPlayBack();
......
...@@ -158,6 +158,11 @@ void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t d ...@@ -158,6 +158,11 @@ void DecoderImp::onDecode(int stream,int codecid,int flags,int64_t pts,int64_t d
} }
case PSI_STREAM_AAC: { case PSI_STREAM_AAC: {
uint8_t *ptr = (uint8_t *)data;
if(!(bytes > 7 && ptr[0] == 0xFF && (ptr[1] & 0xF0) == 0xF0)){
//这不是aac
break;
}
if (!_codecid_audio) { if (!_codecid_audio) {
//获取到音频 //获取到音频
_codecid_audio = codecid; _codecid_audio = codecid;
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <stdint.h> #include <stdint.h>
#include <memory> #include <memory>
#include <functional> #include <functional>
#include "Decoder.h"
#include "Common/MediaSink.h" #include "Common/MediaSink.h"
using namespace std; using namespace std;
......
...@@ -73,11 +73,6 @@ RtpProcess::RtpProcess(uint32_t ssrc) { ...@@ -73,11 +73,6 @@ RtpProcess::RtpProcess(uint32_t ssrc) {
} }
RtpProcess::~RtpProcess() { RtpProcess::~RtpProcess() {
DebugP(this);
if (_addr) {
delete _addr;
}
uint64_t duration = (_last_rtp_time.createdTime() - _last_rtp_time.elapsedTime()) / 1000; uint64_t duration = (_last_rtp_time.createdTime() - _last_rtp_time.elapsedTime()) / 1000;
WarnP(this) << "RTP推流器(" WarnP(this) << "RTP推流器("
<< _media_info._vhost << "/" << _media_info._vhost << "/"
...@@ -90,6 +85,11 @@ RtpProcess::~RtpProcess() { ...@@ -90,6 +85,11 @@ RtpProcess::~RtpProcess() {
if (_total_bytes > iFlowThreshold * 1024) { if (_total_bytes > iFlowThreshold * 1024) {
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport, _media_info, _total_bytes, duration, false, static_cast<SockInfo &>(*this)); NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport, _media_info, _total_bytes, duration, false, static_cast<SockInfo &>(*this));
} }
if (_addr) {
delete _addr;
_addr = nullptr;
}
} }
bool RtpProcess::inputRtp(const Socket::Ptr &sock, const char *data, int data_len,const struct sockaddr *addr,uint32_t *dts_out) { bool RtpProcess::inputRtp(const Socket::Ptr &sock, const char *data, int data_len,const struct sockaddr *addr,uint32_t *dts_out) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论