From a100ee0acd9190fa35822422825c31a189593c12 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Tue, 28 May 2019 17:14:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=85=A8=E5=B1=80=E7=9A=84?= =?UTF-8?q?=E7=A6=81=E7=94=A8=E8=99=9A=E6=8B=9F=E4=B8=BB=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Android/app/src/main/cpp/test_server.cpp | 2 +- server/WebApi.cpp | 4 +- server/WebHook.cpp | 26 ++++++------- src/Common/MediaSource.cpp | 16 +++++++- src/Common/config.cpp | 20 +++++----- src/Common/config.h | 49 ++++++++++++------------ src/Http/HttpSession.cpp | 36 ++++++++--------- src/Http/HttpSession.h | 29 +++++++------- src/MediaFile/MediaReader.cpp | 13 +++++-- src/MediaFile/MediaRecorder.cpp | 30 ++++++++++----- src/MediaFile/Mp4Maker.cpp | 28 +++++++++----- src/Rtmp/RtmpMediaSource.h | 5 ++- src/Rtmp/RtmpSession.cpp | 4 +- src/Rtsp/RtpBroadCaster.cpp | 6 +-- src/Rtsp/RtpReceiver.cpp | 4 +- src/Rtsp/RtspMediaSource.h | 5 ++- src/Rtsp/RtspSession.cpp | 6 +-- src/RtspMuxer/AACRtpCodec.cpp | 2 +- src/RtspMuxer/H264RtpCodec.cpp | 2 +- src/RtspMuxer/H265RtpCodec.cpp | 2 +- src/RtspMuxer/RtspMuxer.cpp | 4 +- src/Shell/ShellSession.cpp | 2 +- tests/test_server.cpp | 2 +- 23 files changed, 173 insertions(+), 124 deletions(-) diff --git a/Android/app/src/main/cpp/test_server.cpp b/Android/app/src/main/cpp/test_server.cpp index 7a8fe993..05fb596d 100644 --- a/Android/app/src/main/cpp/test_server.cpp +++ b/Android/app/src/main/cpp/test_server.cpp @@ -174,7 +174,7 @@ static onceToken s_token([](){ lock_guard lck(s_mtxFlvRecorder); if(bRegist){ DebugL << "开始录制RTMP:" << schema << " " << vhost << " " << app << " " << stream; - GET_CONFIG_AND_REGISTER(string,http_root,Http::kRootPath); + GET_CONFIG(string,http_root,Http::kRootPath); auto path = http_root + "/" + vhost + "/" + app + "/" + stream + "_" + to_string(time(NULL)) + ".flv"; FlvRecorder::Ptr recorder(new FlvRecorder); try{ diff --git a/server/WebApi.cpp b/server/WebApi.cpp index 956a194c..907e2694 100644 --- a/server/WebApi.cpp +++ b/server/WebApi.cpp @@ -127,7 +127,7 @@ static ApiArgsType getAllArgs(const Parser &parser) { } static inline void addHttpListener(){ - GET_CONFIG_AND_REGISTER(bool, api_debug, API::kApiDebug); + GET_CONFIG(bool, api_debug, API::kApiDebug); //注册监听kBroadcastHttpRequest事件 NoticeCenter::Instance().addListener(nullptr, Broadcast::kBroadcastHttpRequest, [](BroadcastHttpRequestArgs) { auto it = s_map_api.find(parser.Url()); @@ -224,7 +224,7 @@ static inline string getProxyKey(const string &vhost,const string &app,const str void installWebApi() { addHttpListener(); - GET_CONFIG_AND_REGISTER(string,api_secret,API::kSecret); + GET_CONFIG(string,api_secret,API::kSecret); //获取线程负载 //测试url http://127.0.0.1/index/api/getThreadsLoad diff --git a/server/WebHook.cpp b/server/WebHook.cpp index 59a271e9..abfa7df1 100644 --- a/server/WebHook.cpp +++ b/server/WebHook.cpp @@ -111,7 +111,7 @@ const char *getContentType(const HttpArgs &value){ } static void do_http_hook(const string &url,const ArgsType &body,const function &fun){ - GET_CONFIG_AND_REGISTER(float,hook_timeoutSec,Hook::kTimeoutSec); + GET_CONFIG(float,hook_timeoutSec,Hook::kTimeoutSec); HttpRequester::Ptr requester(new HttpRequester); requester->setMethod("POST"); auto bodyStr = to_string(body); @@ -150,18 +150,18 @@ static ArgsType make_json(const MediaInfo &args){ void installWebHook(){ - GET_CONFIG_AND_REGISTER(bool,hook_enable,Hook::kEnable); - GET_CONFIG_AND_REGISTER(string,hook_publish,Hook::kOnPublish); - GET_CONFIG_AND_REGISTER(string,hook_play,Hook::kOnPlay); - GET_CONFIG_AND_REGISTER(string,hook_flowreport,Hook::kOnFlowReport); - GET_CONFIG_AND_REGISTER(string,hook_adminparams,Hook::kAdminParams); - GET_CONFIG_AND_REGISTER(string,hook_rtsp_realm,Hook::kOnRtspRealm); - GET_CONFIG_AND_REGISTER(string,hook_rtsp_auth,Hook::kOnRtspAuth); - GET_CONFIG_AND_REGISTER(string,hook_stream_chaned,Hook::kOnStreamChanged); - GET_CONFIG_AND_REGISTER(string,hook_stream_not_found,Hook::kOnStreamNotFound); - GET_CONFIG_AND_REGISTER(string,hook_record_mp4,Hook::kOnRecordMp4); - GET_CONFIG_AND_REGISTER(string,hook_shell_login,Hook::kOnShellLogin); - GET_CONFIG_AND_REGISTER(string,hook_stream_none_reader,Hook::kOnStreamNoneReader); + GET_CONFIG(bool,hook_enable,Hook::kEnable); + GET_CONFIG(string,hook_publish,Hook::kOnPublish); + GET_CONFIG(string,hook_play,Hook::kOnPlay); + GET_CONFIG(string,hook_flowreport,Hook::kOnFlowReport); + GET_CONFIG(string,hook_adminparams,Hook::kAdminParams); + GET_CONFIG(string,hook_rtsp_realm,Hook::kOnRtspRealm); + GET_CONFIG(string,hook_rtsp_auth,Hook::kOnRtspAuth); + GET_CONFIG(string,hook_stream_chaned,Hook::kOnStreamChanged); + GET_CONFIG(string,hook_stream_not_found,Hook::kOnStreamNotFound); + GET_CONFIG(string,hook_record_mp4,Hook::kOnRecordMp4); + GET_CONFIG(string,hook_shell_login,Hook::kOnShellLogin); + GET_CONFIG(string,hook_stream_none_reader,Hook::kOnStreamNoneReader); NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastMediaPublish,[](BroadcastMediaPublishArgs){ if(!hook_enable || args._param_strs == hook_adminparams || hook_publish.empty()){ diff --git a/src/Common/MediaSource.cpp b/src/Common/MediaSource.cpp index 0313118a..0c48cfc3 100644 --- a/src/Common/MediaSource.cpp +++ b/src/Common/MediaSource.cpp @@ -61,7 +61,7 @@ void MediaSource::findAsync(const MediaInfo &info, NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastNotFoundStream,info,*session); //最多等待一定时间,如果这个时间内,流未注册上,那么返回未找到流 - GET_CONFIG_AND_REGISTER(int,maxWaitMS,Broadcast::kMaxStreamWaitTimeMS); + GET_CONFIG(int,maxWaitMS,General::kMaxStreamWaitTimeMS); //若干秒后执行等待媒体注册超时回调 auto onRegistTimeout = session->getPoller()->doDelayTask(maxWaitMS,[cb,listener_tag](){ @@ -112,6 +112,12 @@ MediaSource::Ptr MediaSource::find( if(vhost.empty()){ vhost = DEFAULT_VHOST; } + + GET_CONFIG(bool,enableVhost,General::kEnableVhost); + if(!enableVhost){ + vhost = DEFAULT_VHOST; + } + lock_guard lock(g_mtxMediaSrc); MediaSource::Ptr ret; searchMedia(schema, vhost, app, id, @@ -135,6 +141,10 @@ MediaSource::Ptr MediaSource::find( return ret; } void MediaSource::regist() { + GET_CONFIG(bool,enableVhost,General::kEnableVhost); + if(!enableVhost){ + _strVhost = DEFAULT_VHOST; + } //注册该源,注册后服务器才能找到该源 { lock_guard lock(g_mtxMediaSrc); @@ -229,6 +239,10 @@ void MediaInfo::parse(const string &url){ _vhost = DEFAULT_VHOST; } } + GET_CONFIG(bool,enableVhost,General::kEnableVhost); + if(!enableVhost){ + _vhost = DEFAULT_VHOST; + } } diff --git a/src/Common/config.cpp b/src/Common/config.cpp index 9ba8c38a..58d4eb05 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -66,17 +66,23 @@ const char kBroadcastReloadConfig[] = "kBroadcastReloadConfig"; const char kBroadcastShellLogin[] = "kBroadcastShellLogin"; const char kBroadcastNotFoundStream[] = "kBroadcastNotFoundStream"; const char kBroadcastStreamNoneReader[] = "kBroadcastStreamNoneReader"; +} //namespace Broadcast -const char kFlowThreshold[] = "broadcast.flowThreshold"; -const char kStreamNoneReaderDelayMS[] = "broadcast.streamNoneReaderDelayMS"; -const char kMaxStreamWaitTimeMS[] = "kMaxStreamWaitTimeMS"; - +//通用配置项目 +namespace General{ +#define GENERAL_FIELD "general." +const char kFlowThreshold[] = GENERAL_FIELD"flowThreshold"; +const char kStreamNoneReaderDelayMS[] = GENERAL_FIELD"streamNoneReaderDelayMS"; +const char kMaxStreamWaitTimeMS[] = GENERAL_FIELD"maxStreamWaitMS"; +const char kEnableVhost[] = GENERAL_FIELD"enableVhost"; onceToken token([](){ mINI::Instance()[kFlowThreshold] = 1024; mINI::Instance()[kStreamNoneReaderDelayMS] = 5 * 1000; mINI::Instance()[kMaxStreamWaitTimeMS] = 5 * 1000; + mINI::Instance()[kEnableVhost] = 1; },nullptr); -} //namespace Broadcast + +}//namespace General ////////////HTTP配置/////////// namespace Http { @@ -98,9 +104,6 @@ const char kKeepAliveSecond[] = HTTP_FIELD"keepAliveSecond"; #define HTTP_MAX_REQ_CNT 100 const char kMaxReqCount[] = HTTP_FIELD"maxReqCount"; -//文件服务器是否启动虚拟主机 -const char kEnableVhost[] = HTTP_FIELD"enableVhost"; - //http 字符编码 #if defined(_WIN32) @@ -135,7 +138,6 @@ onceToken token([](){ mINI::Instance()[kCharSet] = HTTP_CHAR_SET; mINI::Instance()[kRootPath] = HTTP_ROOT_PATH; mINI::Instance()[kNotFound] = HTTP_NOT_FOUND; - mINI::Instance()[kEnableVhost] = 1; },nullptr); }//namespace Http diff --git a/src/Common/config.h b/src/Common/config.h index a96878cd..028b34ee 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -96,10 +96,6 @@ typedef std::function AuthInvoker; extern const char kBroadcastMediaPublish[]; #define BroadcastMediaPublishArgs const MediaInfo &args,const Broadcast::AuthInvoker &invoker,TcpSession &sender -//兼容旧代码的宏 -#define BroadcastRtmpPublishArgs BroadcastMediaPublishArgs -#define kBroadcastRtmpPublish kBroadcastMediaPublish - //播放rtsp/rtmp/http-flv事件广播,通过该事件控制播放鉴权 extern const char kBroadcastMediaPlayed[]; #define BroadcastMediaPlayedArgs const MediaInfo &args,const Broadcast::AuthInvoker &invoker,TcpSession &sender @@ -120,24 +116,11 @@ extern const char kBroadcastNotFoundStream[]; extern const char kBroadcastStreamNoneReader[]; #define BroadcastStreamNoneReaderArgs MediaSource &sender -//流量汇报事件流量阈值,单位KB,默认1MB -extern const char kFlowThreshold[]; - -//流无人观看并且超过若干时间后才触发kBroadcastStreamNoneReader事件 -//默认连续5秒无人观看然后触发kBroadcastStreamNoneReader事件 -extern const char kStreamNoneReaderDelayMS[]; - -//等待流注册超时时间,收到播放器后请求后,如果未找到相关流,服务器会等待一定时间, -//如果在这个时间内,相关流注册上了,那么服务器会立即响应播放器播放成功, -//否则会最多等待kMaxStreamWaitTimeMS毫秒,然后响应播放器播放失败 -extern const char kMaxStreamWaitTimeMS[]; - //更新配置文件事件广播,执行loadIniConfig函数加载配置文件成功后会触发该广播 extern const char kBroadcastReloadConfig[]; - #define BroadcastReloadConfigArgs void -#define ReloadConfigTag ((void *)(0xFF)) +#define ReloadConfigTag ((void *)(0xFF)) #define RELOAD_KEY(arg,key) \ do{ \ decltype(arg) arg##tmp = mINI::Instance()[key]; \ @@ -148,7 +131,7 @@ extern const char kBroadcastReloadConfig[]; }while(0); //监听某个配置发送变更 -#define RELOAD_KEY_REGISTER(arg,key) \ +#define LISTEN_RELOAD_KEY(arg,key) \ do{ \ static onceToken s_token([](){ \ NoticeCenter::Instance().addListener(ReloadConfigTag,Broadcast::kBroadcastReloadConfig,[](BroadcastReloadConfigArgs){ \ @@ -157,12 +140,33 @@ extern const char kBroadcastReloadConfig[]; }); \ }while(0); -#define GET_CONFIG_AND_REGISTER(type,arg,key) \ +#define GET_CONFIG(type,arg,key) \ static type arg = mINI::Instance()[key]; \ - RELOAD_KEY_REGISTER(arg,key); + LISTEN_RELOAD_KEY(arg,key); + +//兼容老代码 +#define GET_CONFIG_AND_REGISTER GET_CONFIG +#define BroadcastRtmpPublishArgs BroadcastMediaPublishArgs +#define kBroadcastRtmpPublish kBroadcastMediaPublish } //namespace Broadcast +////////////通用配置/////////// +namespace General{ +//流量汇报事件流量阈值,单位KB,默认1MB +extern const char kFlowThreshold[]; +//流无人观看并且超过若干时间后才触发kBroadcastStreamNoneReader事件 +//默认连续5秒无人观看然后触发kBroadcastStreamNoneReader事件 +extern const char kStreamNoneReaderDelayMS[]; +//等待流注册超时时间,收到播放器后请求后,如果未找到相关流,服务器会等待一定时间, +//如果在这个时间内,相关流注册上了,那么服务器会立即响应播放器播放成功, +//否则会最多等待kMaxStreamWaitTimeMS毫秒,然后响应播放器播放失败 +extern const char kMaxStreamWaitTimeMS[]; +//是否启动虚拟主机 +extern const char kEnableVhost[]; +}//namespace General + + ////////////HTTP配置/////////// namespace Http { //http 文件发送缓存大小 @@ -179,9 +183,6 @@ extern const char kCharSet[]; extern const char kRootPath[]; //http 404错误提示内容 extern const char kNotFound[]; -//文件服务器是否启动虚拟主机 -extern const char kEnableVhost[]; - }//namespace Http ////////////SHELL配置/////////// diff --git a/src/Http/HttpSession.cpp b/src/Http/HttpSession.cpp index ce73239d..b0b481b0 100644 --- a/src/Http/HttpSession.cpp +++ b/src/Http/HttpSession.cpp @@ -157,7 +157,7 @@ void HttpSession::onRecv(const Buffer::Ptr &pBuf) { void HttpSession::onError(const SockException& err) { //WarnL << err.what(); - GET_CONFIG_AND_REGISTER(uint32_t,iFlowThreshold,Broadcast::kFlowThreshold); + GET_CONFIG(uint32_t,iFlowThreshold,General::kFlowThreshold); if(_ui64TotalBytes > iFlowThreshold * 1024){ NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport, @@ -170,7 +170,7 @@ void HttpSession::onError(const SockException& err) { } void HttpSession::onManager() { - GET_CONFIG_AND_REGISTER(uint32_t,keepAliveSec,Http::kKeepAliveSecond); + GET_CONFIG(uint32_t,keepAliveSec,Http::kKeepAliveSecond); if(_ticker.elapsedTime() > keepAliveSec * 1000){ //1分钟超时 @@ -218,7 +218,7 @@ inline bool HttpSession::checkLiveFlvStream(){ } _mediaInfo._streamid.erase(_mediaInfo._streamid.size() - 4);//去除.flv后缀 - GET_CONFIG_AND_REGISTER(uint32_t,reqCnt,Http::kMaxReqCount); + GET_CONFIG(uint32_t,reqCnt,Http::kMaxReqCount); bool bClose = (strcasecmp(_parser["Connection"].data(),"close") == 0) || ( ++_iReqCnt > reqCnt); weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); @@ -285,7 +285,7 @@ inline bool HttpSession::checkLiveFlvStream(){ return true; } -inline bool makeMeun(const string &httpPath,const string &strFullPath,const string &vhost, string &strRet) ; +inline bool makeMeun(const string &httpPath,const string &strFullPath, string &strRet) ; inline static string findIndexFile(const string &dir){ DIR *pDir; @@ -334,9 +334,9 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) { _mediaInfo.parse(fullUrl); /////////////HTTP连接是否需要被关闭//////////////// - GET_CONFIG_AND_REGISTER(uint32_t,reqCnt,Http::kMaxReqCount); - GET_CONFIG_AND_REGISTER(bool,enableVhost,Http::kEnableVhost); - GET_CONFIG_AND_REGISTER(string,rootPath,Http::kRootPath); + GET_CONFIG(uint32_t,reqCnt,Http::kMaxReqCount); + GET_CONFIG(bool,enableVhost,General::kEnableVhost); + GET_CONFIG(string,rootPath,Http::kRootPath); string strFile = enableVhost ? rootPath + "/" + _mediaInfo._vhost + _parser.Url() :rootPath + _parser.Url(); bool bClose = (strcasecmp(_parser["Connection"].data(),"close") == 0) || ( ++_iReqCnt > reqCnt); @@ -351,7 +351,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) { } //生成文件夹菜单索引 string strMeun; - if (!makeMeun(_parser.Url(),strFile,_mediaInfo._vhost, strMeun)) { + if (!makeMeun(_parser.Url(),strFile,strMeun)) { //文件夹不存在 sendNotFound(bClose); return !bClose; @@ -417,7 +417,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) { //回复Content部分 std::shared_ptr piLeft(new int64_t(iRangeEnd - iRangeStart + 1)); - GET_CONFIG_AND_REGISTER(uint32_t,sendBufSize,Http::kSendBufSize); + GET_CONFIG(uint32_t,sendBufSize,Http::kSendBufSize); weak_ptr weakSelf = dynamic_pointer_cast(shared_from_this()); auto onFlush = [pFilePtr,bClose,weakSelf,piLeft]() { @@ -477,7 +477,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) { return true; } -inline bool makeMeun(const string &httpPath,const string &strFullPath,const string &vhost, string &strRet) { +inline bool makeMeun(const string &httpPath,const string &strFullPath, string &strRet) { string strPathPrefix(strFullPath); string last_dir_name; if(strPathPrefix.back() == '/'){ @@ -589,9 +589,9 @@ inline void HttpSession::sendResponse(const char* pcStatus, const KeyValue& head } inline HttpSession::KeyValue HttpSession::makeHttpHeader(bool bClose, int64_t iContentSize,const char* pcContentType) { KeyValue headerOut; - GET_CONFIG_AND_REGISTER(string,charSet,Http::kCharSet); - GET_CONFIG_AND_REGISTER(uint32_t,keepAliveSec,Http::kKeepAliveSecond); - GET_CONFIG_AND_REGISTER(uint32_t,reqCnt,Http::kMaxReqCount); + GET_CONFIG(string,charSet,Http::kCharSet); + GET_CONFIG(uint32_t,keepAliveSec,Http::kKeepAliveSecond); + GET_CONFIG(uint32_t,reqCnt,Http::kMaxReqCount); headerOut.emplace("Date", dateStr()); headerOut.emplace("Server", SERVER_NAME); @@ -612,7 +612,7 @@ inline HttpSession::KeyValue HttpSession::makeHttpHeader(bool bClose, int64_t iC string HttpSession::urlDecode(const string &str){ auto ret = strCoding::UrlDecode(str); #ifdef _WIN32 - GET_CONFIG_AND_REGISTER(string,charSet,Http::kCharSet); + GET_CONFIG(string,charSet,Http::kCharSet); bool isGb2312 = !strcasecmp(charSet.data(), "gb2312"); if (isGb2312) { ret = strCoding::UTF8ToGB2312(ret); @@ -630,7 +630,7 @@ inline void HttpSession::urlDecode(Parser &parser){ inline bool HttpSession::emitHttpEvent(bool doInvoke){ ///////////////////是否断开本链接/////////////////////// - GET_CONFIG_AND_REGISTER(uint32_t,reqCnt,Http::kMaxReqCount); + GET_CONFIG(uint32_t,reqCnt,Http::kMaxReqCount); bool bClose = (strcasecmp(_parser["Connection"].data(),"close") == 0) || ( ++_iReqCnt > reqCnt); auto Origin = _parser["Origin"]; @@ -666,8 +666,8 @@ inline bool HttpSession::emitHttpEvent(bool doInvoke){ return consumed; } inline bool HttpSession::Handle_Req_POST(int64_t &content_len) { - GET_CONFIG_AND_REGISTER(uint64_t,maxReqSize,Http::kMaxReqSize); - GET_CONFIG_AND_REGISTER(int,maxReqCnt,Http::kMaxReqCount); + GET_CONFIG(uint64_t,maxReqSize,Http::kMaxReqSize); + GET_CONFIG(int,maxReqCnt,Http::kMaxReqCount); int64_t totalContentLen = _parser["Content-Length"].empty() ? -1 : atoll(_parser["Content-Length"].data()); @@ -754,7 +754,7 @@ void HttpSession::responseDelay(const string &Origin,bool bClose, sendResponse(codeOut.data(), headerOut, contentOut); } inline void HttpSession::sendNotFound(bool bClose) { - GET_CONFIG_AND_REGISTER(string,notFound,Http::kNotFound); + GET_CONFIG(string,notFound,Http::kNotFound); sendResponse("404 Not Found", makeHttpHeader(bClose, notFound.size()), notFound); } diff --git a/src/Http/HttpSession.h b/src/Http/HttpSession.h index 94cb345c..a3835454 100644 --- a/src/Http/HttpSession.h +++ b/src/Http/HttpSession.h @@ -95,16 +95,7 @@ protected: void onRecvWebSocketData(const Parser &header,const char *data,uint64_t len){ WebSocketSplitter::decode((uint8_t *)data,len); } -private: - Parser _parser; - Ticker _ticker; - uint32_t _iReqCnt = 0; - //消耗的总流量 - uint64_t _ui64TotalBytes = 0; - //flv over http - MediaInfo _mediaInfo; - //处理content数据的callback - function _contentCallBack; + private: inline bool Handle_Req_GET(int64_t &content_len); inline bool Handle_Req_POST(int64_t &content_len); @@ -115,9 +106,21 @@ private: inline void sendNotFound(bool bClose); inline void sendResponse(const char *pcStatus,const KeyValue &header,const string &strContent); inline static KeyValue makeHttpHeader(bool bClose=false,int64_t iContentSize=-1,const char *pcContentType="text/html"); - void responseDelay(const string &Origin,bool bClose, - const string &codeOut,const KeyValue &headerOut, - const string &contentOut); + void responseDelay(const string &Origin, + bool bClose, + const string &codeOut, + const KeyValue &headerOut, + const string &contentOut); +private: + Parser _parser; + Ticker _ticker; + uint32_t _iReqCnt = 0; + //消耗的总流量 + uint64_t _ui64TotalBytes = 0; + //flv over http + MediaInfo _mediaInfo; + //处理content数据的callback + function _contentCallBack; }; diff --git a/src/MediaFile/MediaReader.cpp b/src/MediaFile/MediaReader.cpp index e6e30514..59808c41 100644 --- a/src/MediaFile/MediaReader.cpp +++ b/src/MediaFile/MediaReader.cpp @@ -36,8 +36,13 @@ namespace mediakit { MediaReader::MediaReader(const string &strVhost,const string &strApp, const string &strId,const string &filePath ) { auto strFileName = filePath; if(strFileName.empty()){ - GET_CONFIG_AND_REGISTER(string,recordPath,Record::kFilePath); - strFileName = recordPath + "/" + strVhost + "/" + strApp + "/" + strId; + GET_CONFIG(string,recordPath,Record::kFilePath); + GET_CONFIG(bool,enableVhost,General::kEnableVhost); + if(enableVhost){ + strFileName = recordPath + "/" + strVhost + "/" + strApp + "/" + strId; + }else{ + strFileName = recordPath + "/" + strApp + "/" + strId; + } } _hMP4File = MP4Read(strFileName.data()); @@ -152,7 +157,7 @@ MediaReader::~MediaReader() { void MediaReader::startReadMP4() { auto strongSelf = shared_from_this(); - GET_CONFIG_AND_REGISTER(uint32_t,sampleMS,Record::kSampleMS); + GET_CONFIG(uint32_t,sampleMS,Record::kSampleMS); _timer = std::make_shared(sampleMS / 1000.0f,[strongSelf](){ return strongSelf->readSample(0,false); @@ -321,7 +326,7 @@ MediaSource::Ptr MediaReader::onMakeMediaSource(const string &strSchema, const string &filePath, bool checkApp ){ #ifdef ENABLE_MP4V2 - GET_CONFIG_AND_REGISTER(string,appName,Record::kAppName); + GET_CONFIG(string,appName,Record::kAppName); if (checkApp && strApp != appName) { return nullptr; } diff --git a/src/MediaFile/MediaRecorder.cpp b/src/MediaFile/MediaRecorder.cpp index 1bdc6331..be08867d 100644 --- a/src/MediaFile/MediaRecorder.cpp +++ b/src/MediaFile/MediaRecorder.cpp @@ -41,10 +41,11 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp, bool enableHls, bool enableMp4) { - GET_CONFIG_AND_REGISTER(string,hlsPath,Hls::kFilePath); - GET_CONFIG_AND_REGISTER(uint32_t,hlsBufSize,Hls::kFileBufSize); - GET_CONFIG_AND_REGISTER(uint32_t,hlsDuration,Hls::kSegmentDuration); - GET_CONFIG_AND_REGISTER(uint32_t,hlsNum,Hls::kSegmentNum); + GET_CONFIG(string,hlsPath,Hls::kFilePath); + GET_CONFIG(uint32_t,hlsBufSize,Hls::kFileBufSize); + GET_CONFIG(uint32_t,hlsDuration,Hls::kSegmentDuration); + GET_CONFIG(uint32_t,hlsNum,Hls::kSegmentNum); + GET_CONFIG(bool,enableVhost,General::kEnableVhost); string strVhost = strVhost_tmp; if(trim(strVhost).empty()){ @@ -54,17 +55,28 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp, #if defined(ENABLE_HLS) if(enableHls) { - auto m3u8FilePath = hlsPath + "/" + strVhost + "/" + strApp + "/" + strId + "/hls.m3u8"; - _hlsMaker.reset(new HlsRecorder(m3u8FilePath,string(VHOST_KEY) + "=" + strVhost ,hlsBufSize, hlsDuration, hlsNum)); + string m3u8FilePath; + if(enableVhost){ + m3u8FilePath = hlsPath + "/" + strVhost + "/" + strApp + "/" + strId + "/hls.m3u8"; + _hlsMaker.reset(new HlsRecorder(m3u8FilePath,string(VHOST_KEY) + "=" + strVhost ,hlsBufSize, hlsDuration, hlsNum)); + }else{ + m3u8FilePath = hlsPath + "/" + strApp + "/" + strId + "/hls.m3u8"; + _hlsMaker.reset(new HlsRecorder(m3u8FilePath,"",hlsBufSize, hlsDuration, hlsNum)); + } } #endif //defined(ENABLE_HLS) #if defined(ENABLE_MP4V2) - GET_CONFIG_AND_REGISTER(string,recordPath,Record::kFilePath); - GET_CONFIG_AND_REGISTER(string,recordAppName,Record::kAppName); + GET_CONFIG(string,recordPath,Record::kFilePath); + GET_CONFIG(string,recordAppName,Record::kAppName); if(enableMp4){ - auto mp4FilePath = recordPath + "/" + strVhost + "/" + recordAppName + "/" + strApp + "/" + strId + "/"; + string mp4FilePath; + if(enableVhost){ + mp4FilePath = recordPath + "/" + strVhost + "/" + recordAppName + "/" + strApp + "/" + strId + "/"; + } else { + mp4FilePath = recordPath + "/" + recordAppName + "/" + strApp + "/" + strId + "/"; + } _mp4Maker.reset(new Mp4Maker(mp4FilePath,strVhost,strApp,strId)); } #endif //defined(ENABLE_MP4V2) diff --git a/src/MediaFile/Mp4Maker.cpp b/src/MediaFile/Mp4Maker.cpp index 0e09f7a2..f156ef42 100644 --- a/src/MediaFile/Mp4Maker.cpp +++ b/src/MediaFile/Mp4Maker.cpp @@ -115,7 +115,7 @@ void Mp4Maker::inputAAC(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp } void Mp4Maker::inputH264_l(void *pData, uint32_t ui32Length, uint32_t ui32Duration) { - GET_CONFIG_AND_REGISTER(uint32_t,recordSec,Record::kFileSecond); + GET_CONFIG(uint32_t,recordSec,Record::kFileSecond); auto iType = H264_TYPE(((uint8_t*)pData)[4]); if(iType == H264Frame::NAL_IDR && (_hMp4 == MP4_INVALID_FILE_HANDLE || _ticker.elapsedTime() > recordSec * 1000)){ //在I帧率处新建MP4文件 @@ -128,7 +128,7 @@ void Mp4Maker::inputH264_l(void *pData, uint32_t ui32Length, uint32_t ui32Durati } void Mp4Maker::inputAAC_l(void *pData, uint32_t ui32Length, uint32_t ui32Duration) { - GET_CONFIG_AND_REGISTER(uint32_t,recordSec,Record::kFileSecond); + GET_CONFIG(uint32_t,recordSec,Record::kFileSecond); if (!_haveVideo && (_hMp4 == MP4_INVALID_FILE_HANDLE || _ticker.elapsedTime() > recordSec * 1000)) { //在I帧率处新建MP4文件 @@ -154,14 +154,24 @@ void Mp4Maker::createFile() { _info.strFileName = strTime + ".mp4"; _info.strFilePath = strFile; - GET_CONFIG_AND_REGISTER(string,appName,Record::kAppName); + GET_CONFIG(string,appName,Record::kAppName); + GET_CONFIG(bool,enableVhost,General::kEnableVhost); + + if(enableVhost){ + _info.strUrl = _info.strVhost + "/" + + appName + "/" + + _info.strAppName + "/" + + _info.strStreamId + "/" + + strDate + "/" + + strTime + ".mp4"; + }else{ + _info.strUrl = appName + "/" + + _info.strAppName + "/" + + _info.strStreamId + "/" + + strDate + "/" + + strTime + ".mp4"; + } - _info.strUrl = _info.strVhost + "/" - + appName + "/" - + _info.strAppName + "/" - + _info.strStreamId + "/" - + strDate + "/" - + strTime + ".mp4"; //----record 业务逻辑----// #if !defined(_WIN32) diff --git a/src/Rtmp/RtmpMediaSource.h b/src/Rtmp/RtmpMediaSource.h index 396b65fb..04f42271 100644 --- a/src/Rtmp/RtmpMediaSource.h +++ b/src/Rtmp/RtmpMediaSource.h @@ -127,9 +127,10 @@ public: private: void onReaderChanged(int size){ + //我们记录最后一次活动时间 _readerTicker.resetTime(); if(size != 0 || readerCount() != 0){ - //还有消费者正在观看该流,我们记录最后一次活动时间 + //还有消费者正在观看该流 _asyncEmitNoneReader = false; return; } @@ -137,7 +138,7 @@ private: } void checkNoneReader(){ - GET_CONFIG_AND_REGISTER(int,stream_none_reader_delay,Broadcast::kStreamNoneReaderDelayMS); + GET_CONFIG(int,stream_none_reader_delay,General::kStreamNoneReaderDelayMS); if(_asyncEmitNoneReader && _readerTicker.elapsedTime() > stream_none_reader_delay){ _asyncEmitNoneReader = false; auto listener = _listener.lock(); diff --git a/src/Rtmp/RtmpSession.cpp b/src/Rtmp/RtmpSession.cpp index c164ebd8..128ffb58 100644 --- a/src/Rtmp/RtmpSession.cpp +++ b/src/Rtmp/RtmpSession.cpp @@ -49,7 +49,7 @@ void RtmpSession::onError(const SockException& err) { DebugL << err.what(); //流量统计事件广播 - GET_CONFIG_AND_REGISTER(uint32_t,iFlowThreshold,Broadcast::kFlowThreshold); + GET_CONFIG(uint32_t,iFlowThreshold,General::kFlowThreshold); if(_ui64TotalBytes > iFlowThreshold * 1024){ bool isPlayer = !_pPublisherSrc; @@ -438,7 +438,7 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) { if (!_pPublisherSrc) { throw std::runtime_error("Not a rtmp publisher!"); } - GET_CONFIG_AND_REGISTER(bool,rtmp_modify_stamp,Rtmp::kModifyStamp); + GET_CONFIG(bool,rtmp_modify_stamp,Rtmp::kModifyStamp); if(rtmp_modify_stamp){ chunkData.timeStamp = _stampTicker[chunkData.typeId % 2].elapsedTime(); } diff --git a/src/Rtsp/RtpBroadCaster.cpp b/src/Rtsp/RtpBroadCaster.cpp index 5b84c06c..303f5d8b 100644 --- a/src/Rtsp/RtpBroadCaster.cpp +++ b/src/Rtsp/RtpBroadCaster.cpp @@ -50,8 +50,8 @@ static uint32_t addressToInt(const string &ip){ std::shared_ptr MultiCastAddressMaker::obtain(uint32_t iTry) { lock_guard lck(_mtx); - GET_CONFIG_AND_REGISTER(string,addrMinStr,MultiCast::kAddrMin); - GET_CONFIG_AND_REGISTER(string,addrMaxStr,MultiCast::kAddrMax); + GET_CONFIG(string,addrMinStr,MultiCast::kAddrMin); + GET_CONFIG(string,addrMaxStr,MultiCast::kAddrMax); uint32_t addrMin = addressToInt(addrMinStr); uint32_t addrMax = addressToInt(addrMaxStr); @@ -111,7 +111,7 @@ RtpBroadCaster::RtpBroadCaster(const EventPoller::Ptr &poller,const string &strL throw std::runtime_error(strErr); } auto fd = _apUdpSock[i]->rawFD(); - GET_CONFIG_AND_REGISTER(uint32_t,udpTTL,MultiCast::kUdpTTL); + GET_CONFIG(uint32_t,udpTTL,MultiCast::kUdpTTL); SockUtil::setMultiTTL(fd, udpTTL); SockUtil::setMultiLOOP(fd, false); diff --git a/src/Rtsp/RtpReceiver.cpp b/src/Rtsp/RtpReceiver.cpp index 3f9adb79..08adcef2 100644 --- a/src/Rtsp/RtpReceiver.cpp +++ b/src/Rtsp/RtpReceiver.cpp @@ -132,8 +132,8 @@ bool RtpReceiver::handleOneRtp(int iTrackidx,SdpTrack::Ptr &track, unsigned char //开始排序缓存 if (_abSortStarted[iTrackidx]) { _amapRtpSort[iTrackidx].emplace(rtppt.sequence, pt_ptr); - GET_CONFIG_AND_REGISTER(uint32_t,clearCount,Rtp::kClearCount); - GET_CONFIG_AND_REGISTER(uint32_t,maxRtpCount,Rtp::kMaxRtpCount); + GET_CONFIG(uint32_t,clearCount,Rtp::kClearCount); + GET_CONFIG(uint32_t,maxRtpCount,Rtp::kMaxRtpCount); if (_aui32SeqOkCnt[iTrackidx] >= clearCount) { //网络环境改善,需要清空排序缓存 _aui32SeqOkCnt[iTrackidx] = 0; diff --git a/src/Rtsp/RtspMediaSource.h b/src/Rtsp/RtspMediaSource.h index c5a321d2..c09712c3 100644 --- a/src/Rtsp/RtspMediaSource.h +++ b/src/Rtsp/RtspMediaSource.h @@ -143,9 +143,10 @@ public: } private: void onReaderChanged(int size){ + //我们记录最后一次活动时间 _readerTicker.resetTime(); if(size != 0 || readerCount() != 0){ - //还有消费者正在观看该流,我们记录最后一次活动时间 + //还有消费者正在观看该流 _asyncEmitNoneReader = false; return; } @@ -153,7 +154,7 @@ private: } void checkNoneReader(){ - GET_CONFIG_AND_REGISTER(int,stream_none_reader_delay,Broadcast::kStreamNoneReaderDelayMS); + GET_CONFIG(int,stream_none_reader_delay,General::kStreamNoneReaderDelayMS); if(_asyncEmitNoneReader && _readerTicker.elapsedTime() > stream_none_reader_delay){ _asyncEmitNoneReader = false; auto listener = _listener.lock(); diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 82980ada..d0a1a43d 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -97,7 +97,7 @@ void RtspSession::onError(const SockException& err) { } //流量统计事件广播 - GET_CONFIG_AND_REGISTER(uint32_t,iFlowThreshold,Broadcast::kFlowThreshold); + GET_CONFIG(uint32_t,iFlowThreshold,General::kFlowThreshold); if(_ui64TotalBytes > iFlowThreshold * 1024){ bool isPlayer = !_pushSrc; NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastFlowReport, @@ -389,7 +389,7 @@ void RtspSession::onAuthFailed(const weak_ptr &weakSelf,const strin return; } - GET_CONFIG_AND_REGISTER(bool,authBasic,Rtsp::kAuthBasic); + GET_CONFIG(bool,authBasic,Rtsp::kAuthBasic); if (!authBasic) { //我们需要客户端优先以md5方式认证 strongSelf->_strNonce = makeRandStr(32); @@ -674,7 +674,7 @@ bool RtspSession::handleReq_Setup(const Parser &parser) { return false; } startListenPeerUdpData(trackIdx); - GET_CONFIG_AND_REGISTER(uint32_t,udpTTL,MultiCast::kUdpTTL); + GET_CONFIG(uint32_t,udpTTL,MultiCast::kUdpTTL); sendRtspResponse("200 OK", {"Transport",StrPrinter << "RTP/AVP;multicast;" diff --git a/src/RtspMuxer/AACRtpCodec.cpp b/src/RtspMuxer/AACRtpCodec.cpp index fd6e9527..58474324 100644 --- a/src/RtspMuxer/AACRtpCodec.cpp +++ b/src/RtspMuxer/AACRtpCodec.cpp @@ -42,7 +42,7 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc, void AACRtpEncoder::inputFrame(const Frame::Ptr &frame) { RtpCodec::inputFrame(frame); - GET_CONFIG_AND_REGISTER(uint32_t, cycleMS, Rtp::kCycleMS); + GET_CONFIG(uint32_t, cycleMS, Rtp::kCycleMS); auto uiStamp = frame->stamp(); auto pcData = frame->data() + frame->prefixSize(); auto iLen = frame->size() - frame->prefixSize(); diff --git a/src/RtspMuxer/H264RtpCodec.cpp b/src/RtspMuxer/H264RtpCodec.cpp index 01ec2dc7..09260793 100644 --- a/src/RtspMuxer/H264RtpCodec.cpp +++ b/src/RtspMuxer/H264RtpCodec.cpp @@ -219,7 +219,7 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc, void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) { RtpCodec::inputFrame(frame); - GET_CONFIG_AND_REGISTER(uint32_t,cycleMS,Rtp::kCycleMS); + GET_CONFIG(uint32_t,cycleMS,Rtp::kCycleMS); auto pcData = frame->data() + frame->prefixSize(); auto uiStamp = frame->stamp(); auto iLen = frame->size() - frame->prefixSize(); diff --git a/src/RtspMuxer/H265RtpCodec.cpp b/src/RtspMuxer/H265RtpCodec.cpp index 1ad0f83d..343b7ef8 100644 --- a/src/RtspMuxer/H265RtpCodec.cpp +++ b/src/RtspMuxer/H265RtpCodec.cpp @@ -169,7 +169,7 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc, void H265RtpEncoder::inputFrame(const Frame::Ptr &frame) { RtpCodec::inputFrame(frame); - GET_CONFIG_AND_REGISTER(uint32_t,cycleMS,Rtp::kCycleMS); + GET_CONFIG(uint32_t,cycleMS,Rtp::kCycleMS); uint8_t *pcData = (uint8_t*)frame->data() + frame->prefixSize(); auto uiStamp = frame->stamp(); auto iLen = frame->size() - frame->prefixSize(); diff --git a/src/RtspMuxer/RtspMuxer.cpp b/src/RtspMuxer/RtspMuxer.cpp index 50d5082c..e89d0403 100644 --- a/src/RtspMuxer/RtspMuxer.cpp +++ b/src/RtspMuxer/RtspMuxer.cpp @@ -46,8 +46,8 @@ void RtspMuxer::onTrackReady(const Track::Ptr &track) { } uint32_t ssrc = ((uint64_t) sdp.get()) & 0xFFFFFFFF; - GET_CONFIG_AND_REGISTER(uint32_t,audio_mtu,Rtp::kAudioMtuSize); - GET_CONFIG_AND_REGISTER(uint32_t,video_mtu,Rtp::kVideoMtuSize); + GET_CONFIG(uint32_t,audio_mtu,Rtp::kAudioMtuSize); + GET_CONFIG(uint32_t,video_mtu,Rtp::kVideoMtuSize); auto mtu = (track->getTrackType() == TrackVideo ? video_mtu : audio_mtu); // 根据sdp生成rtp编码器ssrc diff --git a/src/Shell/ShellSession.cpp b/src/Shell/ShellSession.cpp index bc308499..500dbad9 100644 --- a/src/Shell/ShellSession.cpp +++ b/src/Shell/ShellSession.cpp @@ -47,7 +47,7 @@ ShellSession::~ShellSession() { void ShellSession::onRecv(const Buffer::Ptr&buf) { //DebugL << hexdump(buf->data(), buf->size()); - GET_CONFIG_AND_REGISTER(uint32_t,maxReqSize,Shell::kMaxReqSize); + GET_CONFIG(uint32_t,maxReqSize,Shell::kMaxReqSize); if (_strRecvBuf.size() + buf->size() >= maxReqSize) { WarnL << "接收缓冲区溢出!"; shutdown(); diff --git a/tests/test_server.cpp b/tests/test_server.cpp index 979887ad..2e1b6d4a 100644 --- a/tests/test_server.cpp +++ b/tests/test_server.cpp @@ -174,7 +174,7 @@ static onceToken s_token([](){ lock_guard lck(s_mtxFlvRecorder); if(bRegist){ DebugL << "开始录制RTMP:" << schema << " " << vhost << " " << app << " " << stream; - GET_CONFIG_AND_REGISTER(string,http_root,Http::kRootPath); + GET_CONFIG(string,http_root,Http::kRootPath); auto path = http_root + "/" + vhost + "/" + app + "/" + stream + "_" + to_string(time(NULL)) + ".flv"; FlvRecorder::Ptr recorder(new FlvRecorder); try{