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
eca92369
Commit
eca92369
authored
Sep 06, 2020
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
优化与拦截代码
parent
74d6689a
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
315 行增加
和
323 行删除
+315
-323
server/FFmpegSource.cpp
+0
-24
server/FFmpegSource.h
+1
-5
src/Common/MediaSink.h
+6
-1
src/Common/MediaSource.cpp
+212
-156
src/Common/MediaSource.h
+51
-30
src/Common/MultiMediaSourceMuxer.cpp
+23
-63
src/Common/MultiMediaSourceMuxer.h
+22
-44
没有找到文件。
server/FFmpegSource.cpp
查看文件 @
eca92369
...
...
@@ -245,30 +245,6 @@ bool FFmpegSource::close(MediaSource &sender, bool force) {
return
true
;
}
int
FFmpegSource
::
totalReaderCount
(
MediaSource
&
sender
)
{
auto
listener
=
_listener
.
lock
();
if
(
listener
){
return
listener
->
totalReaderCount
(
sender
);
}
return
sender
.
readerCount
();
}
void
FFmpegSource
::
onNoneReader
(
MediaSource
&
sender
){
auto
listener
=
_listener
.
lock
();
if
(
listener
){
listener
->
onNoneReader
(
sender
);
return
;
}
MediaSourceEvent
::
onNoneReader
(
sender
);
}
void
FFmpegSource
::
onRegist
(
MediaSource
&
sender
,
bool
regist
){
auto
listener
=
_listener
.
lock
();
if
(
listener
){
listener
->
onRegist
(
sender
,
regist
);
}
}
void
FFmpegSource
::
onGetMediaSource
(
const
MediaSource
::
Ptr
&
src
)
{
auto
listener
=
src
->
getListener
();
if
(
listener
.
lock
().
get
()
!=
this
)
{
...
...
server/FFmpegSource.h
查看文件 @
eca92369
...
...
@@ -40,7 +40,7 @@ private:
~
FFmpegSnap
()
=
delete
;
};
class
FFmpegSource
:
public
std
::
enable_shared_from_this
<
FFmpegSource
>
,
public
MediaSourceEvent
{
class
FFmpegSource
:
public
std
::
enable_shared_from_this
<
FFmpegSource
>
,
public
MediaSourceEvent
Interceptor
{
public
:
typedef
shared_ptr
<
FFmpegSource
>
Ptr
;
typedef
function
<
void
(
const
SockException
&
ex
)
>
onPlay
;
...
...
@@ -60,9 +60,6 @@ private:
//MediaSourceEvent override
bool
close
(
MediaSource
&
sender
,
bool
force
)
override
;
int
totalReaderCount
(
MediaSource
&
sender
)
override
;
void
onNoneReader
(
MediaSource
&
sender
)
override
;
void
onRegist
(
MediaSource
&
sender
,
bool
regist
)
override
;
private
:
Process
_process
;
...
...
@@ -72,7 +69,6 @@ private:
string
_src_url
;
string
_dst_url
;
function
<
void
()
>
_onClose
;
std
::
weak_ptr
<
MediaSourceEvent
>
_listener
;
Ticker
_replay_ticker
;
};
...
...
src/Common/MediaSink.h
查看文件 @
eca92369
...
...
@@ -37,6 +37,11 @@ public:
virtual
void
addTrack
(
const
Track
::
Ptr
&
track
)
=
0
;
/**
* 添加所有Track完毕
*/
virtual
void
addTrackCompleted
()
{}
/**
* 重置track
*/
virtual
void
resetTracks
()
=
0
;
...
...
@@ -70,7 +75,7 @@ public:
* 这样会增加生成流的延时,如果添加了音视频双Track,那么可以不调用此方法
* 否则为了降低流注册延时,请手动调用此方法
*/
void
addTrackCompleted
();
void
addTrackCompleted
()
override
;
/**
* 重置track
...
...
src/Common/MediaSource.cpp
查看文件 @
eca92369
...
...
@@ -17,16 +17,19 @@
using
namespace
toolkit
;
namespace
mediakit
{
recursive_mutex
MediaSource
::
g_mtxMediaSrc
;
MediaSource
::
SchemaVhostAppStreamMap
MediaSource
::
g_mapMediaSrc
;
recursive_mutex
s_media_source_mtx
;
MediaSource
::
SchemaVhostAppStreamMap
s_media_source_map
;
MediaSource
::
MediaSource
(
const
string
&
s
trSchema
,
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strId
)
:
_strSchema
(
strSchema
),
_strApp
(
strApp
),
_strId
(
strId
)
{
if
(
strVhost
.
empty
()
)
{
_
strV
host
=
DEFAULT_VHOST
;
MediaSource
::
MediaSource
(
const
string
&
s
chema
,
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream_id
){
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
!
enableVhost
)
{
_
v
host
=
DEFAULT_VHOST
;
}
else
{
_
strVhost
=
strV
host
;
_
vhost
=
vhost
.
empty
()
?
DEFAULT_VHOST
:
v
host
;
}
_schema
=
schema
;
_app
=
app
;
_stream_id
=
stream_id
;
}
MediaSource
::~
MediaSource
()
{
...
...
@@ -34,26 +37,26 @@ MediaSource::~MediaSource() {
}
const
string
&
MediaSource
::
getSchema
()
const
{
return
_s
trS
chema
;
return
_schema
;
}
const
string
&
MediaSource
::
getVhost
()
const
{
return
_
strV
host
;
return
_
v
host
;
}
const
string
&
MediaSource
::
getApp
()
const
{
//获取该源的id
return
_
strA
pp
;
return
_
a
pp
;
}
const
string
&
MediaSource
::
getId
()
const
{
return
_str
I
d
;
return
_str
eam_i
d
;
}
vector
<
Track
::
Ptr
>
MediaSource
::
getTracks
(
bool
trackR
eady
)
const
{
vector
<
Track
::
Ptr
>
MediaSource
::
getTracks
(
bool
r
eady
)
const
{
auto
strongPtr
=
_track_source
.
lock
();
if
(
strongPtr
){
return
strongPtr
->
getTracks
(
trackR
eady
);
return
strongPtr
->
getTracks
(
r
eady
);
}
return
vector
<
Track
::
Ptr
>
();
}
...
...
@@ -77,12 +80,13 @@ int MediaSource::totalReaderCount(){
}
return
listener
->
totalReaderCount
(
*
this
);
}
bool
MediaSource
::
seekTo
(
uint32_t
ui32Stamp
)
{
bool
MediaSource
::
seekTo
(
uint32_t
stamp
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
){
return
false
;
}
return
listener
->
seekTo
(
*
this
,
ui32S
tamp
);
return
listener
->
seekTo
(
*
this
,
s
tamp
);
}
bool
MediaSource
::
close
(
bool
force
)
{
...
...
@@ -121,12 +125,12 @@ bool MediaSource::isRecording(Recorder::type type){
}
void
MediaSource
::
for_each_media
(
const
function
<
void
(
const
MediaSource
::
Ptr
&
src
)
>
&
cb
)
{
decltype
(
g_mapMediaSrc
)
copy
;
decltype
(
s_media_source_map
)
copy
;
{
//拷贝
g_mapMediaSrc
后再遍历,考虑到是高频使用的全局单例锁,并且在上锁时会执行回调代码
//拷贝
s_media_source_map
后再遍历,考虑到是高频使用的全局单例锁,并且在上锁时会执行回调代码
//很容易导致多个锁交叉死锁的情况,而且该函数使用频率不高,拷贝开销相对来说是可以接受的
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
copy
=
g_mapMediaSrc
;
lock_guard
<
recursive_mutex
>
lock
(
s_media_source_mtx
);
copy
=
s_media_source_map
;
}
for
(
auto
&
pr0
:
copy
)
{
...
...
@@ -181,42 +185,75 @@ static void eraseIfEmpty(MAP &map, IT0 it0, IT1 it1, IT2 it2) {
}
}
void
MediaSource
::
findAsync_l
(
const
MediaInfo
&
info
,
const
std
::
shared_ptr
<
TcpSession
>
&
session
,
bool
retry
,
const
function
<
void
(
const
MediaSource
::
Ptr
&
src
)
>
&
cb
){
auto
src
=
MediaSource
::
find_l
(
info
.
_schema
,
info
.
_vhost
,
info
.
_app
,
info
.
_streamid
,
true
);
static
MediaSource
::
Ptr
find_l
(
const
string
&
schema
,
const
string
&
vhost_in
,
const
string
&
app
,
const
string
&
id
,
bool
create_new
)
{
string
vhost
=
vhost_in
;
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
vhost
.
empty
()
||
!
enableVhost
){
vhost
=
DEFAULT_VHOST
;
}
MediaSource
::
Ptr
ret
;
{
lock_guard
<
recursive_mutex
>
lock
(
s_media_source_mtx
);
//查找某一媒体源,找到后返回
searchMedia
(
s_media_source_map
,
schema
,
vhost
,
app
,
id
,
[
&
](
MediaSource
::
SchemaVhostAppStreamMap
::
iterator
&
it0
,
MediaSource
::
VhostAppStreamMap
::
iterator
&
it1
,
MediaSource
::
AppStreamMap
::
iterator
&
it2
,
MediaSource
::
StreamMap
::
iterator
&
it3
)
{
ret
=
it3
->
second
.
lock
();
if
(
!
ret
)
{
//该对象已经销毁
it2
->
second
.
erase
(
it3
);
eraseIfEmpty
(
s_media_source_map
,
it0
,
it1
,
it2
);
return
false
;
}
return
true
;
});
}
if
(
!
ret
&&
create_new
){
//未查找媒体源,则创建一个
ret
=
MediaSource
::
createFromMP4
(
schema
,
vhost
,
app
,
id
);
}
return
ret
;
}
static
void
findAsync_l
(
const
MediaInfo
&
info
,
const
std
::
shared_ptr
<
TcpSession
>
&
session
,
bool
retry
,
const
function
<
void
(
const
MediaSource
::
Ptr
&
src
)
>
&
cb
){
auto
src
=
find_l
(
info
.
_schema
,
info
.
_vhost
,
info
.
_app
,
info
.
_streamid
,
true
);
if
(
src
||
!
retry
)
{
cb
(
src
);
return
;
}
void
*
listener_tag
=
session
.
get
();
weak_ptr
<
TcpSession
>
weak
S
ession
=
session
;
weak_ptr
<
TcpSession
>
weak
_s
ession
=
session
;
GET_CONFIG
(
int
,
maxWaitMS
,
General
::
kMaxStreamWaitTimeMS
);
auto
on
T
imeout
=
session
->
getPoller
()
->
doDelayTask
(
maxWaitMS
,
[
cb
,
listener_tag
]()
{
auto
on
_t
imeout
=
session
->
getPoller
()
->
doDelayTask
(
maxWaitMS
,
[
cb
,
listener_tag
]()
{
//最多等待一定时间,如果这个时间内,流未注册上,那么返回未找到流
NoticeCenter
::
Instance
().
delListener
(
listener_tag
,
Broadcast
::
kBroadcastMediaChanged
);
cb
(
nullptr
);
return
0
;
});
auto
cancel
All
=
[
onT
imeout
,
listener_tag
]()
{
auto
cancel
_all
=
[
on_t
imeout
,
listener_tag
]()
{
//取消延时任务,防止多次回调
on
T
imeout
->
cancel
();
on
_t
imeout
->
cancel
();
//取消媒体注册事件监听
NoticeCenter
::
Instance
().
delListener
(
listener_tag
,
Broadcast
::
kBroadcastMediaChanged
);
};
function
<
void
()
>
close
Player
=
[
cb
,
cancelA
ll
]()
{
cancel
A
ll
();
function
<
void
()
>
close
_player
=
[
cb
,
cancel_a
ll
]()
{
cancel
_a
ll
();
//告诉播放器,流不存在,这样会立即断开播放器
cb
(
nullptr
);
};
auto
on
Regist
=
[
weakSession
,
info
,
cb
,
cancelA
ll
](
BroadcastMediaChangedArgs
)
{
auto
strong
Session
=
weakS
ession
.
lock
();
if
(
!
strong
S
ession
)
{
auto
on
_regist
=
[
weak_session
,
info
,
cb
,
cancel_a
ll
](
BroadcastMediaChangedArgs
)
{
auto
strong
_session
=
weak_s
ession
.
lock
();
if
(
!
strong
_s
ession
)
{
//自己已经销毁
cancel
A
ll
();
cancel
_a
ll
();
return
;
}
...
...
@@ -229,11 +266,11 @@ void MediaSource::findAsync_l(const MediaInfo &info, const std::shared_ptr<TcpSe
return
;
}
cancel
A
ll
();
cancel
_a
ll
();
//播发器请求的流终于注册上了,切换到自己的线程再回复
strong
Session
->
async
([
weakS
ession
,
info
,
cb
]()
{
auto
strongSession
=
weak
S
ession
.
lock
();
strong
_session
->
async
([
weak_s
ession
,
info
,
cb
]()
{
auto
strongSession
=
weak
_s
ession
.
lock
();
if
(
!
strongSession
)
{
return
;
}
...
...
@@ -244,9 +281,9 @@ void MediaSource::findAsync_l(const MediaInfo &info, const std::shared_ptr<TcpSe
};
//监听媒体注册事件
NoticeCenter
::
Instance
().
addListener
(
listener_tag
,
Broadcast
::
kBroadcastMediaChanged
,
on
R
egist
);
NoticeCenter
::
Instance
().
addListener
(
listener_tag
,
Broadcast
::
kBroadcastMediaChanged
,
on
_r
egist
);
//广播未找到流,此时可以立即去拉流,这样还来得及
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastNotFoundStream
,
info
,
static_cast
<
SockInfo
&>
(
*
session
),
close
P
layer
);
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastNotFoundStream
,
info
,
static_cast
<
SockInfo
&>
(
*
session
),
close
_p
layer
);
}
void
MediaSource
::
findAsync
(
const
MediaInfo
&
info
,
const
std
::
shared_ptr
<
TcpSession
>
&
session
,
const
function
<
void
(
const
Ptr
&
src
)
>
&
cb
){
...
...
@@ -257,55 +294,10 @@ MediaSource::Ptr MediaSource::find(const string &schema, const string &vhost, co
return
find_l
(
schema
,
vhost
,
app
,
id
,
false
);
}
MediaSource
::
Ptr
MediaSource
::
find_l
(
const
string
&
schema
,
const
string
&
vhost_tmp
,
const
string
&
app
,
const
string
&
id
,
bool
bMake
)
{
string
vhost
=
vhost_tmp
;
if
(
vhost
.
empty
()){
vhost
=
DEFAULT_VHOST
;
}
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
!
enableVhost
){
vhost
=
DEFAULT_VHOST
;
}
MediaSource
::
Ptr
ret
;
{
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
//查找某一媒体源,找到后返回
searchMedia
(
g_mapMediaSrc
,
schema
,
vhost
,
app
,
id
,
[
&
](
SchemaVhostAppStreamMap
::
iterator
&
it0
,
VhostAppStreamMap
::
iterator
&
it1
,
AppStreamMap
::
iterator
&
it2
,
StreamMap
::
iterator
&
it3
)
{
ret
=
it3
->
second
.
lock
();
if
(
!
ret
)
{
//该对象已经销毁
it2
->
second
.
erase
(
it3
);
eraseIfEmpty
(
g_mapMediaSrc
,
it0
,
it1
,
it2
);
return
false
;
}
return
true
;
});
}
if
(
!
ret
&&
bMake
){
//未查找媒体源,则创建一个
ret
=
createFromMP4
(
schema
,
vhost
,
app
,
id
);
}
return
ret
;
}
void
MediaSource
::
regist
()
{
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
!
enableVhost
){
_strVhost
=
DEFAULT_VHOST
;
}
//注册该源,注册后服务器才能找到该源
{
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
g_mapMediaSrc
[
_strSchema
][
_strVhost
][
_strApp
][
_strId
]
=
shared_from_this
();
}
static
string
getTrackInfoStr
(
const
TrackSource
*
track_src
){
_StrPrinter
codec_info
;
auto
tracks
=
getTracks
(
true
);
for
(
auto
&
track
:
tracks
)
{
auto
tracks
=
track_src
->
getTracks
(
true
);
for
(
auto
&
track
:
tracks
)
{
auto
codec_type
=
track
->
getTrackType
();
codec_info
<<
track
->
getCodecName
();
switch
(
codec_type
)
{
...
...
@@ -329,45 +321,51 @@ void MediaSource::regist() {
break
;
}
}
return
codec_info
;
}
InfoL
<<
_strSchema
<<
" "
<<
_strVhost
<<
" "
<<
_strApp
<<
" "
<<
_strId
<<
" "
<<
codec_info
;
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaChanged
,
true
,
*
this
);
void
MediaSource
::
emitEvent
(
bool
regist
){
auto
listener
=
_listener
.
lock
();
if
(
listener
)
{
listener
->
onRegist
(
*
this
,
true
);
//触发回调
listener
->
onRegist
(
*
this
,
regist
);
}
//触发广播
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaChanged
,
regist
,
*
this
);
InfoL
<<
(
regist
?
"媒体注册:"
:
"媒体注销:"
)
<<
_schema
<<
" "
<<
_vhost
<<
" "
<<
_app
<<
" "
<<
_stream_id
<<
" "
<<
getTrackInfoStr
(
this
);
}
void
MediaSource
::
regist
()
{
{
//减小互斥锁临界区
lock_guard
<
recursive_mutex
>
lock
(
s_media_source_mtx
);
s_media_source_map
[
_schema
][
_vhost
][
_app
][
_stream_id
]
=
shared_from_this
();
}
emitEvent
(
true
);
}
//反注册该源
bool
MediaSource
::
unregist
()
{
bool
ret
;
{
lock_guard
<
recursive_mutex
>
lock
(
g_mtxMediaSrc
);
ret
=
searchMedia
(
g_mapMediaSrc
,
_strSchema
,
_strVhost
,
_strApp
,
_strId
,
[
&
](
SchemaVhostAppStreamMap
::
iterator
&
it0
,
VhostAppStreamMap
::
iterator
&
it1
,
AppStreamMap
::
iterator
&
it2
,
StreamMap
::
iterator
&
it3
)
{
auto
strongMedia
=
it3
->
second
.
lock
();
if
(
strongMedia
&&
this
!=
strongMedia
.
get
())
{
//不是自己,不允许反注册
return
false
;
}
it2
->
second
.
erase
(
it3
);
eraseIfEmpty
(
g_mapMediaSrc
,
it0
,
it1
,
it2
);
return
true
;
});
}
if
(
ret
){
InfoL
<<
_strSchema
<<
" "
<<
_strVhost
<<
" "
<<
_strApp
<<
" "
<<
_strId
;
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaChanged
,
false
,
*
this
);
auto
listener
=
_listener
.
lock
();
if
(
listener
)
{
listener
->
onRegist
(
*
this
,
false
);
}
//减小互斥锁临界区
lock_guard
<
recursive_mutex
>
lock
(
s_media_source_mtx
);
ret
=
searchMedia
(
s_media_source_map
,
_schema
,
_vhost
,
_app
,
_stream_id
,
[
&
](
SchemaVhostAppStreamMap
::
iterator
&
it0
,
VhostAppStreamMap
::
iterator
&
it1
,
AppStreamMap
::
iterator
&
it2
,
StreamMap
::
iterator
&
it3
)
{
auto
strong_self
=
it3
->
second
.
lock
();
if
(
strong_self
&&
this
!=
strong_self
.
get
())
{
//不是自己,不允许反注册
return
false
;
}
it2
->
second
.
erase
(
it3
);
eraseIfEmpty
(
s_media_source_map
,
it0
,
it1
,
it2
);
return
true
;
});
}
if
(
ret
)
{
emitEvent
(
false
);
}
return
ret
;
}
...
...
@@ -377,67 +375,87 @@ bool MediaSource::unregist() {
void
MediaInfo
::
parse
(
const
string
&
url
){
//string url = "rtsp://127.0.0.1:8554/live/id?key=val&a=1&&b=2&vhost=vhost.com";
auto
schema_pos
=
url
.
find
(
"://"
);
if
(
schema_pos
!=
string
::
npos
)
{
_schema
=
url
.
substr
(
0
,
schema_pos
);
}
else
{
if
(
schema_pos
!=
string
::
npos
)
{
_schema
=
url
.
substr
(
0
,
schema_pos
);
}
else
{
schema_pos
=
-
3
;
}
auto
split_vec
=
split
(
url
.
substr
(
schema_pos
+
3
),
"/"
);
if
(
split_vec
.
size
()
>
0
)
{
auto
split_vec
=
split
(
url
.
substr
(
schema_pos
+
3
),
"/"
);
if
(
split_vec
.
size
()
>
0
)
{
auto
vhost
=
split_vec
[
0
];
auto
pos
=
vhost
.
find
(
":"
);
if
(
pos
!=
string
::
npos
)
{
_host
=
_vhost
=
vhost
.
substr
(
0
,
pos
);
if
(
pos
!=
string
::
npos
)
{
_host
=
_vhost
=
vhost
.
substr
(
0
,
pos
);
_port
=
vhost
.
substr
(
pos
+
1
);
}
else
{
}
else
{
_host
=
_vhost
=
vhost
;
}
if
(
_vhost
==
"localhost"
||
INADDR_NONE
!=
inet_addr
(
_vhost
.
data
()))
{
if
(
_vhost
==
"localhost"
||
INADDR_NONE
!=
inet_addr
(
_vhost
.
data
()))
{
//如果访问的是localhost或ip,那么则为默认虚拟主机
_vhost
=
DEFAULT_VHOST
;
}
}
if
(
split_vec
.
size
()
>
1
)
{
if
(
split_vec
.
size
()
>
1
)
{
_app
=
split_vec
[
1
];
}
if
(
split_vec
.
size
()
>
2
)
{
string
st
eam
id
;
for
(
int
i
=
2
;
i
<
split_vec
.
size
()
;
++
i
)
{
st
eam
id
.
append
(
split_vec
[
i
]
+
"/"
);
if
(
split_vec
.
size
()
>
2
)
{
string
st
ream_
id
;
for
(
int
i
=
2
;
i
<
split_vec
.
size
();
++
i
)
{
st
ream_
id
.
append
(
split_vec
[
i
]
+
"/"
);
}
if
(
steamid
.
back
()
==
'/'
)
{
st
eam
id
.
pop_back
();
if
(
stream_id
.
back
()
==
'/'
)
{
st
ream_
id
.
pop_back
();
}
auto
pos
=
st
eam
id
.
find
(
"?"
);
if
(
pos
!=
string
::
npos
)
{
_streamid
=
st
eamid
.
substr
(
0
,
pos
);
_param_strs
=
st
eam
id
.
substr
(
pos
+
1
);
auto
pos
=
st
ream_
id
.
find
(
"?"
);
if
(
pos
!=
string
::
npos
)
{
_streamid
=
st
ream_id
.
substr
(
0
,
pos
);
_param_strs
=
st
ream_
id
.
substr
(
pos
+
1
);
auto
params
=
Parser
::
parseArgs
(
_param_strs
);
if
(
params
.
find
(
VHOST_KEY
)
!=
params
.
end
())
{
if
(
params
.
find
(
VHOST_KEY
)
!=
params
.
end
())
{
_vhost
=
params
[
VHOST_KEY
];
}
}
else
{
_streamid
=
st
eam
id
;
}
else
{
_streamid
=
st
ream_
id
;
}
}
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
!
enableVhost
||
_vhost
.
empty
())
{
GET_CONFIG
(
bool
,
enableVhost
,
General
::
kEnableVhost
);
if
(
!
enableVhost
||
_vhost
.
empty
())
{
//如果关闭虚拟主机或者虚拟主机为空,则设置虚拟主机为默认
_vhost
=
DEFAULT_VHOST
;
}
}
MediaSource
::
Ptr
MediaSource
::
createFromMP4
(
const
string
&
schema
,
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream
,
const
string
&
file_path
,
bool
check_app
){
GET_CONFIG
(
string
,
appName
,
Record
::
kAppName
);
if
(
check_app
&&
app
!=
appName
)
{
return
nullptr
;
}
#ifdef ENABLE_MP4
try
{
MP4Reader
::
Ptr
pReader
(
new
MP4Reader
(
vhost
,
app
,
stream
,
file_path
));
pReader
->
startReadMP4
();
return
MediaSource
::
find
(
schema
,
vhost
,
app
,
stream
);
}
catch
(
std
::
exception
&
ex
)
{
WarnL
<<
ex
.
what
();
return
nullptr
;
}
#else
WarnL
<<
"创建MP4点播失败,请编译时打开
\"
ENABLE_MP4
\"
选项"
;
return
nullptr
;
#endif //ENABLE_MP4
}
/////////////////////////////////////MediaSourceEvent//////////////////////////////////////
void
MediaSourceEvent
::
onNoneReader
(
MediaSource
&
sender
){
GET_CONFIG
(
string
,
record
A
pp
,
Record
::
kAppName
);
GET_CONFIG
(
string
,
record
_a
pp
,
Record
::
kAppName
);
GET_CONFIG
(
int
,
stream_none_reader_delay
,
General
::
kStreamNoneReaderDelayMS
);
//如果mp4点播, 无人观看时我们强制关闭点播
bool
is_mp4_vod
=
sender
.
getApp
()
==
record
A
pp
;
bool
is_mp4_vod
=
sender
.
getApp
()
==
record
_a
pp
;
//没有任何人观看该视频源,表明该源可以关闭了
weak_ptr
<
MediaSource
>
weakSender
=
sender
.
shared_from_this
();
...
...
@@ -475,26 +493,64 @@ void MediaSourceEvent::onNoneReader(MediaSource &sender){
},
nullptr
);
}
MediaSource
::
Ptr
MediaSource
::
createFromMP4
(
const
string
&
schema
,
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream
,
const
string
&
filePath
,
bool
checkApp
)
{
GET_CONFIG
(
string
,
appName
,
Record
::
kAppName
);
if
(
checkApp
&&
app
!=
appName
)
{
return
nullptr
;
bool
MediaSourceEventInterceptor
::
seekTo
(
MediaSource
&
sender
,
uint32_t
stamp
)
{
auto
listener
=
_listener
.
lock
(
);
if
(
!
listener
)
{
return
false
;
}
#ifdef ENABLE_MP4
try
{
MP4Reader
::
Ptr
pReader
(
new
MP4Reader
(
vhost
,
app
,
stream
,
filePath
));
pReader
->
startReadMP4
();
return
MediaSource
::
find
(
schema
,
vhost
,
app
,
stream
);
}
catch
(
std
::
exception
&
ex
)
{
WarnL
<<
ex
.
what
();
return
nullptr
;
return
listener
->
seekTo
(
sender
,
stamp
);
}
bool
MediaSourceEventInterceptor
::
close
(
MediaSource
&
sender
,
bool
force
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
return
false
;
}
#else
WarnL
<<
"创建MP4点播失败,请编译时打开
\"
ENABLE_MP4
\"
选项"
;
return
nullptr
;
#endif //ENABLE_MP4
return
listener
->
close
(
sender
,
force
);
}
int
MediaSourceEventInterceptor
::
totalReaderCount
(
MediaSource
&
sender
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
return
sender
.
readerCount
();
}
return
listener
->
totalReaderCount
(
sender
);
}
void
MediaSourceEventInterceptor
::
onNoneReader
(
MediaSource
&
sender
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
MediaSourceEvent
::
onNoneReader
(
sender
);
return
;
}
listener
->
onNoneReader
(
sender
);
}
void
MediaSourceEventInterceptor
::
onRegist
(
MediaSource
&
sender
,
bool
regist
)
{
auto
listener
=
_listener
.
lock
();
if
(
listener
)
{
listener
->
onRegist
(
sender
,
regist
);
}
}
bool
MediaSourceEventInterceptor
::
setupRecord
(
MediaSource
&
sender
,
Recorder
::
type
type
,
bool
start
,
const
string
&
custom_path
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
return
false
;
}
return
listener
->
setupRecord
(
sender
,
type
,
start
,
custom_path
);
}
bool
MediaSourceEventInterceptor
::
isRecording
(
MediaSource
&
sender
,
Recorder
::
type
type
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
return
false
;
}
return
listener
->
isRecording
(
sender
,
type
);
}
/////////////////////////////////////FlushPolicy//////////////////////////////////////
static
bool
isFlushAble_default
(
bool
is_video
,
uint32_t
last_stamp
,
uint32_t
new_stamp
,
int
cache_size
)
{
if
(
new_stamp
+
500
<
last_stamp
)
{
//时间戳回退比较大(可能seek中),由于rtp中时间戳是pts,是可能存在一定程度的回退的
...
...
src/Common/MediaSource.h
查看文件 @
eca92369
...
...
@@ -44,33 +44,54 @@ public:
virtual
~
MediaSourceEvent
(){};
// 通知拖动进度条
virtual
bool
seekTo
(
MediaSource
&
sender
,
uint32_t
ui32Stamp
)
{
return
false
;
}
// 通知其停止
推
流
virtual
bool
close
(
MediaSource
&
sender
,
bool
force
)
{
return
false
;
}
// 观看总人数
virtual
bool
seekTo
(
MediaSource
&
sender
,
uint32_t
stamp
)
{
return
false
;
}
// 通知其停止
产生
流
virtual
bool
close
(
MediaSource
&
sender
,
bool
force
)
{
return
false
;
}
//
获取
观看总人数
virtual
int
totalReaderCount
(
MediaSource
&
sender
)
=
0
;
// 开启或关闭录制
virtual
bool
setupRecord
(
MediaSource
&
sender
,
Recorder
::
type
type
,
bool
start
,
const
string
&
custom_path
)
{
return
false
;
};
// 获取录制状态
virtual
bool
isRecording
(
MediaSource
&
sender
,
Recorder
::
type
type
)
{
return
false
;
};
// 通知无人观看
virtual
void
onNoneReader
(
MediaSource
&
sender
);
//流注册或注销事件
virtual
void
onRegist
(
MediaSource
&
sender
,
bool
regist
)
{};
////////////////////////仅供MultiMediaSourceMuxer对象继承////////////////////////
// 开启或关闭录制
virtual
bool
setupRecord
(
MediaSource
&
sender
,
Recorder
::
type
type
,
bool
start
,
const
string
&
custom_path
)
{
return
false
;
};
// 获取录制状态
virtual
bool
isRecording
(
MediaSource
&
sender
,
Recorder
::
type
type
)
{
return
false
;
};
private
:
Timer
::
Ptr
_async_close_timer
;
};
//该对象用于拦截感兴趣的MediaSourceEvent事件
class
MediaSourceEventInterceptor
:
public
MediaSourceEvent
{
public
:
MediaSourceEventInterceptor
(){}
~
MediaSourceEventInterceptor
()
override
{}
bool
seekTo
(
MediaSource
&
sender
,
uint32_t
stamp
)
override
;
bool
close
(
MediaSource
&
sender
,
bool
force
)
override
;
int
totalReaderCount
(
MediaSource
&
sender
)
override
;
void
onNoneReader
(
MediaSource
&
sender
)
override
;
void
onRegist
(
MediaSource
&
sender
,
bool
regist
)
override
;;
bool
setupRecord
(
MediaSource
&
sender
,
Recorder
::
type
type
,
bool
start
,
const
string
&
custom_path
)
override
;
bool
isRecording
(
MediaSource
&
sender
,
Recorder
::
type
type
)
override
;
protected
:
std
::
weak_ptr
<
MediaSourceEvent
>
_listener
;
};
/**
* 解析url获取媒体相关信息
*/
class
MediaInfo
{
public
:
MediaInfo
()
{}
~
MediaInfo
()
{}
MediaInfo
(
const
string
&
url
){
parse
(
url
);
}
~
MediaInfo
()
{}
MediaInfo
()
{}
MediaInfo
(
const
string
&
url
)
{
parse
(
url
);
}
void
parse
(
const
string
&
url
);
public
:
string
_schema
;
string
_host
;
...
...
@@ -92,7 +113,7 @@ public:
typedef
unordered_map
<
string
,
AppStreamMap
>
VhostAppStreamMap
;
typedef
unordered_map
<
string
,
VhostAppStreamMap
>
SchemaVhostAppStreamMap
;
MediaSource
(
const
string
&
s
trSchema
,
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strI
d
)
;
MediaSource
(
const
string
&
s
chema
,
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream_i
d
)
;
virtual
~
MediaSource
()
;
// 获取协议类型
...
...
@@ -107,7 +128,7 @@ public:
// 设置TrackSource
void
setTrackSource
(
const
std
::
weak_ptr
<
TrackSource
>
&
track_src
);
// 获取所有Track
vector
<
Track
::
Ptr
>
getTracks
(
bool
trackR
eady
=
true
)
const
override
;
vector
<
Track
::
Ptr
>
getTracks
(
bool
r
eady
=
true
)
const
override
;
// 设置监听者
virtual
void
setListener
(
const
std
::
weak_ptr
<
MediaSourceEvent
>
&
listener
);
...
...
@@ -120,12 +141,12 @@ public:
virtual
int
totalReaderCount
();
// 获取流当前时间戳
virtual
uint32_t
getTimeStamp
(
TrackType
t
rackT
ype
)
{
return
0
;
};
virtual
uint32_t
getTimeStamp
(
TrackType
type
)
{
return
0
;
};
// 设置时间戳
virtual
void
setTimeStamp
(
uint32_t
uiS
tamp
)
{};
virtual
void
setTimeStamp
(
uint32_t
s
tamp
)
{};
// 拖动进度条
bool
seekTo
(
uint32_t
ui32S
tamp
);
bool
seekTo
(
uint32_t
s
tamp
);
// 关闭该流
bool
close
(
bool
force
);
// 该流无人观看
...
...
@@ -141,26 +162,26 @@ public:
static
void
findAsync
(
const
MediaInfo
&
info
,
const
std
::
shared_ptr
<
TcpSession
>
&
session
,
const
function
<
void
(
const
Ptr
&
src
)
>
&
cb
);
// 遍历所有流
static
void
for_each_media
(
const
function
<
void
(
const
Ptr
&
src
)
>
&
cb
);
// 从mp4文件生成MediaSource
static
MediaSource
::
Ptr
createFromMP4
(
const
string
&
schema
,
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream
,
const
string
&
file
Path
=
""
,
bool
checkA
pp
=
true
);
static
MediaSource
::
Ptr
createFromMP4
(
const
string
&
schema
,
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream
,
const
string
&
file
_path
=
""
,
bool
check_a
pp
=
true
);
protected
:
void
regist
()
;
bool
un
regist
();
//媒体注册
void
regist
();
private
:
static
Ptr
find_l
(
const
string
&
schema
,
const
string
&
vhost
,
const
string
&
app
,
const
string
&
id
,
bool
bMake
);
static
void
findAsync_l
(
const
MediaInfo
&
info
,
const
std
::
shared_ptr
<
TcpSession
>
&
session
,
bool
retry
,
const
function
<
void
(
const
MediaSource
::
Ptr
&
src
)
>
&
cb
);
//媒体注销
bool
unregist
();
//触发媒体事件
void
emitEvent
(
bool
regist
);
private
:
string
_strSchema
;
string
_strVhost
;
string
_strApp
;
string
_strId
;
std
::
weak_ptr
<
MediaSourceEvent
>
_listener
;
string
_schema
;
string
_vhost
;
string
_app
;
string
_stream_id
;
weak_ptr
<
TrackSource
>
_track_source
;
static
SchemaVhostAppStreamMap
g_mapMediaSrc
;
static
recursive_mutex
g_mtxMediaSrc
;
std
::
weak_ptr
<
MediaSourceEvent
>
_listener
;
};
///缓存刷新策略类
...
...
@@ -221,9 +242,9 @@ private:
}
private
:
bool
_key_pos
=
false
;
policy
_policy
;
std
::
shared_ptr
<
packet_list
>
_cache
;
bool
_key_pos
=
false
;
};
}
/* namespace mediakit */
...
...
src/Common/MultiMediaSourceMuxer.cpp
查看文件 @
eca92369
...
...
@@ -11,15 +11,11 @@
#include "MultiMediaSourceMuxer.h"
namespace
mediakit
{
///////////////////////////////MultiMuxerPrivate//////////////////////////////////
MultiMuxerPrivate
::~
MultiMuxerPrivate
()
{}
MultiMuxerPrivate
::
MultiMuxerPrivate
(
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream
,
float
dur_sec
,
bool
enable_rtsp
,
bool
enable_rtmp
,
bool
enable_hls
,
bool
enable_mp4
)
{
MultiMuxerPrivate
::
MultiMuxerPrivate
(
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream
,
float
dur_sec
,
bool
enable_rtsp
,
bool
enable_rtmp
,
bool
enable_hls
,
bool
enable_mp4
)
{
if
(
enable_rtmp
)
{
_rtmp
=
std
::
make_shared
<
RtmpMediaSourceMuxer
>
(
vhost
,
app
,
stream
,
std
::
make_shared
<
TitleMeta
>
(
dur_sec
));
_enable_rtxp
=
true
;
...
...
@@ -73,7 +69,7 @@ void MultiMuxerPrivate::setMediaListener(const std::weak_ptr<MediaSourceEvent> &
if
(
hls_src
)
{
hls_src
->
setListener
(
listener
);
}
_
meida_
listener
=
listener
;
_listener
=
listener
;
}
int
MultiMuxerPrivate
::
totalReaderCount
()
const
{
...
...
@@ -99,7 +95,7 @@ bool MultiMuxerPrivate::setupRecord(MediaSource &sender, Recorder::type type, bo
auto
hls_src
=
getHlsMediaSource
();
if
(
hls_src
)
{
//设置HlsMediaSource的事件监听器
hls_src
->
setListener
(
_
meida_
listener
);
hls_src
->
setListener
(
_listener
);
hls_src
->
setTrackSource
(
shared_from_this
());
}
}
else
if
(
!
start
&&
_hls
)
{
...
...
@@ -146,7 +142,7 @@ void MultiMuxerPrivate::setTimeStamp(uint32_t stamp) {
}
void
MultiMuxerPrivate
::
setTrackListener
(
Listener
*
listener
)
{
_listener
=
listener
;
_
track_
listener
=
listener
;
}
void
MultiMuxerPrivate
::
onTrackReady
(
const
Track
::
Ptr
&
track
)
{
...
...
@@ -206,8 +202,8 @@ void MultiMuxerPrivate::onAllTrackReady() {
hls_src
->
setTrackSource
(
shared_from_this
());
}
if
(
_listener
)
{
_listener
->
onAllTrackReady
();
if
(
_
track_
listener
)
{
_
track_
listener
->
onAllTrackReady
();
}
}
...
...
@@ -219,22 +215,18 @@ MediaSource::Ptr MultiMuxerPrivate::getHlsMediaSource() const {
return
nullptr
;
}
/////////////////////////////////////////////////////////////////
///////////////////////////////
MultiMediaSourceMuxer
//////////////////////////////////
MultiMediaSourceMuxer
::~
MultiMediaSourceMuxer
()
{}
MultiMediaSourceMuxer
::
MultiMediaSourceMuxer
(
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream
,
float
dur_sec
,
bool
enable_rtsp
,
bool
enable_rtmp
,
bool
enable_hls
,
bool
enable_mp4
)
{
MultiMediaSourceMuxer
::
MultiMediaSourceMuxer
(
const
string
&
vhost
,
const
string
&
app
,
const
string
&
stream
,
float
dur_sec
,
bool
enable_rtsp
,
bool
enable_rtmp
,
bool
enable_hls
,
bool
enable_mp4
)
{
_muxer
.
reset
(
new
MultiMuxerPrivate
(
vhost
,
app
,
stream
,
dur_sec
,
enable_rtsp
,
enable_rtmp
,
enable_hls
,
enable_mp4
));
_muxer
->
setTrackListener
(
this
);
}
void
MultiMediaSourceMuxer
::
setMediaListener
(
const
std
::
weak_ptr
<
MediaSourceEvent
>
&
listener
)
{
//拦截事件
_muxer
->
setMediaListener
(
shared_from_this
());
_listener
=
listener
;
}
...
...
@@ -255,46 +247,14 @@ vector<Track::Ptr> MultiMediaSourceMuxer::getTracks(bool trackReady) const {
return
_muxer
->
getTracks
(
trackReady
);
}
bool
MultiMediaSourceMuxer
::
seekTo
(
MediaSource
&
sender
,
uint32_t
ui32Stamp
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
return
false
;
}
return
listener
->
seekTo
(
sender
,
ui32Stamp
);
}
bool
MultiMediaSourceMuxer
::
close
(
MediaSource
&
sender
,
bool
force
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
return
false
;
}
return
listener
->
close
(
sender
,
force
);
}
int
MultiMediaSourceMuxer
::
totalReaderCount
(
MediaSource
&
sender
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
return
_muxer
->
totalReaderCount
();
return
totalReaderCount
();
}
return
listener
->
totalReaderCount
(
sender
);
}
void
MultiMediaSourceMuxer
::
onNoneReader
(
MediaSource
&
sender
){
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
MediaSourceEvent
::
onNoneReader
(
sender
);
return
;
}
listener
->
onNoneReader
(
sender
);
}
void
MultiMediaSourceMuxer
::
onRegist
(
MediaSource
&
sender
,
bool
regist
){
auto
listener
=
_listener
.
lock
();
if
(
listener
)
{
listener
->
onRegist
(
sender
,
regist
);
}
}
bool
MultiMediaSourceMuxer
::
setupRecord
(
MediaSource
&
sender
,
Recorder
::
type
type
,
bool
start
,
const
string
&
custom_path
)
{
return
_muxer
->
setupRecord
(
sender
,
type
,
start
,
custom_path
);
}
...
...
@@ -313,9 +273,9 @@ void MultiMediaSourceMuxer::addTrackCompleted() {
void
MultiMediaSourceMuxer
::
onAllTrackReady
(){
_muxer
->
setMediaListener
(
shared_from_this
());
auto
track_
listener
=
_track_listener
.
lock
();
if
(
track_
listener
){
track_
listener
->
onAllTrackReady
();
auto
listener
=
_track_listener
.
lock
();
if
(
listener
){
listener
->
onAllTrackReady
();
}
}
...
...
@@ -370,19 +330,19 @@ public:
return
_frame
->
getCodecId
();
}
private
:
Frame
::
Ptr
_frame
;
int64_t
_dts
;
int64_t
_pts
;
Frame
::
Ptr
_frame
;
};
void
MultiMediaSourceMuxer
::
inputFrame
(
const
Frame
::
Ptr
&
frame
)
{
GET_CONFIG
(
bool
,
modify_stamp
,
General
::
kModifyStamp
);
if
(
!
modify_stamp
)
{
GET_CONFIG
(
bool
,
modify_stamp
,
General
::
kModifyStamp
);
if
(
!
modify_stamp
)
{
//未开启时间戳覆盖
_muxer
->
inputFrame
(
frame
);
}
else
{
}
else
{
//开启了时间戳覆盖
FrameModifyStamp
::
Ptr
new_frame
=
std
::
make_shared
<
FrameModifyStamp
>
(
frame
,
_stamp
[
frame
->
getTrackType
()]);
FrameModifyStamp
::
Ptr
new_frame
=
std
::
make_shared
<
FrameModifyStamp
>
(
frame
,
_stamp
[
frame
->
getTrackType
()]);
//输入时间戳覆盖后的帧
_muxer
->
inputFrame
(
new_frame
);
}
...
...
src/Common/MultiMediaSourceMuxer.h
查看文件 @
eca92369
...
...
@@ -17,7 +17,7 @@
#include "Record/HlsRecorder.h"
namespace
mediakit
{
class
MultiMuxerPrivate
:
public
MediaSink
,
public
std
::
enable_shared_from_this
<
MultiMuxerPrivate
>
{
class
MultiMuxerPrivate
:
public
MediaSink
,
public
std
::
enable_shared_from_this
<
MultiMuxerPrivate
>
{
public
:
friend
class
MultiMediaSourceMuxer
;
typedef
std
::
shared_ptr
<
MultiMuxerPrivate
>
Ptr
;
...
...
@@ -47,17 +47,17 @@ private:
MediaSource
::
Ptr
getHlsMediaSource
()
const
;
private
:
bool
_enable_rtxp
=
false
;
bool
_enable_record
=
false
;
Listener
*
_track_listener
=
nullptr
;
RtmpMediaSourceMuxer
::
Ptr
_rtmp
;
RtspMediaSourceMuxer
::
Ptr
_rtsp
;
MediaSinkInterface
::
Ptr
_hls
;
MediaSinkInterface
::
Ptr
_mp4
;
Listener
*
_listener
=
nullptr
;
std
::
weak_ptr
<
MediaSourceEvent
>
_meida_listener
;
bool
_enable_rtxp
=
false
;
bool
_enable_record
=
false
;
std
::
weak_ptr
<
MediaSourceEvent
>
_listener
;
};
class
MultiMediaSourceMuxer
:
public
MediaSourceEvent
,
public
MediaSinkInterface
,
public
TrackSource
,
public
MultiMuxerPrivate
::
Listener
,
public
std
::
enable_shared_from_this
<
MultiMediaSourceMuxer
>
{
class
MultiMediaSourceMuxer
:
public
MediaSourceEvent
Interceptor
,
public
MediaSinkInterface
,
public
TrackSource
,
public
MultiMuxerPrivate
::
Listener
,
public
std
::
enable_shared_from_this
<
MultiMediaSourceMuxer
>
{
public
:
typedef
MultiMuxerPrivate
::
Listener
Listener
;
typedef
std
::
shared_ptr
<
MultiMediaSourceMuxer
>
Ptr
;
...
...
@@ -84,11 +84,18 @@ public:
int
totalReaderCount
()
const
;
/**
* 判断是否生效(是否正在转其他协议)
*/
bool
isEnabled
();
/**
* 设置MediaSource时间戳
* @param stamp 时间戳
*/
void
setTimeStamp
(
uint32_t
stamp
);
/////////////////////////////////TrackSource override/////////////////////////////////
/**
* 获取所有Track
* @param trackReady 是否筛选过滤未就绪的track
...
...
@@ -96,21 +103,7 @@ public:
*/
vector
<
Track
::
Ptr
>
getTracks
(
bool
trackReady
=
true
)
const
override
;
/**
* 通知拖动进度条
* @param sender 事件发送者
* @param ui32Stamp 目标时间戳
* @return 是否成功
*/
bool
seekTo
(
MediaSource
&
sender
,
uint32_t
ui32Stamp
)
override
;
/**
* 通知停止流生成
* @param sender 事件发送者
* @param force 是否强制关闭
* @return 成功与否
*/
bool
close
(
MediaSource
&
sender
,
bool
force
)
override
;
/////////////////////////////////MediaSourceEvent override/////////////////////////////////
/**
* 观看总人数
...
...
@@ -120,19 +113,6 @@ public:
int
totalReaderCount
(
MediaSource
&
sender
)
override
;
/**
* 触发无人观看事件
* @param sender 触发者
*/
void
onNoneReader
(
MediaSource
&
sender
)
override
;
/**
* 媒体注册注销事件
* @param sender 触发者
* @param regist 是否为注册事件
*/
void
onRegist
(
MediaSource
&
sender
,
bool
regist
)
override
;
/**
* 设置录制状态
* @param type 录制类型
* @param start 开始或停止
...
...
@@ -148,6 +128,8 @@ public:
*/
bool
isRecording
(
MediaSource
&
sender
,
Recorder
::
type
type
)
override
;
/////////////////////////////////MediaSinkInterface override/////////////////////////////////
/**
* 添加track,内部会调用Track的clone方法
* 只会克隆sps pps这些信息 ,而不会克隆Delegate相关关系
...
...
@@ -158,12 +140,7 @@ public:
/**
* 添加track完毕
*/
void
addTrackCompleted
();
/**
* 所有track全部就绪
*/
void
onAllTrackReady
()
override
;
void
addTrackCompleted
()
override
;
/**
* 重置track
...
...
@@ -176,16 +153,17 @@ public:
*/
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
/////////////////////////////////MultiMuxerPrivate::Listener override/////////////////////////////////
/**
*
判断是否生效(是否正在转其他协议)
*
所有track全部就绪
*/
bool
isEnabled
()
;
void
onAllTrackReady
()
override
;
private
:
Stamp
_stamp
[
2
];
MultiMuxerPrivate
::
Ptr
_muxer
;
std
::
weak_ptr
<
MediaSourceEvent
>
_listener
;
std
::
weak_ptr
<
MultiMuxerPrivate
::
Listener
>
_track_listener
;
Stamp
_stamp
[
2
];
};
}
//namespace mediakit
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论