mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
实现hls按需拉流
This commit is contained in:
parent
54736859d4
commit
4b4c4e0cec
@ -94,14 +94,12 @@ typedef struct {
|
|||||||
/**
|
/**
|
||||||
* 在http文件服务器中,收到http访问文件或目录的广播,通过该事件控制访问http目录的权限
|
* 在http文件服务器中,收到http访问文件或目录的广播,通过该事件控制访问http目录的权限
|
||||||
* @param parser http请求内容对象
|
* @param parser http请求内容对象
|
||||||
* @param url_info 请求url相关信息
|
|
||||||
* @param path 文件绝对路径
|
* @param path 文件绝对路径
|
||||||
* @param is_dir path是否为文件夹
|
* @param is_dir path是否为文件夹
|
||||||
* @param invoker 执行invoker返回本次访问文件的结果
|
* @param invoker 执行invoker返回本次访问文件的结果
|
||||||
* @param sender http客户端相关信息
|
* @param sender http客户端相关信息
|
||||||
*/
|
*/
|
||||||
void (API_CALL *on_mk_http_access)(const mk_parser parser,
|
void (API_CALL *on_mk_http_access)(const mk_parser parser,
|
||||||
const mk_media_info url_info,
|
|
||||||
const char *path,
|
const char *path,
|
||||||
int is_dir,
|
int is_dir,
|
||||||
const mk_http_access_path_invoker invoker,
|
const mk_http_access_path_invoker invoker,
|
||||||
@ -111,12 +109,10 @@ typedef struct {
|
|||||||
* 在http文件服务器中,收到http访问文件或目录前的广播,通过该事件可以控制http url到文件路径的映射
|
* 在http文件服务器中,收到http访问文件或目录前的广播,通过该事件可以控制http url到文件路径的映射
|
||||||
* 在该事件中通过自行覆盖path参数,可以做到譬如根据虚拟主机或者app选择不同http根目录的目的
|
* 在该事件中通过自行覆盖path参数,可以做到譬如根据虚拟主机或者app选择不同http根目录的目的
|
||||||
* @param parser http请求内容对象
|
* @param parser http请求内容对象
|
||||||
* @param url_info 请求url相关信息
|
|
||||||
* @param path 文件绝对路径,覆盖之可以重定向到其他文件
|
* @param path 文件绝对路径,覆盖之可以重定向到其他文件
|
||||||
* @param sender http客户端相关信息
|
* @param sender http客户端相关信息
|
||||||
*/
|
*/
|
||||||
void (API_CALL *on_mk_http_before_access)(const mk_parser parser,
|
void (API_CALL *on_mk_http_before_access)(const mk_parser parser,
|
||||||
const mk_media_info url_info,
|
|
||||||
char *path,
|
char *path,
|
||||||
const mk_tcp_session sender);
|
const mk_tcp_session sender);
|
||||||
|
|
||||||
|
@ -70,7 +70,6 @@ API_EXPORT void API_CALL mk_events_listen(const mk_events *events){
|
|||||||
NoticeCenter::Instance().addListener(&s_tag,Broadcast::kBroadcastHttpAccess,[](BroadcastHttpAccessArgs){
|
NoticeCenter::Instance().addListener(&s_tag,Broadcast::kBroadcastHttpAccess,[](BroadcastHttpAccessArgs){
|
||||||
if(s_events.on_mk_http_access){
|
if(s_events.on_mk_http_access){
|
||||||
s_events.on_mk_http_access((mk_parser)&parser,
|
s_events.on_mk_http_access((mk_parser)&parser,
|
||||||
(mk_media_info)&args,
|
|
||||||
path.c_str(),
|
path.c_str(),
|
||||||
is_dir,
|
is_dir,
|
||||||
(mk_http_access_path_invoker)&invoker,
|
(mk_http_access_path_invoker)&invoker,
|
||||||
@ -85,7 +84,6 @@ API_EXPORT void API_CALL mk_events_listen(const mk_events *events){
|
|||||||
char path_c[4 * 1024] = {0};
|
char path_c[4 * 1024] = {0};
|
||||||
strcpy(path_c,path.c_str());
|
strcpy(path_c,path.c_str());
|
||||||
s_events.on_mk_http_before_access((mk_parser) &parser,
|
s_events.on_mk_http_before_access((mk_parser) &parser,
|
||||||
(mk_media_info) &args,
|
|
||||||
path_c,
|
path_c,
|
||||||
(mk_tcp_session) &sender);
|
(mk_tcp_session) &sender);
|
||||||
path = path_c;
|
path = path_c;
|
||||||
|
@ -198,14 +198,12 @@ void API_CALL on_mk_http_request(const mk_parser parser,
|
|||||||
/**
|
/**
|
||||||
* 在http文件服务器中,收到http访问文件或目录的广播,通过该事件控制访问http目录的权限
|
* 在http文件服务器中,收到http访问文件或目录的广播,通过该事件控制访问http目录的权限
|
||||||
* @param parser http请求内容对象
|
* @param parser http请求内容对象
|
||||||
* @param url_info 请求url相关信息
|
|
||||||
* @param path 文件绝对路径
|
* @param path 文件绝对路径
|
||||||
* @param is_dir path是否为文件夹
|
* @param is_dir path是否为文件夹
|
||||||
* @param invoker 执行invoker返回本次访问文件的结果
|
* @param invoker 执行invoker返回本次访问文件的结果
|
||||||
* @param sender http客户端相关信息
|
* @param sender http客户端相关信息
|
||||||
*/
|
*/
|
||||||
void API_CALL on_mk_http_access(const mk_parser parser,
|
void API_CALL on_mk_http_access(const mk_parser parser,
|
||||||
const mk_media_info url_info,
|
|
||||||
const char *path,
|
const char *path,
|
||||||
int is_dir,
|
int is_dir,
|
||||||
const mk_http_access_path_invoker invoker,
|
const mk_http_access_path_invoker invoker,
|
||||||
@ -236,12 +234,10 @@ void API_CALL on_mk_http_access(const mk_parser parser,
|
|||||||
* 在http文件服务器中,收到http访问文件或目录前的广播,通过该事件可以控制http url到文件路径的映射
|
* 在http文件服务器中,收到http访问文件或目录前的广播,通过该事件可以控制http url到文件路径的映射
|
||||||
* 在该事件中通过自行覆盖path参数,可以做到譬如根据虚拟主机或者app选择不同http根目录的目的
|
* 在该事件中通过自行覆盖path参数,可以做到譬如根据虚拟主机或者app选择不同http根目录的目的
|
||||||
* @param parser http请求内容对象
|
* @param parser http请求内容对象
|
||||||
* @param url_info 请求url相关信息
|
|
||||||
* @param path 文件绝对路径,覆盖之可以重定向到其他文件
|
* @param path 文件绝对路径,覆盖之可以重定向到其他文件
|
||||||
* @param sender http客户端相关信息
|
* @param sender http客户端相关信息
|
||||||
*/
|
*/
|
||||||
void API_CALL on_mk_http_before_access(const mk_parser parser,
|
void API_CALL on_mk_http_before_access(const mk_parser parser,
|
||||||
const mk_media_info url_info,
|
|
||||||
char *path,
|
char *path,
|
||||||
const mk_tcp_session sender) {
|
const mk_tcp_session sender) {
|
||||||
log_printf(LOG_LEV,
|
log_printf(LOG_LEV,
|
||||||
|
@ -25,10 +25,10 @@ flowThreshold=1024
|
|||||||
#ZLMediaKit会最多让播放器等待maxStreamWaitMS毫秒
|
#ZLMediaKit会最多让播放器等待maxStreamWaitMS毫秒
|
||||||
#如果在这个时间内,该流注册成功,那么会立即返回播放器播放成功
|
#如果在这个时间内,该流注册成功,那么会立即返回播放器播放成功
|
||||||
#否则返回播放器未找到该流,该机制的目的是可以先播放再推流
|
#否则返回播放器未找到该流,该机制的目的是可以先播放再推流
|
||||||
maxStreamWaitMS=5000
|
maxStreamWaitMS=15000
|
||||||
#某个流无人观看时,触发hook.on_stream_none_reader事件的最大等待时间,单位毫秒
|
#某个流无人观看时,触发hook.on_stream_none_reader事件的最大等待时间,单位毫秒
|
||||||
#在配合hook.on_stream_none_reader事件时,可以做到无人观看自动停止拉流或停止接收推流
|
#在配合hook.on_stream_none_reader事件时,可以做到无人观看自动停止拉流或停止接收推流
|
||||||
streamNoneReaderDelayMS=5000
|
streamNoneReaderDelayMS=20000
|
||||||
#是否开启低延时模式,该模式下禁用MSG_MORE,启用TCP_NODEALY,延时将降低,但数据发送性能将降低
|
#是否开启低延时模式,该模式下禁用MSG_MORE,启用TCP_NODEALY,延时将降低,但数据发送性能将降低
|
||||||
ultraLowDelay=1
|
ultraLowDelay=1
|
||||||
#拉流代理是否添加静音音频(直接拉流模式本协议无效)
|
#拉流代理是否添加静音音频(直接拉流模式本协议无效)
|
||||||
|
@ -834,7 +834,7 @@ void installWebApi() {
|
|||||||
<< allArgs["stream"] << "?vhost="
|
<< allArgs["stream"] << "?vhost="
|
||||||
<< allArgs["vhost"];
|
<< allArgs["vhost"];
|
||||||
|
|
||||||
addFFmpegSource("http://live.hkstv.hk.lxdns.com/live/hks2/playlist.m3u8",/** ffmpeg拉流支持任意编码格式任意协议 **/
|
addFFmpegSource("http://hls-ott-zhibo.wasu.tv/live/272/index.m3u8",/** ffmpeg拉流支持任意编码格式任意协议 **/
|
||||||
dst_url,
|
dst_url,
|
||||||
(1000 * timeout_sec) - 500,
|
(1000 * timeout_sec) - 500,
|
||||||
[invoker,val,headerOut](const SockException &ex,const string &key){
|
[invoker,val,headerOut](const SockException &ex,const string &key){
|
||||||
|
@ -441,7 +441,7 @@ void installWebHook(){
|
|||||||
//如果没有url参数,客户端又不支持cookie,那么会根据ip和端口追踪用户
|
//如果没有url参数,客户端又不支持cookie,那么会根据ip和端口追踪用户
|
||||||
//追踪用户的目的是为了缓存上次鉴权结果,减少鉴权次数,提高性能
|
//追踪用户的目的是为了缓存上次鉴权结果,减少鉴权次数,提高性能
|
||||||
NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastHttpAccess,[](BroadcastHttpAccessArgs){
|
NoticeCenter::Instance().addListener(nullptr,Broadcast::kBroadcastHttpAccess,[](BroadcastHttpAccessArgs){
|
||||||
if(sender.get_peer_ip() == "127.0.0.1" && args._param_strs == hook_adminparams){
|
if(sender.get_peer_ip() == "127.0.0.1" && parser.Params() == hook_adminparams){
|
||||||
//如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
|
//如果是本机或超级管理员访问,那么不做访问鉴权;权限有效期1个小时
|
||||||
invoker("","",60 * 60);
|
invoker("","",60 * 60);
|
||||||
return;
|
return;
|
||||||
|
@ -87,8 +87,8 @@ const string kPublishToMP4 = GENERAL_FIELD"publishToMP4";
|
|||||||
|
|
||||||
onceToken token([](){
|
onceToken token([](){
|
||||||
mINI::Instance()[kFlowThreshold] = 1024;
|
mINI::Instance()[kFlowThreshold] = 1024;
|
||||||
mINI::Instance()[kStreamNoneReaderDelayMS] = 5 * 1000;
|
mINI::Instance()[kStreamNoneReaderDelayMS] = 20 * 1000;
|
||||||
mINI::Instance()[kMaxStreamWaitTimeMS] = 5 * 1000;
|
mINI::Instance()[kMaxStreamWaitTimeMS] = 15 * 1000;
|
||||||
mINI::Instance()[kEnableVhost] = 0;
|
mINI::Instance()[kEnableVhost] = 0;
|
||||||
mINI::Instance()[kUltraLowDelay] = 1;
|
mINI::Instance()[kUltraLowDelay] = 1;
|
||||||
mINI::Instance()[kAddMuteAudio] = 1;
|
mINI::Instance()[kAddMuteAudio] = 1;
|
||||||
|
@ -86,12 +86,12 @@ extern const string kBroadcastHttpRequest;
|
|||||||
|
|
||||||
//在http文件服务器中,收到http访问文件或目录的广播,通过该事件控制访问http目录的权限
|
//在http文件服务器中,收到http访问文件或目录的广播,通过该事件控制访问http目录的权限
|
||||||
extern const string kBroadcastHttpAccess;
|
extern const string kBroadcastHttpAccess;
|
||||||
#define BroadcastHttpAccessArgs const Parser &parser,const MediaInfo &args,const string &path,const bool &is_dir,const HttpSession::HttpAccessPathInvoker &invoker,TcpSession &sender
|
#define BroadcastHttpAccessArgs const Parser &parser,const string &path,const bool &is_dir,const HttpSession::HttpAccessPathInvoker &invoker,TcpSession &sender
|
||||||
|
|
||||||
//在http文件服务器中,收到http访问文件或目录前的广播,通过该事件可以控制http url到文件路径的映射
|
//在http文件服务器中,收到http访问文件或目录前的广播,通过该事件可以控制http url到文件路径的映射
|
||||||
//在该事件中通过自行覆盖path参数,可以做到譬如根据虚拟主机或者app选择不同http根目录的目的
|
//在该事件中通过自行覆盖path参数,可以做到譬如根据虚拟主机或者app选择不同http根目录的目的
|
||||||
extern const string kBroadcastHttpBeforeAccess;
|
extern const string kBroadcastHttpBeforeAccess;
|
||||||
#define BroadcastHttpBeforeAccessArgs const Parser &parser,const MediaInfo &args,string &path,TcpSession &sender
|
#define BroadcastHttpBeforeAccessArgs const Parser &parser,string &path,TcpSession &sender
|
||||||
|
|
||||||
//该流是否需要认证?是的话调用invoker并传入realm,否则传入空的realm.如果该事件不监听则不认证
|
//该流是否需要认证?是的话调用invoker并传入realm,否则传入空的realm.如果该事件不监听则不认证
|
||||||
extern const string kBroadcastOnGetRtspRealm;
|
extern const string kBroadcastOnGetRtspRealm;
|
||||||
|
@ -218,16 +218,13 @@ static bool end_of(const string &str, const string &substr){
|
|||||||
};
|
};
|
||||||
|
|
||||||
//拦截hls的播放请求
|
//拦截hls的播放请求
|
||||||
static bool emitHlsPlayed(BroadcastHttpAccessArgs){
|
static bool emitHlsPlayed(const Parser &parser, const MediaInfo &mediaInfo, const HttpSession::HttpAccessPathInvoker &invoker,TcpSession &sender){
|
||||||
//访问的hls.m3u8结尾,我们转换成kBroadcastMediaPlayed事件
|
//访问的hls.m3u8结尾,我们转换成kBroadcastMediaPlayed事件
|
||||||
Broadcast::AuthInvoker mediaAuthInvoker = [invoker,path](const string &err){
|
Broadcast::AuthInvoker mediaAuthInvoker = [invoker](const string &err){
|
||||||
//cookie有效期为kHlsCookieSecond
|
//cookie有效期为kHlsCookieSecond
|
||||||
invoker(err,"",kHlsCookieSecond);
|
invoker(err,"",kHlsCookieSecond);
|
||||||
};
|
};
|
||||||
|
return NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed,mediaInfo,mediaAuthInvoker,sender);
|
||||||
auto args_copy = args;
|
|
||||||
replace(args_copy._streamid,kHlsSuffix,"");
|
|
||||||
return NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastMediaPlayed,args_copy,mediaAuthInvoker,sender);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -284,7 +281,7 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
HttpCookieManager::Instance().delCookie(cookie);
|
HttpCookieManager::Instance().delCookie(cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_hls = end_of(path,kHlsSuffix);
|
bool is_hls = mediaInfo._schema == HLS_SCHEMA;
|
||||||
//该用户从来未获取过cookie,这个时候我们广播是否允许该用户访问该http目录
|
//该用户从来未获取过cookie,这个时候我们广播是否允许该用户访问该http目录
|
||||||
HttpSession::HttpAccessPathInvoker accessPathInvoker = [callback, uid, path, is_dir, is_hls, mediaInfo]
|
HttpSession::HttpAccessPathInvoker accessPathInvoker = [callback, uid, path, is_dir, is_hls, mediaInfo]
|
||||||
(const string &errMsg, const string &cookie_path_in, int cookieLifeSecond) {
|
(const string &errMsg, const string &cookie_path_in, int cookieLifeSecond) {
|
||||||
@ -308,7 +305,6 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
(*cookie)[kAccessHls].set<bool>(is_hls);
|
(*cookie)[kAccessHls].set<bool>(is_hls);
|
||||||
if(is_hls){
|
if(is_hls){
|
||||||
//hls相关信息
|
//hls相关信息
|
||||||
replace(const_cast<string &>(mediaInfo._streamid),kHlsSuffix,"");
|
|
||||||
(*cookie)[kHlsData].set<HlsCookieData>(mediaInfo);
|
(*cookie)[kHlsData].set<HlsCookieData>(mediaInfo);
|
||||||
}
|
}
|
||||||
callback(errMsg, cookie);
|
callback(errMsg, cookie);
|
||||||
@ -317,13 +313,13 @@ static void canAccessPath(TcpSession &sender, const Parser &parser, const MediaI
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (is_hls && emitHlsPlayed(parser, mediaInfo, path, is_dir, accessPathInvoker, sender)) {
|
if (is_hls && emitHlsPlayed(parser, mediaInfo, accessPathInvoker, sender)) {
|
||||||
//是hls的播放鉴权,拦截之
|
//是hls的播放鉴权,拦截之
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//事件未被拦截,则认为是http下载请求
|
//事件未被拦截,则认为是http下载请求
|
||||||
bool flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastHttpAccess, parser, mediaInfo, path, is_dir, accessPathInvoker, sender);
|
bool flag = NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastHttpAccess, parser, path, is_dir, accessPathInvoker, sender);
|
||||||
if (!flag) {
|
if (!flag) {
|
||||||
//此事件无人监听,我们默认都有权限访问
|
//此事件无人监听,我们默认都有权限访问
|
||||||
callback("", nullptr);
|
callback("", nullptr);
|
||||||
@ -357,13 +353,24 @@ static string pathCat(const string &a, const string &b){
|
|||||||
* @param cb 回调对象
|
* @param cb 回调对象
|
||||||
*/
|
*/
|
||||||
static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo &mediaInfo, const string &strFile, const HttpFileManager::invoker &cb) {
|
static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo &mediaInfo, const string &strFile, const HttpFileManager::invoker &cb) {
|
||||||
if (!File::is_file(strFile.data())) {
|
bool is_hls = end_of(strFile, kHlsSuffix);
|
||||||
|
if (!is_hls && !File::is_file(strFile.data())) {
|
||||||
|
//文件不存在且不是hls,那么直接返回404
|
||||||
sendNotFound(cb);
|
sendNotFound(cb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(is_hls){
|
||||||
|
//hls,那么移除掉后缀获取真实的stream_id并且修改协议为HLS
|
||||||
|
const_cast<string &>(mediaInfo._schema) = HLS_SCHEMA;
|
||||||
|
replace(const_cast<string &>(mediaInfo._streamid), kHlsSuffix, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
weak_ptr<TcpSession> weakSession = sender.shared_from_this();
|
||||||
//判断是否有权限访问该文件
|
//判断是否有权限访问该文件
|
||||||
canAccessPath(sender, parser, mediaInfo, false, [cb, strFile, parser](const string &errMsg, const HttpServerCookie::Ptr &cookie) {
|
canAccessPath(sender, parser, mediaInfo, false, [cb, strFile, parser, is_hls, mediaInfo, weakSession](const string &errMsg, const HttpServerCookie::Ptr &cookie) {
|
||||||
if (!errMsg.empty()) {
|
if (!errMsg.empty()) {
|
||||||
|
//文件鉴权失败
|
||||||
StrCaseMap headerOut;
|
StrCaseMap headerOut;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>());
|
headerOut["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>());
|
||||||
@ -372,12 +379,14 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto response_file = [](const HttpServerCookie::Ptr &cookie, const HttpFileManager::invoker &cb, const string &strFile, const Parser &parser) {
|
||||||
StrCaseMap httpHeader;
|
StrCaseMap httpHeader;
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>());
|
httpHeader["Set-Cookie"] = cookie->getCookie((*cookie)[kCookiePathKey].get<string>());
|
||||||
}
|
}
|
||||||
HttpSession::HttpResponseInvoker invoker = [&](const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) {
|
HttpSession::HttpResponseInvoker invoker = [&](const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body) {
|
||||||
if (cookie) {
|
if (cookie) {
|
||||||
|
cookie->getLock();
|
||||||
auto is_hls = (*cookie)[kAccessHls].get<bool>();
|
auto is_hls = (*cookie)[kAccessHls].get<bool>();
|
||||||
if (is_hls) {
|
if (is_hls) {
|
||||||
(*cookie)[kHlsData].get<HlsCookieData>().addByteUsage(body->remainSize());
|
(*cookie)[kHlsData].get<HlsCookieData>().addByteUsage(body->remainSize());
|
||||||
@ -386,6 +395,23 @@ static void accessFile(TcpSession &sender, const Parser &parser, const MediaInfo
|
|||||||
cb(codeOut.data(), getContentType(strFile.data()), headerOut, body);
|
cb(codeOut.data(), getContentType(strFile.data()), headerOut, body);
|
||||||
};
|
};
|
||||||
invoker.responseFile(parser.getValues(), httpHeader, strFile);
|
invoker.responseFile(parser.getValues(), httpHeader, strFile);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!is_hls) {
|
||||||
|
//不是hls,直接回复
|
||||||
|
response_file(cookie, cb, strFile, parser);
|
||||||
|
} else {
|
||||||
|
//文件不存在,那么说明是hls,我们等待其生成并延后回复
|
||||||
|
auto strongSession = weakSession.lock();
|
||||||
|
if(!strongSession){
|
||||||
|
//http客户端已经断开,不需要回复
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MediaSource::findAsync(mediaInfo, strongSession, [response_file, cookie, cb, strFile, parser](const MediaSource::Ptr &src) {
|
||||||
|
//hls已经生成或者超时后仍未生成,那么不管怎么样都返回客户端
|
||||||
|
response_file(cookie, cb, strFile, parser);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,7 +419,7 @@ static string getFilePath(const Parser &parser,const MediaInfo &mediaInfo, TcpSe
|
|||||||
GET_CONFIG(bool, enableVhost, General::kEnableVhost);
|
GET_CONFIG(bool, enableVhost, General::kEnableVhost);
|
||||||
GET_CONFIG(string, rootPath, Http::kRootPath);
|
GET_CONFIG(string, rootPath, Http::kRootPath);
|
||||||
auto ret = File::absolutePath(enableVhost ? mediaInfo._vhost + parser.Url() : parser.Url(), rootPath);
|
auto ret = File::absolutePath(enableVhost ? mediaInfo._vhost + parser.Url() : parser.Url(), rootPath);
|
||||||
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastHttpBeforeAccess, parser, mediaInfo, ret, sender);
|
NoticeCenter::Instance().emitEvent(Broadcast::kBroadcastHttpBeforeAccess, parser, ret, sender);
|
||||||
return std::move(ret);
|
return std::move(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,10 +44,7 @@ class HlsMediaSource : public MediaSource {
|
|||||||
public:
|
public:
|
||||||
friend class HlsCookieData;
|
friend class HlsCookieData;
|
||||||
typedef std::shared_ptr<HlsMediaSource> Ptr;
|
typedef std::shared_ptr<HlsMediaSource> Ptr;
|
||||||
HlsMediaSource(const string &vhost,
|
HlsMediaSource(const string &vhost, const string &app, const string &stream_id) : MediaSource(HLS_SCHEMA, vhost, app, stream_id){
|
||||||
const string &app,
|
|
||||||
const string &stream_id) :
|
|
||||||
MediaSource(HLS_SCHEMA, vhost, app, stream_id){
|
|
||||||
_readerCount = 0;
|
_readerCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user