mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +08:00
支持全局的禁用虚拟主机
This commit is contained in:
parent
2f976214ce
commit
a100ee0acd
@ -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{
|
||||
|
@ -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
|
||||
|
@ -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()){
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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配置///////////
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;"
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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{
|
||||
|
Loading…
Reference in New Issue
Block a user