支持全局的禁用虚拟主机

This commit is contained in:
xiongziliang 2019-05-28 17:14:36 +08:00
parent 2f976214ce
commit a100ee0acd
23 changed files with 173 additions and 124 deletions

View File

@ -174,7 +174,7 @@ static onceToken s_token([](){
lock_guard<mutex> 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{

View File

@ -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

View File

@ -111,7 +111,7 @@ const char *getContentType(const HttpArgs &value){
}
static void do_http_hook(const string &url,const ArgsType &body,const function<void(const Value &,const string &)> &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()){

View File

@ -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<recursive_mutex> 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<recursive_mutex> 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;
}
}

View File

@ -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

View File

@ -96,10 +96,6 @@ typedef std::function<void(const string &errMessage)> 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配置///////////

View File

@ -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<HttpSession> weakSelf = dynamic_pointer_cast<HttpSession>(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<int64_t> 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<HttpSession> weakSelf = dynamic_pointer_cast<HttpSession>(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);
}

View File

@ -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<bool (const char *data,uint64_t len) > _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,
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<bool (const char *data,uint64_t len) > _contentCallBack;
};

View File

@ -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);
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<Timer>(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;
}

View File

@ -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";
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)

View File

@ -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";
}
//----record 业务逻辑----//
#if !defined(_WIN32)

View File

@ -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();

View File

@ -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();
}

View File

@ -50,8 +50,8 @@ static uint32_t addressToInt(const string &ip){
std::shared_ptr<uint32_t> MultiCastAddressMaker::obtain(uint32_t iTry) {
lock_guard<recursive_mutex> 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);

View File

@ -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;

View File

@ -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();

View File

@ -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<RtspSession> &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;"

View File

@ -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();

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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();

View File

@ -174,7 +174,7 @@ static onceToken s_token([](){
lock_guard<mutex> 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{