Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
a100ee0a
Commit
a100ee0a
authored
May 28, 2019
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
支持全局的禁用虚拟主机
parent
2f976214
显示空白字符变更
内嵌
并排
正在显示
23 个修改的文件
包含
164 行增加
和
115 行删除
+164
-115
Android/app/src/main/cpp/test_server.cpp
+1
-1
server/WebApi.cpp
+2
-2
server/WebHook.cpp
+13
-13
src/Common/MediaSource.cpp
+15
-1
src/Common/config.cpp
+11
-9
src/Common/config.h
+25
-24
src/Http/HttpSession.cpp
+18
-18
src/Http/HttpSession.h
+15
-12
src/MediaFile/MediaReader.cpp
+8
-3
src/MediaFile/MediaRecorder.cpp
+20
-8
src/MediaFile/Mp4Maker.cpp
+13
-3
src/Rtmp/RtmpMediaSource.h
+3
-2
src/Rtmp/RtmpSession.cpp
+2
-2
src/Rtsp/RtpBroadCaster.cpp
+3
-3
src/Rtsp/RtpReceiver.cpp
+2
-2
src/Rtsp/RtspMediaSource.h
+3
-2
src/Rtsp/RtspSession.cpp
+3
-3
src/RtspMuxer/AACRtpCodec.cpp
+1
-1
src/RtspMuxer/H264RtpCodec.cpp
+1
-1
src/RtspMuxer/H265RtpCodec.cpp
+1
-1
src/RtspMuxer/RtspMuxer.cpp
+2
-2
src/Shell/ShellSession.cpp
+1
-1
tests/test_server.cpp
+1
-1
没有找到文件。
Android/app/src/main/cpp/test_server.cpp
查看文件 @
a100ee0a
...
@@ -174,7 +174,7 @@ static onceToken s_token([](){
...
@@ -174,7 +174,7 @@ static onceToken s_token([](){
lock_guard
<
mutex
>
lck
(
s_mtxFlvRecorder
);
lock_guard
<
mutex
>
lck
(
s_mtxFlvRecorder
);
if
(
bRegist
){
if
(
bRegist
){
DebugL
<<
"开始录制RTMP:"
<<
schema
<<
" "
<<
vhost
<<
" "
<<
app
<<
" "
<<
stream
;
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"
;
auto
path
=
http_root
+
"/"
+
vhost
+
"/"
+
app
+
"/"
+
stream
+
"_"
+
to_string
(
time
(
NULL
))
+
".flv"
;
FlvRecorder
::
Ptr
recorder
(
new
FlvRecorder
);
FlvRecorder
::
Ptr
recorder
(
new
FlvRecorder
);
try
{
try
{
...
...
server/WebApi.cpp
查看文件 @
a100ee0a
...
@@ -127,7 +127,7 @@ static ApiArgsType getAllArgs(const Parser &parser) {
...
@@ -127,7 +127,7 @@ static ApiArgsType getAllArgs(const Parser &parser) {
}
}
static
inline
void
addHttpListener
(){
static
inline
void
addHttpListener
(){
GET_CONFIG
_AND_REGISTER
(
bool
,
api_debug
,
API
::
kApiDebug
);
GET_CONFIG
(
bool
,
api_debug
,
API
::
kApiDebug
);
//注册监听kBroadcastHttpRequest事件
//注册监听kBroadcastHttpRequest事件
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastHttpRequest
,
[](
BroadcastHttpRequestArgs
)
{
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastHttpRequest
,
[](
BroadcastHttpRequestArgs
)
{
auto
it
=
s_map_api
.
find
(
parser
.
Url
());
auto
it
=
s_map_api
.
find
(
parser
.
Url
());
...
@@ -224,7 +224,7 @@ static inline string getProxyKey(const string &vhost,const string &app,const str
...
@@ -224,7 +224,7 @@ static inline string getProxyKey(const string &vhost,const string &app,const str
void
installWebApi
()
{
void
installWebApi
()
{
addHttpListener
();
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
//测试url http://127.0.0.1/index/api/getThreadsLoad
...
...
server/WebHook.cpp
查看文件 @
a100ee0a
...
@@ -111,7 +111,7 @@ const char *getContentType(const HttpArgs &value){
...
@@ -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
){
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
);
HttpRequester
::
Ptr
requester
(
new
HttpRequester
);
requester
->
setMethod
(
"POST"
);
requester
->
setMethod
(
"POST"
);
auto
bodyStr
=
to_string
(
body
);
auto
bodyStr
=
to_string
(
body
);
...
@@ -150,18 +150,18 @@ static ArgsType make_json(const MediaInfo &args){
...
@@ -150,18 +150,18 @@ static ArgsType make_json(const MediaInfo &args){
void
installWebHook
(){
void
installWebHook
(){
GET_CONFIG
_AND_REGISTER
(
bool
,
hook_enable
,
Hook
::
kEnable
);
GET_CONFIG
(
bool
,
hook_enable
,
Hook
::
kEnable
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_publish
,
Hook
::
kOnPublish
);
GET_CONFIG
(
string
,
hook_publish
,
Hook
::
kOnPublish
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_play
,
Hook
::
kOnPlay
);
GET_CONFIG
(
string
,
hook_play
,
Hook
::
kOnPlay
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_flowreport
,
Hook
::
kOnFlowReport
);
GET_CONFIG
(
string
,
hook_flowreport
,
Hook
::
kOnFlowReport
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_adminparams
,
Hook
::
kAdminParams
);
GET_CONFIG
(
string
,
hook_adminparams
,
Hook
::
kAdminParams
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_rtsp_realm
,
Hook
::
kOnRtspRealm
);
GET_CONFIG
(
string
,
hook_rtsp_realm
,
Hook
::
kOnRtspRealm
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_rtsp_auth
,
Hook
::
kOnRtspAuth
);
GET_CONFIG
(
string
,
hook_rtsp_auth
,
Hook
::
kOnRtspAuth
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_stream_chaned
,
Hook
::
kOnStreamChanged
);
GET_CONFIG
(
string
,
hook_stream_chaned
,
Hook
::
kOnStreamChanged
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_stream_not_found
,
Hook
::
kOnStreamNotFound
);
GET_CONFIG
(
string
,
hook_stream_not_found
,
Hook
::
kOnStreamNotFound
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_record_mp4
,
Hook
::
kOnRecordMp4
);
GET_CONFIG
(
string
,
hook_record_mp4
,
Hook
::
kOnRecordMp4
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_shell_login
,
Hook
::
kOnShellLogin
);
GET_CONFIG
(
string
,
hook_shell_login
,
Hook
::
kOnShellLogin
);
GET_CONFIG
_AND_REGISTER
(
string
,
hook_stream_none_reader
,
Hook
::
kOnStreamNoneReader
);
GET_CONFIG
(
string
,
hook_stream_none_reader
,
Hook
::
kOnStreamNoneReader
);
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastMediaPublish
,[](
BroadcastMediaPublishArgs
){
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastMediaPublish
,[](
BroadcastMediaPublishArgs
){
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_publish
.
empty
()){
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_publish
.
empty
()){
...
...
src/Common/MediaSource.cpp
查看文件 @
a100ee0a
...
@@ -61,7 +61,7 @@ void MediaSource::findAsync(const MediaInfo &info,
...
@@ -61,7 +61,7 @@ void MediaSource::findAsync(const MediaInfo &info,
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastNotFoundStream
,
info
,
*
session
);
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
](){
auto
onRegistTimeout
=
session
->
getPoller
()
->
doDelayTask
(
maxWaitMS
,[
cb
,
listener_tag
](){
...
@@ -112,6 +112,12 @@ MediaSource::Ptr MediaSource::find(
...
@@ -112,6 +112,12 @@ MediaSource::Ptr MediaSource::find(
if
(
vhost
.
empty
()){
if
(
vhost
.
empty
()){
vhost
=
DEFAULT_VHOST
;
vhost
=
DEFAULT_VHOST
;
}
}
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
!
enableVhost
){
vhost
=
DEFAULT_VHOST
;
}
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
MediaSource
::
Ptr
ret
;
MediaSource
::
Ptr
ret
;
searchMedia
(
schema
,
vhost
,
app
,
id
,
searchMedia
(
schema
,
vhost
,
app
,
id
,
...
@@ -135,6 +141,10 @@ MediaSource::Ptr MediaSource::find(
...
@@ -135,6 +141,10 @@ MediaSource::Ptr MediaSource::find(
return
ret
;
return
ret
;
}
}
void
MediaSource
::
regist
()
{
void
MediaSource
::
regist
()
{
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
!
enableVhost
){
_strVhost
=
DEFAULT_VHOST
;
}
//注册该源,注册后服务器才能找到该源
//注册该源,注册后服务器才能找到该源
{
{
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
...
@@ -229,6 +239,10 @@ void MediaInfo::parse(const string &url){
...
@@ -229,6 +239,10 @@ void MediaInfo::parse(const string &url){
_vhost
=
DEFAULT_VHOST
;
_vhost
=
DEFAULT_VHOST
;
}
}
}
}
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
!
enableVhost
){
_vhost
=
DEFAULT_VHOST
;
}
}
}
...
...
src/Common/config.cpp
查看文件 @
a100ee0a
...
@@ -66,17 +66,23 @@ const char kBroadcastReloadConfig[] = "kBroadcastReloadConfig";
...
@@ -66,17 +66,23 @@ const char kBroadcastReloadConfig[] = "kBroadcastReloadConfig";
const
char
kBroadcastShellLogin
[]
=
"kBroadcastShellLogin"
;
const
char
kBroadcastShellLogin
[]
=
"kBroadcastShellLogin"
;
const
char
kBroadcastNotFoundStream
[]
=
"kBroadcastNotFoundStream"
;
const
char
kBroadcastNotFoundStream
[]
=
"kBroadcastNotFoundStream"
;
const
char
kBroadcastStreamNoneReader
[]
=
"kBroadcastStreamNoneReader"
;
const
char
kBroadcastStreamNoneReader
[]
=
"kBroadcastStreamNoneReader"
;
}
//namespace Broadcast
const
char
kFlowThreshold
[]
=
"broadcast.flowThreshold"
;
//通用配置项目
const
char
kStreamNoneReaderDelayMS
[]
=
"broadcast.streamNoneReaderDelayMS"
;
namespace
General
{
const
char
kMaxStreamWaitTimeMS
[]
=
"kMaxStreamWaitTimeMS"
;
#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
([](){
onceToken
token
([](){
mINI
::
Instance
()[
kFlowThreshold
]
=
1024
;
mINI
::
Instance
()[
kFlowThreshold
]
=
1024
;
mINI
::
Instance
()[
kStreamNoneReaderDelayMS
]
=
5
*
1000
;
mINI
::
Instance
()[
kStreamNoneReaderDelayMS
]
=
5
*
1000
;
mINI
::
Instance
()[
kMaxStreamWaitTimeMS
]
=
5
*
1000
;
mINI
::
Instance
()[
kMaxStreamWaitTimeMS
]
=
5
*
1000
;
mINI
::
Instance
()[
kEnableVhost
]
=
1
;
},
nullptr
);
},
nullptr
);
}
//namespace Broadcast
}
//namespace General
////////////HTTP配置///////////
////////////HTTP配置///////////
namespace
Http
{
namespace
Http
{
...
@@ -98,9 +104,6 @@ const char kKeepAliveSecond[] = HTTP_FIELD"keepAliveSecond";
...
@@ -98,9 +104,6 @@ const char kKeepAliveSecond[] = HTTP_FIELD"keepAliveSecond";
#define HTTP_MAX_REQ_CNT 100
#define HTTP_MAX_REQ_CNT 100
const
char
kMaxReqCount
[]
=
HTTP_FIELD
"maxReqCount"
;
const
char
kMaxReqCount
[]
=
HTTP_FIELD
"maxReqCount"
;
//文件服务器是否启动虚拟主机
const
char
kEnableVhost
[]
=
HTTP_FIELD
"enableVhost"
;
//http 字符编码
//http 字符编码
#if defined(_WIN32)
#if defined(_WIN32)
...
@@ -135,7 +138,6 @@ onceToken token([](){
...
@@ -135,7 +138,6 @@ onceToken token([](){
mINI
::
Instance
()[
kCharSet
]
=
HTTP_CHAR_SET
;
mINI
::
Instance
()[
kCharSet
]
=
HTTP_CHAR_SET
;
mINI
::
Instance
()[
kRootPath
]
=
HTTP_ROOT_PATH
;
mINI
::
Instance
()[
kRootPath
]
=
HTTP_ROOT_PATH
;
mINI
::
Instance
()[
kNotFound
]
=
HTTP_NOT_FOUND
;
mINI
::
Instance
()[
kNotFound
]
=
HTTP_NOT_FOUND
;
mINI
::
Instance
()[
kEnableVhost
]
=
1
;
},
nullptr
);
},
nullptr
);
}
//namespace Http
}
//namespace Http
...
...
src/Common/config.h
查看文件 @
a100ee0a
...
@@ -96,10 +96,6 @@ typedef std::function<void(const string &errMessage)> AuthInvoker;
...
@@ -96,10 +96,6 @@ typedef std::function<void(const string &errMessage)> AuthInvoker;
extern
const
char
kBroadcastMediaPublish
[];
extern
const
char
kBroadcastMediaPublish
[];
#define BroadcastMediaPublishArgs const MediaInfo &args,const Broadcast::AuthInvoker &invoker,TcpSession &sender
#define BroadcastMediaPublishArgs const MediaInfo &args,const Broadcast::AuthInvoker &invoker,TcpSession &sender
//兼容旧代码的宏
#define BroadcastRtmpPublishArgs BroadcastMediaPublishArgs
#define kBroadcastRtmpPublish kBroadcastMediaPublish
//播放rtsp/rtmp/http-flv事件广播,通过该事件控制播放鉴权
//播放rtsp/rtmp/http-flv事件广播,通过该事件控制播放鉴权
extern
const
char
kBroadcastMediaPlayed
[];
extern
const
char
kBroadcastMediaPlayed
[];
#define BroadcastMediaPlayedArgs const MediaInfo &args,const Broadcast::AuthInvoker &invoker,TcpSession &sender
#define BroadcastMediaPlayedArgs const MediaInfo &args,const Broadcast::AuthInvoker &invoker,TcpSession &sender
...
@@ -120,24 +116,11 @@ extern const char kBroadcastNotFoundStream[];
...
@@ -120,24 +116,11 @@ extern const char kBroadcastNotFoundStream[];
extern
const
char
kBroadcastStreamNoneReader
[];
extern
const
char
kBroadcastStreamNoneReader
[];
#define BroadcastStreamNoneReaderArgs MediaSource &sender
#define BroadcastStreamNoneReaderArgs MediaSource &sender
//流量汇报事件流量阈值,单位KB,默认1MB
extern
const
char
kFlowThreshold
[];
//流无人观看并且超过若干时间后才触发kBroadcastStreamNoneReader事件
//默认连续5秒无人观看然后触发kBroadcastStreamNoneReader事件
extern
const
char
kStreamNoneReaderDelayMS
[];
//等待流注册超时时间,收到播放器后请求后,如果未找到相关流,服务器会等待一定时间,
//如果在这个时间内,相关流注册上了,那么服务器会立即响应播放器播放成功,
//否则会最多等待kMaxStreamWaitTimeMS毫秒,然后响应播放器播放失败
extern
const
char
kMaxStreamWaitTimeMS
[];
//更新配置文件事件广播,执行loadIniConfig函数加载配置文件成功后会触发该广播
//更新配置文件事件广播,执行loadIniConfig函数加载配置文件成功后会触发该广播
extern
const
char
kBroadcastReloadConfig
[];
extern
const
char
kBroadcastReloadConfig
[];
#define BroadcastReloadConfigArgs void
#define BroadcastReloadConfigArgs void
#define ReloadConfigTag ((void *)(0xFF))
#define ReloadConfigTag ((void *)(0xFF))
#define RELOAD_KEY(arg,key) \
#define RELOAD_KEY(arg,key) \
do{ \
do{ \
decltype(arg) arg##tmp = mINI::Instance()[key]; \
decltype(arg) arg##tmp = mINI::Instance()[key]; \
...
@@ -148,7 +131,7 @@ extern const char kBroadcastReloadConfig[];
...
@@ -148,7 +131,7 @@ extern const char kBroadcastReloadConfig[];
}while(0);
}while(0);
//监听某个配置发送变更
//监听某个配置发送变更
#define
RELOAD_KEY_REGISTER
(arg,key) \
#define
LISTEN_RELOAD_KEY
(arg,key) \
do{ \
do{ \
static onceToken s_token([](){ \
static onceToken s_token([](){ \
NoticeCenter::Instance().addListener(ReloadConfigTag,Broadcast::kBroadcastReloadConfig,[](BroadcastReloadConfigArgs){ \
NoticeCenter::Instance().addListener(ReloadConfigTag,Broadcast::kBroadcastReloadConfig,[](BroadcastReloadConfigArgs){ \
...
@@ -157,12 +140,33 @@ extern const char kBroadcastReloadConfig[];
...
@@ -157,12 +140,33 @@ extern const char kBroadcastReloadConfig[];
}); \
}); \
}while(0);
}while(0);
#define GET_CONFIG
_AND_REGISTER
(type,arg,key) \
#define GET_CONFIG(type,arg,key) \
static type arg = mINI::Instance()[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 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配置///////////
////////////HTTP配置///////////
namespace
Http
{
namespace
Http
{
//http 文件发送缓存大小
//http 文件发送缓存大小
...
@@ -179,9 +183,6 @@ extern const char kCharSet[];
...
@@ -179,9 +183,6 @@ extern const char kCharSet[];
extern
const
char
kRootPath
[];
extern
const
char
kRootPath
[];
//http 404错误提示内容
//http 404错误提示内容
extern
const
char
kNotFound
[];
extern
const
char
kNotFound
[];
//文件服务器是否启动虚拟主机
extern
const
char
kEnableVhost
[];
}
//namespace Http
}
//namespace Http
////////////SHELL配置///////////
////////////SHELL配置///////////
...
...
src/Http/HttpSession.cpp
查看文件 @
a100ee0a
...
@@ -157,7 +157,7 @@ void HttpSession::onRecv(const Buffer::Ptr &pBuf) {
...
@@ -157,7 +157,7 @@ void HttpSession::onRecv(const Buffer::Ptr &pBuf) {
void
HttpSession
::
onError
(
const
SockException
&
err
)
{
void
HttpSession
::
onError
(
const
SockException
&
err
)
{
//WarnL << err.what();
//WarnL << err.what();
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
iFlowThreshold
,
Broadcast
::
kFlowThreshold
);
GET_CONFIG
(
uint32_t
,
iFlowThreshold
,
General
::
kFlowThreshold
);
if
(
_ui64TotalBytes
>
iFlowThreshold
*
1024
){
if
(
_ui64TotalBytes
>
iFlowThreshold
*
1024
){
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastFlowReport
,
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastFlowReport
,
...
@@ -170,7 +170,7 @@ void HttpSession::onError(const SockException& err) {
...
@@ -170,7 +170,7 @@ void HttpSession::onError(const SockException& err) {
}
}
void
HttpSession
::
onManager
()
{
void
HttpSession
::
onManager
()
{
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
keepAliveSec
,
Http
::
kKeepAliveSecond
);
GET_CONFIG
(
uint32_t
,
keepAliveSec
,
Http
::
kKeepAliveSecond
);
if
(
_ticker
.
elapsedTime
()
>
keepAliveSec
*
1000
){
if
(
_ticker
.
elapsedTime
()
>
keepAliveSec
*
1000
){
//1分钟超时
//1分钟超时
...
@@ -218,7 +218,7 @@ inline bool HttpSession::checkLiveFlvStream(){
...
@@ -218,7 +218,7 @@ inline bool HttpSession::checkLiveFlvStream(){
}
}
_mediaInfo
.
_streamid
.
erase
(
_mediaInfo
.
_streamid
.
size
()
-
4
);
//去除.flv后缀
_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
);
bool
bClose
=
(
strcasecmp
(
_parser
[
"Connection"
].
data
(),
"close"
)
==
0
)
||
(
++
_iReqCnt
>
reqCnt
);
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
...
@@ -285,7 +285,7 @@ inline bool HttpSession::checkLiveFlvStream(){
...
@@ -285,7 +285,7 @@ inline bool HttpSession::checkLiveFlvStream(){
return
true
;
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
){
inline
static
string
findIndexFile
(
const
string
&
dir
){
DIR
*
pDir
;
DIR
*
pDir
;
...
@@ -334,9 +334,9 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
...
@@ -334,9 +334,9 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
_mediaInfo
.
parse
(
fullUrl
);
_mediaInfo
.
parse
(
fullUrl
);
/////////////HTTP连接是否需要被关闭////////////////
/////////////HTTP连接是否需要被关闭////////////////
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
reqCnt
,
Http
::
kMaxReqCount
);
GET_CONFIG
(
uint32_t
,
reqCnt
,
Http
::
kMaxReqCount
);
GET_CONFIG
_AND_REGISTER
(
bool
,
enableVhost
,
Http
::
kEnableVhost
);
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
GET_CONFIG
_AND_REGISTER
(
string
,
rootPath
,
Http
::
kRootPath
);
GET_CONFIG
(
string
,
rootPath
,
Http
::
kRootPath
);
string
strFile
=
enableVhost
?
rootPath
+
"/"
+
_mediaInfo
.
_vhost
+
_parser
.
Url
()
:
rootPath
+
_parser
.
Url
();
string
strFile
=
enableVhost
?
rootPath
+
"/"
+
_mediaInfo
.
_vhost
+
_parser
.
Url
()
:
rootPath
+
_parser
.
Url
();
bool
bClose
=
(
strcasecmp
(
_parser
[
"Connection"
].
data
(),
"close"
)
==
0
)
||
(
++
_iReqCnt
>
reqCnt
);
bool
bClose
=
(
strcasecmp
(
_parser
[
"Connection"
].
data
(),
"close"
)
==
0
)
||
(
++
_iReqCnt
>
reqCnt
);
...
@@ -351,7 +351,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
...
@@ -351,7 +351,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
}
}
//生成文件夹菜单索引
//生成文件夹菜单索引
string
strMeun
;
string
strMeun
;
if
(
!
makeMeun
(
_parser
.
Url
(),
strFile
,
_mediaInfo
.
_vhost
,
strMeun
))
{
if
(
!
makeMeun
(
_parser
.
Url
(),
strFile
,
strMeun
))
{
//文件夹不存在
//文件夹不存在
sendNotFound
(
bClose
);
sendNotFound
(
bClose
);
return
!
bClose
;
return
!
bClose
;
...
@@ -417,7 +417,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
...
@@ -417,7 +417,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
//回复Content部分
//回复Content部分
std
::
shared_ptr
<
int64_t
>
piLeft
(
new
int64_t
(
iRangeEnd
-
iRangeStart
+
1
));
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
());
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
auto
onFlush
=
[
pFilePtr
,
bClose
,
weakSelf
,
piLeft
]()
{
auto
onFlush
=
[
pFilePtr
,
bClose
,
weakSelf
,
piLeft
]()
{
...
@@ -477,7 +477,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
...
@@ -477,7 +477,7 @@ inline bool HttpSession::Handle_Req_GET(int64_t &content_len) {
return
true
;
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
strPathPrefix
(
strFullPath
);
string
last_dir_name
;
string
last_dir_name
;
if
(
strPathPrefix
.
back
()
==
'/'
){
if
(
strPathPrefix
.
back
()
==
'/'
){
...
@@ -589,9 +589,9 @@ inline void HttpSession::sendResponse(const char* pcStatus, const KeyValue& head
...
@@ -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
)
{
inline
HttpSession
::
KeyValue
HttpSession
::
makeHttpHeader
(
bool
bClose
,
int64_t
iContentSize
,
const
char
*
pcContentType
)
{
KeyValue
headerOut
;
KeyValue
headerOut
;
GET_CONFIG
_AND_REGISTER
(
string
,
charSet
,
Http
::
kCharSet
);
GET_CONFIG
(
string
,
charSet
,
Http
::
kCharSet
);
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
keepAliveSec
,
Http
::
kKeepAliveSecond
);
GET_CONFIG
(
uint32_t
,
keepAliveSec
,
Http
::
kKeepAliveSecond
);
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
reqCnt
,
Http
::
kMaxReqCount
);
GET_CONFIG
(
uint32_t
,
reqCnt
,
Http
::
kMaxReqCount
);
headerOut
.
emplace
(
"Date"
,
dateStr
());
headerOut
.
emplace
(
"Date"
,
dateStr
());
headerOut
.
emplace
(
"Server"
,
SERVER_NAME
);
headerOut
.
emplace
(
"Server"
,
SERVER_NAME
);
...
@@ -612,7 +612,7 @@ inline HttpSession::KeyValue HttpSession::makeHttpHeader(bool bClose, int64_t iC
...
@@ -612,7 +612,7 @@ inline HttpSession::KeyValue HttpSession::makeHttpHeader(bool bClose, int64_t iC
string
HttpSession
::
urlDecode
(
const
string
&
str
){
string
HttpSession
::
urlDecode
(
const
string
&
str
){
auto
ret
=
strCoding
::
UrlDecode
(
str
);
auto
ret
=
strCoding
::
UrlDecode
(
str
);
#ifdef _WIN32
#ifdef _WIN32
GET_CONFIG
_AND_REGISTER
(
string
,
charSet
,
Http
::
kCharSet
);
GET_CONFIG
(
string
,
charSet
,
Http
::
kCharSet
);
bool
isGb2312
=
!
strcasecmp
(
charSet
.
data
(),
"gb2312"
);
bool
isGb2312
=
!
strcasecmp
(
charSet
.
data
(),
"gb2312"
);
if
(
isGb2312
)
{
if
(
isGb2312
)
{
ret
=
strCoding
::
UTF8ToGB2312
(
ret
);
ret
=
strCoding
::
UTF8ToGB2312
(
ret
);
...
@@ -630,7 +630,7 @@ inline void HttpSession::urlDecode(Parser &parser){
...
@@ -630,7 +630,7 @@ inline void HttpSession::urlDecode(Parser &parser){
inline
bool
HttpSession
::
emitHttpEvent
(
bool
doInvoke
){
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
);
bool
bClose
=
(
strcasecmp
(
_parser
[
"Connection"
].
data
(),
"close"
)
==
0
)
||
(
++
_iReqCnt
>
reqCnt
);
auto
Origin
=
_parser
[
"Origin"
];
auto
Origin
=
_parser
[
"Origin"
];
...
@@ -666,8 +666,8 @@ inline bool HttpSession::emitHttpEvent(bool doInvoke){
...
@@ -666,8 +666,8 @@ inline bool HttpSession::emitHttpEvent(bool doInvoke){
return
consumed
;
return
consumed
;
}
}
inline
bool
HttpSession
::
Handle_Req_POST
(
int64_t
&
content_len
)
{
inline
bool
HttpSession
::
Handle_Req_POST
(
int64_t
&
content_len
)
{
GET_CONFIG
_AND_REGISTER
(
uint64_t
,
maxReqSize
,
Http
::
kMaxReqSize
);
GET_CONFIG
(
uint64_t
,
maxReqSize
,
Http
::
kMaxReqSize
);
GET_CONFIG
_AND_REGISTER
(
int
,
maxReqCnt
,
Http
::
kMaxReqCount
);
GET_CONFIG
(
int
,
maxReqCnt
,
Http
::
kMaxReqCount
);
int64_t
totalContentLen
=
_parser
[
"Content-Length"
].
empty
()
?
-
1
:
atoll
(
_parser
[
"Content-Length"
].
data
());
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,
...
@@ -754,7 +754,7 @@ void HttpSession::responseDelay(const string &Origin,bool bClose,
sendResponse
(
codeOut
.
data
(),
headerOut
,
contentOut
);
sendResponse
(
codeOut
.
data
(),
headerOut
,
contentOut
);
}
}
inline
void
HttpSession
::
sendNotFound
(
bool
bClose
)
{
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
);
sendResponse
(
"404 Not Found"
,
makeHttpHeader
(
bClose
,
notFound
.
size
()),
notFound
);
}
}
...
...
src/Http/HttpSession.h
查看文件 @
a100ee0a
...
@@ -95,16 +95,7 @@ protected:
...
@@ -95,16 +95,7 @@ protected:
void
onRecvWebSocketData
(
const
Parser
&
header
,
const
char
*
data
,
uint64_t
len
){
void
onRecvWebSocketData
(
const
Parser
&
header
,
const
char
*
data
,
uint64_t
len
){
WebSocketSplitter
::
decode
((
uint8_t
*
)
data
,
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
:
private
:
inline
bool
Handle_Req_GET
(
int64_t
&
content_len
);
inline
bool
Handle_Req_GET
(
int64_t
&
content_len
);
inline
bool
Handle_Req_POST
(
int64_t
&
content_len
);
inline
bool
Handle_Req_POST
(
int64_t
&
content_len
);
...
@@ -115,9 +106,21 @@ private:
...
@@ -115,9 +106,21 @@ private:
inline
void
sendNotFound
(
bool
bClose
);
inline
void
sendNotFound
(
bool
bClose
);
inline
void
sendResponse
(
const
char
*
pcStatus
,
const
KeyValue
&
header
,
const
string
&
strContent
);
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"
);
inline
static
KeyValue
makeHttpHeader
(
bool
bClose
=
false
,
int64_t
iContentSize
=-
1
,
const
char
*
pcContentType
=
"text/html"
);
void
responseDelay
(
const
string
&
Origin
,
bool
bClose
,
void
responseDelay
(
const
string
&
Origin
,
const
string
&
codeOut
,
const
KeyValue
&
headerOut
,
bool
bClose
,
const
string
&
codeOut
,
const
KeyValue
&
headerOut
,
const
string
&
contentOut
);
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
;
};
};
...
...
src/MediaFile/MediaReader.cpp
查看文件 @
a100ee0a
...
@@ -36,8 +36,13 @@ namespace mediakit {
...
@@ -36,8 +36,13 @@ namespace mediakit {
MediaReader
::
MediaReader
(
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strId
,
const
string
&
filePath
)
{
MediaReader
::
MediaReader
(
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strId
,
const
string
&
filePath
)
{
auto
strFileName
=
filePath
;
auto
strFileName
=
filePath
;
if
(
strFileName
.
empty
()){
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
;
strFileName
=
recordPath
+
"/"
+
strVhost
+
"/"
+
strApp
+
"/"
+
strId
;
}
else
{
strFileName
=
recordPath
+
"/"
+
strApp
+
"/"
+
strId
;
}
}
}
_hMP4File
=
MP4Read
(
strFileName
.
data
());
_hMP4File
=
MP4Read
(
strFileName
.
data
());
...
@@ -152,7 +157,7 @@ MediaReader::~MediaReader() {
...
@@ -152,7 +157,7 @@ MediaReader::~MediaReader() {
void
MediaReader
::
startReadMP4
()
{
void
MediaReader
::
startReadMP4
()
{
auto
strongSelf
=
shared_from_this
();
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.0
f
,[
strongSelf
](){
_timer
=
std
::
make_shared
<
Timer
>
(
sampleMS
/
1000.0
f
,[
strongSelf
](){
return
strongSelf
->
readSample
(
0
,
false
);
return
strongSelf
->
readSample
(
0
,
false
);
...
@@ -321,7 +326,7 @@ MediaSource::Ptr MediaReader::onMakeMediaSource(const string &strSchema,
...
@@ -321,7 +326,7 @@ MediaSource::Ptr MediaReader::onMakeMediaSource(const string &strSchema,
const
string
&
filePath
,
const
string
&
filePath
,
bool
checkApp
){
bool
checkApp
){
#ifdef ENABLE_MP4V2
#ifdef ENABLE_MP4V2
GET_CONFIG
_AND_REGISTER
(
string
,
appName
,
Record
::
kAppName
);
GET_CONFIG
(
string
,
appName
,
Record
::
kAppName
);
if
(
checkApp
&&
strApp
!=
appName
)
{
if
(
checkApp
&&
strApp
!=
appName
)
{
return
nullptr
;
return
nullptr
;
}
}
...
...
src/MediaFile/MediaRecorder.cpp
查看文件 @
a100ee0a
...
@@ -41,10 +41,11 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp,
...
@@ -41,10 +41,11 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp,
bool
enableHls
,
bool
enableHls
,
bool
enableMp4
)
{
bool
enableMp4
)
{
GET_CONFIG_AND_REGISTER
(
string
,
hlsPath
,
Hls
::
kFilePath
);
GET_CONFIG
(
string
,
hlsPath
,
Hls
::
kFilePath
);
GET_CONFIG_AND_REGISTER
(
uint32_t
,
hlsBufSize
,
Hls
::
kFileBufSize
);
GET_CONFIG
(
uint32_t
,
hlsBufSize
,
Hls
::
kFileBufSize
);
GET_CONFIG_AND_REGISTER
(
uint32_t
,
hlsDuration
,
Hls
::
kSegmentDuration
);
GET_CONFIG
(
uint32_t
,
hlsDuration
,
Hls
::
kSegmentDuration
);
GET_CONFIG_AND_REGISTER
(
uint32_t
,
hlsNum
,
Hls
::
kSegmentNum
);
GET_CONFIG
(
uint32_t
,
hlsNum
,
Hls
::
kSegmentNum
);
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
string
strVhost
=
strVhost_tmp
;
string
strVhost
=
strVhost_tmp
;
if
(
trim
(
strVhost
).
empty
()){
if
(
trim
(
strVhost
).
empty
()){
...
@@ -54,17 +55,28 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp,
...
@@ -54,17 +55,28 @@ MediaRecorder::MediaRecorder(const string &strVhost_tmp,
#if defined(ENABLE_HLS)
#if defined(ENABLE_HLS)
if
(
enableHls
)
{
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
));
_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)
#endif //defined(ENABLE_HLS)
#if defined(ENABLE_MP4V2)
#if defined(ENABLE_MP4V2)
GET_CONFIG
_AND_REGISTER
(
string
,
recordPath
,
Record
::
kFilePath
);
GET_CONFIG
(
string
,
recordPath
,
Record
::
kFilePath
);
GET_CONFIG
_AND_REGISTER
(
string
,
recordAppName
,
Record
::
kAppName
);
GET_CONFIG
(
string
,
recordAppName
,
Record
::
kAppName
);
if
(
enableMp4
){
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
));
_mp4Maker
.
reset
(
new
Mp4Maker
(
mp4FilePath
,
strVhost
,
strApp
,
strId
));
}
}
#endif //defined(ENABLE_MP4V2)
#endif //defined(ENABLE_MP4V2)
...
...
src/MediaFile/Mp4Maker.cpp
查看文件 @
a100ee0a
...
@@ -115,7 +115,7 @@ void Mp4Maker::inputAAC(void *pData, uint32_t ui32Length, uint32_t ui32TimeStamp
...
@@ -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
)
{
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
]);
auto
iType
=
H264_TYPE
(((
uint8_t
*
)
pData
)[
4
]);
if
(
iType
==
H264Frame
::
NAL_IDR
&&
(
_hMp4
==
MP4_INVALID_FILE_HANDLE
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
)){
if
(
iType
==
H264Frame
::
NAL_IDR
&&
(
_hMp4
==
MP4_INVALID_FILE_HANDLE
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
)){
//在I帧率处新建MP4文件
//在I帧率处新建MP4文件
...
@@ -128,7 +128,7 @@ void Mp4Maker::inputH264_l(void *pData, uint32_t ui32Length, uint32_t ui32Durati
...
@@ -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
)
{
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
))
{
if
(
!
_haveVideo
&&
(
_hMp4
==
MP4_INVALID_FILE_HANDLE
||
_ticker
.
elapsedTime
()
>
recordSec
*
1000
))
{
//在I帧率处新建MP4文件
//在I帧率处新建MP4文件
...
@@ -154,14 +154,24 @@ void Mp4Maker::createFile() {
...
@@ -154,14 +154,24 @@ void Mp4Maker::createFile() {
_info
.
strFileName
=
strTime
+
".mp4"
;
_info
.
strFileName
=
strTime
+
".mp4"
;
_info
.
strFilePath
=
strFile
;
_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
+
"/"
_info
.
strUrl
=
_info
.
strVhost
+
"/"
+
appName
+
"/"
+
appName
+
"/"
+
_info
.
strAppName
+
"/"
+
_info
.
strAppName
+
"/"
+
_info
.
strStreamId
+
"/"
+
_info
.
strStreamId
+
"/"
+
strDate
+
"/"
+
strDate
+
"/"
+
strTime
+
".mp4"
;
+
strTime
+
".mp4"
;
}
else
{
_info
.
strUrl
=
appName
+
"/"
+
_info
.
strAppName
+
"/"
+
_info
.
strStreamId
+
"/"
+
strDate
+
"/"
+
strTime
+
".mp4"
;
}
//----record 业务逻辑----//
//----record 业务逻辑----//
#if !defined(_WIN32)
#if !defined(_WIN32)
...
...
src/Rtmp/RtmpMediaSource.h
查看文件 @
a100ee0a
...
@@ -127,9 +127,10 @@ public:
...
@@ -127,9 +127,10 @@ public:
private
:
private
:
void
onReaderChanged
(
int
size
){
void
onReaderChanged
(
int
size
){
//我们记录最后一次活动时间
_readerTicker
.
resetTime
();
_readerTicker
.
resetTime
();
if
(
size
!=
0
||
readerCount
()
!=
0
){
if
(
size
!=
0
||
readerCount
()
!=
0
){
//还有消费者正在观看该流
,我们记录最后一次活动时间
//还有消费者正在观看该流
_asyncEmitNoneReader
=
false
;
_asyncEmitNoneReader
=
false
;
return
;
return
;
}
}
...
@@ -137,7 +138,7 @@ private:
...
@@ -137,7 +138,7 @@ private:
}
}
void
checkNoneReader
(){
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
){
if
(
_asyncEmitNoneReader
&&
_readerTicker
.
elapsedTime
()
>
stream_none_reader_delay
){
_asyncEmitNoneReader
=
false
;
_asyncEmitNoneReader
=
false
;
auto
listener
=
_listener
.
lock
();
auto
listener
=
_listener
.
lock
();
...
...
src/Rtmp/RtmpSession.cpp
查看文件 @
a100ee0a
...
@@ -49,7 +49,7 @@ void RtmpSession::onError(const SockException& err) {
...
@@ -49,7 +49,7 @@ void RtmpSession::onError(const SockException& err) {
DebugL
<<
err
.
what
();
DebugL
<<
err
.
what
();
//流量统计事件广播
//流量统计事件广播
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
iFlowThreshold
,
Broadcast
::
kFlowThreshold
);
GET_CONFIG
(
uint32_t
,
iFlowThreshold
,
General
::
kFlowThreshold
);
if
(
_ui64TotalBytes
>
iFlowThreshold
*
1024
){
if
(
_ui64TotalBytes
>
iFlowThreshold
*
1024
){
bool
isPlayer
=
!
_pPublisherSrc
;
bool
isPlayer
=
!
_pPublisherSrc
;
...
@@ -438,7 +438,7 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
...
@@ -438,7 +438,7 @@ void RtmpSession::onRtmpChunk(RtmpPacket &chunkData) {
if
(
!
_pPublisherSrc
)
{
if
(
!
_pPublisherSrc
)
{
throw
std
::
runtime_error
(
"Not a rtmp publisher!"
);
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
){
if
(
rtmp_modify_stamp
){
chunkData
.
timeStamp
=
_stampTicker
[
chunkData
.
typeId
%
2
].
elapsedTime
();
chunkData
.
timeStamp
=
_stampTicker
[
chunkData
.
typeId
%
2
].
elapsedTime
();
}
}
...
...
src/Rtsp/RtpBroadCaster.cpp
查看文件 @
a100ee0a
...
@@ -50,8 +50,8 @@ static uint32_t addressToInt(const string &ip){
...
@@ -50,8 +50,8 @@ static uint32_t addressToInt(const string &ip){
std
::
shared_ptr
<
uint32_t
>
MultiCastAddressMaker
::
obtain
(
uint32_t
iTry
)
{
std
::
shared_ptr
<
uint32_t
>
MultiCastAddressMaker
::
obtain
(
uint32_t
iTry
)
{
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
GET_CONFIG
_AND_REGISTER
(
string
,
addrMinStr
,
MultiCast
::
kAddrMin
);
GET_CONFIG
(
string
,
addrMinStr
,
MultiCast
::
kAddrMin
);
GET_CONFIG
_AND_REGISTER
(
string
,
addrMaxStr
,
MultiCast
::
kAddrMax
);
GET_CONFIG
(
string
,
addrMaxStr
,
MultiCast
::
kAddrMax
);
uint32_t
addrMin
=
addressToInt
(
addrMinStr
);
uint32_t
addrMin
=
addressToInt
(
addrMinStr
);
uint32_t
addrMax
=
addressToInt
(
addrMaxStr
);
uint32_t
addrMax
=
addressToInt
(
addrMaxStr
);
...
@@ -111,7 +111,7 @@ RtpBroadCaster::RtpBroadCaster(const EventPoller::Ptr &poller,const string &strL
...
@@ -111,7 +111,7 @@ RtpBroadCaster::RtpBroadCaster(const EventPoller::Ptr &poller,const string &strL
throw
std
::
runtime_error
(
strErr
);
throw
std
::
runtime_error
(
strErr
);
}
}
auto
fd
=
_apUdpSock
[
i
]
->
rawFD
();
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
::
setMultiTTL
(
fd
,
udpTTL
);
SockUtil
::
setMultiLOOP
(
fd
,
false
);
SockUtil
::
setMultiLOOP
(
fd
,
false
);
...
...
src/Rtsp/RtpReceiver.cpp
查看文件 @
a100ee0a
...
@@ -132,8 +132,8 @@ bool RtpReceiver::handleOneRtp(int iTrackidx,SdpTrack::Ptr &track, unsigned char
...
@@ -132,8 +132,8 @@ bool RtpReceiver::handleOneRtp(int iTrackidx,SdpTrack::Ptr &track, unsigned char
//开始排序缓存
//开始排序缓存
if
(
_abSortStarted
[
iTrackidx
])
{
if
(
_abSortStarted
[
iTrackidx
])
{
_amapRtpSort
[
iTrackidx
].
emplace
(
rtppt
.
sequence
,
pt_ptr
);
_amapRtpSort
[
iTrackidx
].
emplace
(
rtppt
.
sequence
,
pt_ptr
);
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
clearCount
,
Rtp
::
kClearCount
);
GET_CONFIG
(
uint32_t
,
clearCount
,
Rtp
::
kClearCount
);
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
maxRtpCount
,
Rtp
::
kMaxRtpCount
);
GET_CONFIG
(
uint32_t
,
maxRtpCount
,
Rtp
::
kMaxRtpCount
);
if
(
_aui32SeqOkCnt
[
iTrackidx
]
>=
clearCount
)
{
if
(
_aui32SeqOkCnt
[
iTrackidx
]
>=
clearCount
)
{
//网络环境改善,需要清空排序缓存
//网络环境改善,需要清空排序缓存
_aui32SeqOkCnt
[
iTrackidx
]
=
0
;
_aui32SeqOkCnt
[
iTrackidx
]
=
0
;
...
...
src/Rtsp/RtspMediaSource.h
查看文件 @
a100ee0a
...
@@ -143,9 +143,10 @@ public:
...
@@ -143,9 +143,10 @@ public:
}
}
private
:
private
:
void
onReaderChanged
(
int
size
){
void
onReaderChanged
(
int
size
){
//我们记录最后一次活动时间
_readerTicker
.
resetTime
();
_readerTicker
.
resetTime
();
if
(
size
!=
0
||
readerCount
()
!=
0
){
if
(
size
!=
0
||
readerCount
()
!=
0
){
//还有消费者正在观看该流
,我们记录最后一次活动时间
//还有消费者正在观看该流
_asyncEmitNoneReader
=
false
;
_asyncEmitNoneReader
=
false
;
return
;
return
;
}
}
...
@@ -153,7 +154,7 @@ private:
...
@@ -153,7 +154,7 @@ private:
}
}
void
checkNoneReader
(){
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
){
if
(
_asyncEmitNoneReader
&&
_readerTicker
.
elapsedTime
()
>
stream_none_reader_delay
){
_asyncEmitNoneReader
=
false
;
_asyncEmitNoneReader
=
false
;
auto
listener
=
_listener
.
lock
();
auto
listener
=
_listener
.
lock
();
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
a100ee0a
...
@@ -97,7 +97,7 @@ void RtspSession::onError(const SockException& err) {
...
@@ -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
){
if
(
_ui64TotalBytes
>
iFlowThreshold
*
1024
){
bool
isPlayer
=
!
_pushSrc
;
bool
isPlayer
=
!
_pushSrc
;
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastFlowReport
,
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastFlowReport
,
...
@@ -389,7 +389,7 @@ void RtspSession::onAuthFailed(const weak_ptr<RtspSession> &weakSelf,const strin
...
@@ -389,7 +389,7 @@ void RtspSession::onAuthFailed(const weak_ptr<RtspSession> &weakSelf,const strin
return
;
return
;
}
}
GET_CONFIG
_AND_REGISTER
(
bool
,
authBasic
,
Rtsp
::
kAuthBasic
);
GET_CONFIG
(
bool
,
authBasic
,
Rtsp
::
kAuthBasic
);
if
(
!
authBasic
)
{
if
(
!
authBasic
)
{
//我们需要客户端优先以md5方式认证
//我们需要客户端优先以md5方式认证
strongSelf
->
_strNonce
=
makeRandStr
(
32
);
strongSelf
->
_strNonce
=
makeRandStr
(
32
);
...
@@ -674,7 +674,7 @@ bool RtspSession::handleReq_Setup(const Parser &parser) {
...
@@ -674,7 +674,7 @@ bool RtspSession::handleReq_Setup(const Parser &parser) {
return
false
;
return
false
;
}
}
startListenPeerUdpData
(
trackIdx
);
startListenPeerUdpData
(
trackIdx
);
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
udpTTL
,
MultiCast
::
kUdpTTL
);
GET_CONFIG
(
uint32_t
,
udpTTL
,
MultiCast
::
kUdpTTL
);
sendRtspResponse
(
"200 OK"
,
sendRtspResponse
(
"200 OK"
,
{
"Transport"
,
StrPrinter
<<
"RTP/AVP;multicast;"
{
"Transport"
,
StrPrinter
<<
"RTP/AVP;multicast;"
...
...
src/RtspMuxer/AACRtpCodec.cpp
查看文件 @
a100ee0a
...
@@ -42,7 +42,7 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
...
@@ -42,7 +42,7 @@ AACRtpEncoder::AACRtpEncoder(uint32_t ui32Ssrc,
void
AACRtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
void
AACRtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
RtpCodec
::
inputFrame
(
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
uiStamp
=
frame
->
stamp
();
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
...
...
src/RtspMuxer/H264RtpCodec.cpp
查看文件 @
a100ee0a
...
@@ -219,7 +219,7 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc,
...
@@ -219,7 +219,7 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc,
void
H264RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
void
H264RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
RtpCodec
::
inputFrame
(
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
pcData
=
frame
->
data
()
+
frame
->
prefixSize
();
auto
uiStamp
=
frame
->
stamp
();
auto
uiStamp
=
frame
->
stamp
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
...
...
src/RtspMuxer/H265RtpCodec.cpp
查看文件 @
a100ee0a
...
@@ -169,7 +169,7 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
...
@@ -169,7 +169,7 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc,
void
H265RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
void
H265RtpEncoder
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
RtpCodec
::
inputFrame
(
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
();
uint8_t
*
pcData
=
(
uint8_t
*
)
frame
->
data
()
+
frame
->
prefixSize
();
auto
uiStamp
=
frame
->
stamp
();
auto
uiStamp
=
frame
->
stamp
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
auto
iLen
=
frame
->
size
()
-
frame
->
prefixSize
();
...
...
src/RtspMuxer/RtspMuxer.cpp
查看文件 @
a100ee0a
...
@@ -46,8 +46,8 @@ void RtspMuxer::onTrackReady(const Track::Ptr &track) {
...
@@ -46,8 +46,8 @@ void RtspMuxer::onTrackReady(const Track::Ptr &track) {
}
}
uint32_t
ssrc
=
((
uint64_t
)
sdp
.
get
())
&
0xFFFFFFFF
;
uint32_t
ssrc
=
((
uint64_t
)
sdp
.
get
())
&
0xFFFFFFFF
;
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
audio_mtu
,
Rtp
::
kAudioMtuSize
);
GET_CONFIG
(
uint32_t
,
audio_mtu
,
Rtp
::
kAudioMtuSize
);
GET_CONFIG
_AND_REGISTER
(
uint32_t
,
video_mtu
,
Rtp
::
kVideoMtuSize
);
GET_CONFIG
(
uint32_t
,
video_mtu
,
Rtp
::
kVideoMtuSize
);
auto
mtu
=
(
track
->
getTrackType
()
==
TrackVideo
?
video_mtu
:
audio_mtu
);
auto
mtu
=
(
track
->
getTrackType
()
==
TrackVideo
?
video_mtu
:
audio_mtu
);
// 根据sdp生成rtp编码器ssrc
// 根据sdp生成rtp编码器ssrc
...
...
src/Shell/ShellSession.cpp
查看文件 @
a100ee0a
...
@@ -47,7 +47,7 @@ ShellSession::~ShellSession() {
...
@@ -47,7 +47,7 @@ ShellSession::~ShellSession() {
void
ShellSession
::
onRecv
(
const
Buffer
::
Ptr
&
buf
)
{
void
ShellSession
::
onRecv
(
const
Buffer
::
Ptr
&
buf
)
{
//DebugL << hexdump(buf->data(), buf->size());
//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
)
{
if
(
_strRecvBuf
.
size
()
+
buf
->
size
()
>=
maxReqSize
)
{
WarnL
<<
"接收缓冲区溢出!"
;
WarnL
<<
"接收缓冲区溢出!"
;
shutdown
();
shutdown
();
...
...
tests/test_server.cpp
查看文件 @
a100ee0a
...
@@ -174,7 +174,7 @@ static onceToken s_token([](){
...
@@ -174,7 +174,7 @@ static onceToken s_token([](){
lock_guard
<
mutex
>
lck
(
s_mtxFlvRecorder
);
lock_guard
<
mutex
>
lck
(
s_mtxFlvRecorder
);
if
(
bRegist
){
if
(
bRegist
){
DebugL
<<
"开始录制RTMP:"
<<
schema
<<
" "
<<
vhost
<<
" "
<<
app
<<
" "
<<
stream
;
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"
;
auto
path
=
http_root
+
"/"
+
vhost
+
"/"
+
app
+
"/"
+
stream
+
"_"
+
to_string
(
time
(
NULL
))
+
".flv"
;
FlvRecorder
::
Ptr
recorder
(
new
FlvRecorder
);
FlvRecorder
::
Ptr
recorder
(
new
FlvRecorder
);
try
{
try
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论