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
b0bf216b
Commit
b0bf216b
authored
May 27, 2019
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加无人观看主动断开事件
parent
3917b645
显示空白字符变更
内嵌
并排
正在显示
21 个修改的文件
包含
209 行增加
和
47 行删除
+209
-47
server/WebApi.cpp
+9
-2
server/WebHook.cpp
+26
-1
src/Common/MediaSource.h
+11
-9
src/Common/config.cpp
+4
-0
src/Common/config.h
+9
-0
src/MediaFile/MediaReader.cpp
+11
-1
src/MediaFile/MediaReader.h
+4
-2
src/Player/PlayerProxy.cpp
+11
-1
src/Player/PlayerProxy.h
+2
-1
src/Rtmp/RtmpMediaSource.h
+49
-10
src/Rtmp/RtmpSession.cpp
+1
-1
src/Rtmp/RtmpSession.h
+4
-1
src/Rtmp/RtmpToRtspMediaSource.h
+1
-1
src/RtmpMuxer/RtmpMediaSourceMuxer.h
+1
-1
src/Rtsp/RtspMediaSource.h
+45
-5
src/Rtsp/RtspSession.cpp
+4
-1
src/Rtsp/RtspSession.h
+1
-1
src/Rtsp/RtspToRtmpMediaSource.h
+2
-3
src/RtspMuxer/RtspMediaSourceMuxer.h
+4
-3
src/Shell/ShellCMD.cpp
+7
-3
src/Shell/ShellSession.cpp
+3
-0
没有找到文件。
server/WebApi.cpp
查看文件 @
b0bf216b
...
@@ -343,7 +343,7 @@ void installWebApi() {
...
@@ -343,7 +343,7 @@ void installWebApi() {
});
});
//主动关断流,包括关断拉流、推流
//主动关断流,包括关断拉流、推流
//测试url http://127.0.0.1/index/api/close_stream?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs
//测试url http://127.0.0.1/index/api/close_stream?schema=rtsp&vhost=__defaultVhost__&app=live&stream=obs
&force=1
API_REGIST
(
api
,
close_stream
,{
API_REGIST
(
api
,
close_stream
,{
CHECK_SECRET
();
CHECK_SECRET
();
CHECK_ARGS
(
"schema"
,
"vhost"
,
"app"
,
"stream"
);
CHECK_ARGS
(
"schema"
,
"vhost"
,
"app"
,
"stream"
);
...
@@ -353,7 +353,7 @@ void installWebApi() {
...
@@ -353,7 +353,7 @@ void installWebApi() {
allArgs
[
"app"
],
allArgs
[
"app"
],
allArgs
[
"stream"
]);
allArgs
[
"stream"
]);
if
(
src
){
if
(
src
){
bool
flag
=
src
->
close
();
bool
flag
=
src
->
close
(
allArgs
[
"force"
].
as
<
bool
>
()
);
val
[
"code"
]
=
flag
?
0
:
-
1
;
val
[
"code"
]
=
flag
?
0
:
-
1
;
val
[
"msg"
]
=
flag
?
"success"
:
"close failed"
;
val
[
"msg"
]
=
flag
?
"success"
:
"close failed"
;
}
else
{
}
else
{
...
@@ -511,6 +511,13 @@ void installWebApi() {
...
@@ -511,6 +511,13 @@ void installWebApi() {
//shell登录调试事件
//shell登录调试事件
throw
SuccessException
();
throw
SuccessException
();
});
});
API_REGIST
(
hook
,
on_stream_none_reader
,{
//无人观看流默认关闭
val
[
"close"
]
=
true
;
});
}
}
void
unInstallWebApi
(){
void
unInstallWebApi
(){
...
...
server/WebHook.cpp
查看文件 @
b0bf216b
...
@@ -42,6 +42,7 @@ const char kOnStreamChanged[] = HOOK_FIELD"on_stream_changed";
...
@@ -42,6 +42,7 @@ const char kOnStreamChanged[] = HOOK_FIELD"on_stream_changed";
const
char
kOnStreamNotFound
[]
=
HOOK_FIELD
"on_stream_not_found"
;
const
char
kOnStreamNotFound
[]
=
HOOK_FIELD
"on_stream_not_found"
;
const
char
kOnRecordMp4
[]
=
HOOK_FIELD
"on_record_mp4"
;
const
char
kOnRecordMp4
[]
=
HOOK_FIELD
"on_record_mp4"
;
const
char
kOnShellLogin
[]
=
HOOK_FIELD
"on_shell_login"
;
const
char
kOnShellLogin
[]
=
HOOK_FIELD
"on_shell_login"
;
const
char
kOnStreamNoneReader
[]
=
HOOK_FIELD
"on_stream_none_reader"
;
const
char
kAdminParams
[]
=
HOOK_FIELD
"admin_params"
;
const
char
kAdminParams
[]
=
HOOK_FIELD
"admin_params"
;
onceToken
token
([](){
onceToken
token
([](){
...
@@ -56,6 +57,7 @@ onceToken token([](){
...
@@ -56,6 +57,7 @@ onceToken token([](){
mINI
::
Instance
()[
kOnStreamNotFound
]
=
"https://127.0.0.1/index/hook/on_stream_not_found"
;
mINI
::
Instance
()[
kOnStreamNotFound
]
=
"https://127.0.0.1/index/hook/on_stream_not_found"
;
mINI
::
Instance
()[
kOnRecordMp4
]
=
"https://127.0.0.1/index/hook/on_record_mp4"
;
mINI
::
Instance
()[
kOnRecordMp4
]
=
"https://127.0.0.1/index/hook/on_record_mp4"
;
mINI
::
Instance
()[
kOnShellLogin
]
=
"https://127.0.0.1/index/hook/on_shell_login"
;
mINI
::
Instance
()[
kOnShellLogin
]
=
"https://127.0.0.1/index/hook/on_shell_login"
;
mINI
::
Instance
()[
kOnStreamNoneReader
]
=
"https://127.0.0.1/index/hook/on_stream_none_reader"
;
mINI
::
Instance
()[
kAdminParams
]
=
"secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc"
;
mINI
::
Instance
()[
kAdminParams
]
=
"secret=035c73f7-bb6b-4889-a715-d9eb2d1925cc"
;
},
nullptr
);
},
nullptr
);
}
//namespace Hook
}
//namespace Hook
...
@@ -159,7 +161,7 @@ void installWebHook(){
...
@@ -159,7 +161,7 @@ void installWebHook(){
GET_CONFIG_AND_REGISTER
(
string
,
hook_stream_not_found
,
Hook
::
kOnStreamNotFound
);
GET_CONFIG_AND_REGISTER
(
string
,
hook_stream_not_found
,
Hook
::
kOnStreamNotFound
);
GET_CONFIG_AND_REGISTER
(
string
,
hook_record_mp4
,
Hook
::
kOnRecordMp4
);
GET_CONFIG_AND_REGISTER
(
string
,
hook_record_mp4
,
Hook
::
kOnRecordMp4
);
GET_CONFIG_AND_REGISTER
(
string
,
hook_shell_login
,
Hook
::
kOnShellLogin
);
GET_CONFIG_AND_REGISTER
(
string
,
hook_shell_login
,
Hook
::
kOnShellLogin
);
GET_CONFIG_AND_REGISTER
(
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
()){
...
@@ -325,6 +327,29 @@ void installWebHook(){
...
@@ -325,6 +327,29 @@ void installWebHook(){
});
});
});
});
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastStreamNoneReader
,[](
BroadcastStreamNoneReaderArgs
){
if
(
!
hook_enable
||
hook_stream_none_reader
.
empty
()){
return
;
}
ArgsType
body
;
body
[
"schema"
]
=
sender
.
getSchema
();
body
[
"vhost"
]
=
sender
.
getVhost
();
body
[
"app"
]
=
sender
.
getApp
();
body
[
"stream"
]
=
sender
.
getId
();
weak_ptr
<
MediaSource
>
weakSrc
=
sender
.
shared_from_this
();
//执行hook
do_http_hook
(
hook_stream_none_reader
,
body
,
[
weakSrc
](
const
Value
&
obj
,
const
string
&
err
){
bool
flag
=
obj
[
"close"
].
asBool
();
auto
strongSrc
=
weakSrc
.
lock
();
if
(
!
flag
||
!
err
.
empty
()
||
!
strongSrc
){
return
;
}
strongSrc
->
close
(
false
);
});
});
}
}
void
unInstallWebHook
(){
void
unInstallWebHook
(){
...
...
src/Common/MediaSource.h
查看文件 @
b0bf216b
...
@@ -44,8 +44,8 @@ using namespace toolkit;
...
@@ -44,8 +44,8 @@ using namespace toolkit;
namespace
mediakit
{
namespace
mediakit
{
class
MediaSource
Event
class
MediaSource
;
{
class
MediaSourceEvent
{
public
:
public
:
MediaSourceEvent
(){};
MediaSourceEvent
(){};
virtual
~
MediaSourceEvent
(){};
virtual
~
MediaSourceEvent
(){};
...
@@ -55,15 +55,18 @@ public:
...
@@ -55,15 +55,18 @@ public:
return
false
;
return
false
;
}
}
virtual
bool
close
()
{
virtual
bool
close
(
bool
force
)
{
//通知其停止推流
//通知其停止推流
return
false
;
return
false
;
}
}
virtual
void
onReaderChanged
(
const
EventPoller
::
Ptr
&
poller
,
int
size
,
bool
add_flag
){}
virtual
void
onNoneReader
(
MediaSource
&
sender
){
//没有任何读取器消费该源,表明该源可以关闭了
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastStreamNoneReader
,
sender
);
}
};
};
class
MediaInfo
{
class
MediaInfo
{
public
:
public
:
MediaInfo
(){}
MediaInfo
(){}
MediaInfo
(
const
string
&
url
){
MediaInfo
(
const
string
&
url
){
...
@@ -85,7 +88,6 @@ public:
...
@@ -85,7 +88,6 @@ public:
string
_streamid
;
string
_streamid
;
StrCaseMap
_params
;
StrCaseMap
_params
;
string
_param_strs
;
string
_param_strs
;
};
};
...
@@ -144,12 +146,12 @@ public:
...
@@ -144,12 +146,12 @@ public:
virtual
uint32_t
getTimeStamp
(
TrackType
trackType
)
=
0
;
virtual
uint32_t
getTimeStamp
(
TrackType
trackType
)
=
0
;
bool
close
()
{
bool
close
(
bool
force
)
{
auto
listener
=
_listener
.
lock
();
auto
listener
=
_listener
.
lock
();
if
(
!
listener
){
if
(
!
listener
){
return
false
;
return
false
;
}
}
return
listener
->
close
();
return
listener
->
close
(
force
);
}
}
virtual
void
setListener
(
const
std
::
weak_ptr
<
MediaSourceEvent
>
&
listener
){
virtual
void
setListener
(
const
std
::
weak_ptr
<
MediaSourceEvent
>
&
listener
){
_listener
=
listener
;
_listener
=
listener
;
...
...
src/Common/config.cpp
查看文件 @
b0bf216b
...
@@ -65,11 +65,15 @@ const char kBroadcastFlowReport[] = "kBroadcastFlowReport";
...
@@ -65,11 +65,15 @@ const char kBroadcastFlowReport[] = "kBroadcastFlowReport";
const
char
kBroadcastReloadConfig
[]
=
"kBroadcastReloadConfig"
;
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
kFlowThreshold
[]
=
"broadcast.flowThreshold"
;
const
char
kFlowThreshold
[]
=
"broadcast.flowThreshold"
;
const
char
kStreamNoneReaderDelayMS
[]
=
"broadcast.streamNoneReaderDelayMS"
;
onceToken
token
([](){
onceToken
token
([](){
mINI
::
Instance
()[
kFlowThreshold
]
=
1024
;
mINI
::
Instance
()[
kFlowThreshold
]
=
1024
;
mINI
::
Instance
()[
kStreamNoneReaderDelayMS
]
=
5
*
1000
;
},
nullptr
);
},
nullptr
);
}
//namespace Broadcast
}
//namespace Broadcast
...
...
src/Common/config.h
查看文件 @
b0bf216b
...
@@ -116,9 +116,18 @@ extern const char kBroadcastFlowReport[];
...
@@ -116,9 +116,18 @@ extern const char kBroadcastFlowReport[];
extern
const
char
kBroadcastNotFoundStream
[];
extern
const
char
kBroadcastNotFoundStream
[];
#define BroadcastNotFoundStreamArgs const MediaInfo &args,TcpSession &sender
#define BroadcastNotFoundStreamArgs const MediaInfo &args,TcpSession &sender
//某个流无人消费时触发,目的为了实现无人观看时主动断开拉流等业务逻辑
extern
const
char
kBroadcastStreamNoneReader
[];
#define BroadcastStreamNoneReaderArgs MediaSource &sender
//流量汇报事件流量阈值,单位KB,默认1MB
//流量汇报事件流量阈值,单位KB,默认1MB
extern
const
char
kFlowThreshold
[];
extern
const
char
kFlowThreshold
[];
//流无人观看并且超过若干时间后才触发kBroadcastStreamNoneReader事件
//默认连续5秒无人观看然后触发kBroadcastStreamNoneReader事件
extern
const
char
kStreamNoneReaderDelayMS
[];
//更新配置文件事件广播,执行loadIniConfig函数加载配置文件成功后会触发该广播
//更新配置文件事件广播,执行loadIniConfig函数加载配置文件成功后会触发该广播
extern
const
char
kBroadcastReloadConfig
[];
extern
const
char
kBroadcastReloadConfig
[];
#define BroadcastReloadConfigArgs void
#define BroadcastReloadConfigArgs void
...
...
src/MediaFile/MediaReader.cpp
查看文件 @
b0bf216b
...
@@ -166,11 +166,21 @@ void MediaReader::startReadMP4() {
...
@@ -166,11 +166,21 @@ void MediaReader::startReadMP4() {
seek
(
ui32Stamp
);
seek
(
ui32Stamp
);
return
true
;
return
true
;
}
}
bool
MediaReader
::
close
(){
bool
MediaReader
::
close
(
bool
force
){
if
(
!
force
&&
_mediaMuxer
->
readerCount
()
!=
0
){
return
false
;
}
_timer
.
reset
();
_timer
.
reset
();
return
true
;
return
true
;
}
}
void
MediaReader
::
onNoneReader
(
MediaSource
&
sender
)
{
if
(
_mediaMuxer
->
readerCount
()
!=
0
){
return
;
}
MediaSourceEvent
::
onNoneReader
(
sender
);
}
bool
MediaReader
::
readSample
(
int
iTimeInc
,
bool
justSeekSyncFrame
)
{
bool
MediaReader
::
readSample
(
int
iTimeInc
,
bool
justSeekSyncFrame
)
{
TimeTicker
();
TimeTicker
();
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
lock_guard
<
recursive_mutex
>
lck
(
_mtx
);
...
...
src/MediaFile/MediaReader.h
查看文件 @
b0bf216b
...
@@ -68,7 +68,7 @@ public:
...
@@ -68,7 +68,7 @@ public:
* 关闭MediaReader的流化进程,会触发该对象放弃自持有
* 关闭MediaReader的流化进程,会触发该对象放弃自持有
* @return
* @return
*/
*/
bool
close
()
override
;
bool
close
(
bool
force
)
override
;
/**
/**
* 自动生成MediaReader对象然后查找相关的MediaSource对象
* 自动生成MediaReader对象然后查找相关的MediaSource对象
...
@@ -86,8 +86,10 @@ public:
...
@@ -86,8 +86,10 @@ public:
const
string
&
strId
,
const
string
&
strId
,
const
string
&
filePath
=
""
,
const
string
&
filePath
=
""
,
bool
checkApp
=
true
);
bool
checkApp
=
true
);
#ifdef ENABLE_MP4V2
private
:
private
:
void
onNoneReader
(
MediaSource
&
sender
)
override
;
#ifdef ENABLE_MP4V2
void
seek
(
uint32_t
iSeekTime
,
bool
bReStart
=
true
);
void
seek
(
uint32_t
iSeekTime
,
bool
bReStart
=
true
);
inline
void
setSeekTime
(
uint32_t
iSeekTime
);
inline
void
setSeekTime
(
uint32_t
iSeekTime
);
inline
uint32_t
getVideoCurrentTime
();
inline
uint32_t
getVideoCurrentTime
();
...
...
src/Player/PlayerProxy.cpp
查看文件 @
b0bf216b
...
@@ -145,7 +145,11 @@ void PlayerProxy::rePlay(const string &strUrl,int iFailedCnt){
...
@@ -145,7 +145,11 @@ void PlayerProxy::rePlay(const string &strUrl,int iFailedCnt){
return
false
;
return
false
;
},
getPoller
());
},
getPoller
());
}
}
bool
PlayerProxy
::
close
()
{
bool
PlayerProxy
::
close
(
bool
force
)
{
if
(
!
force
&&
_mediaMuxer
->
readerCount
()
!=
0
){
return
false
;
}
//通知其停止推流
//通知其停止推流
weak_ptr
<
PlayerProxy
>
weakSlef
=
dynamic_pointer_cast
<
PlayerProxy
>
(
shared_from_this
());
weak_ptr
<
PlayerProxy
>
weakSlef
=
dynamic_pointer_cast
<
PlayerProxy
>
(
shared_from_this
());
getPoller
()
->
async_first
([
weakSlef
]()
{
getPoller
()
->
async_first
([
weakSlef
]()
{
...
@@ -161,6 +165,12 @@ bool PlayerProxy::close() {
...
@@ -161,6 +165,12 @@ bool PlayerProxy::close() {
return
true
;
return
true
;
}
}
void
PlayerProxy
::
onNoneReader
(
MediaSource
&
sender
)
{
if
(
_mediaMuxer
->
readerCount
()
!=
0
){
return
;
}
MediaSourceEvent
::
onNoneReader
(
sender
);
}
class
MuteAudioMaker
:
public
FrameRingInterfaceDelegate
{
class
MuteAudioMaker
:
public
FrameRingInterfaceDelegate
{
public
:
public
:
...
...
src/Player/PlayerProxy.h
查看文件 @
b0bf216b
...
@@ -79,8 +79,9 @@ public:
...
@@ -79,8 +79,9 @@ public:
* 被主动关闭
* 被主动关闭
* @return
* @return
*/
*/
bool
close
()
override
;
bool
close
(
bool
force
)
override
;
private
:
private
:
void
onNoneReader
(
MediaSource
&
sender
)
override
;
void
rePlay
(
const
string
&
strUrl
,
int
iFailedCnt
);
void
rePlay
(
const
string
&
strUrl
,
int
iFailedCnt
);
void
onPlaySuccess
();
void
onPlaySuccess
();
private
:
private
:
...
...
src/Rtmp/RtmpMediaSource.h
查看文件 @
b0bf216b
...
@@ -53,10 +53,13 @@ public:
...
@@ -53,10 +53,13 @@ public:
typedef
std
::
shared_ptr
<
RtmpMediaSource
>
Ptr
;
typedef
std
::
shared_ptr
<
RtmpMediaSource
>
Ptr
;
typedef
RingBuffer
<
RtmpPacket
::
Ptr
>
RingType
;
typedef
RingBuffer
<
RtmpPacket
::
Ptr
>
RingType
;
RtmpMediaSource
(
const
string
&
vhost
,
const
string
&
strApp
,
const
string
&
strId
,
int
ringSize
=
0
)
:
RtmpMediaSource
(
const
string
&
vhost
,
const
string
&
strApp
,
const
string
&
strId
,
int
ringSize
=
0
)
:
MediaSource
(
RTMP_SCHEMA
,
vhost
,
strApp
,
strId
),
MediaSource
(
RTMP_SCHEMA
,
vhost
,
strApp
,
strId
),
_
pRing
(
new
RingBuffer
<
RtmpPacket
::
Ptr
>
(
ringSize
))
{
_
ringSize
(
ringSize
)
{}
}
virtual
~
RtmpMediaSource
()
{}
virtual
~
RtmpMediaSource
()
{}
const
RingType
::
Ptr
&
getRing
()
const
{
const
RingType
::
Ptr
&
getRing
()
const
{
...
@@ -65,7 +68,7 @@ public:
...
@@ -65,7 +68,7 @@ public:
}
}
int
readerCount
()
override
{
int
readerCount
()
override
{
return
_pRing
->
readerCount
()
;
return
_pRing
?
_pRing
->
readerCount
()
:
0
;
}
}
const
AMFValue
&
getMetaData
()
const
{
const
AMFValue
&
getMetaData
()
const
{
...
@@ -89,14 +92,25 @@ public:
...
@@ -89,14 +92,25 @@ public:
lock_guard
<
recursive_mutex
>
lock
(
_mtxMap
);
lock_guard
<
recursive_mutex
>
lock
(
_mtxMap
);
if
(
pkt
->
isCfgFrame
())
{
if
(
pkt
->
isCfgFrame
())
{
_mapCfgFrame
[
pkt
->
typeId
]
=
pkt
;
_mapCfgFrame
[
pkt
->
typeId
]
=
pkt
;
}
else
{
return
;
if
(
!
_bRegisted
){
regist
();
_bRegisted
=
true
;
}
}
_mapStamp
[
pkt
->
typeId
]
=
pkt
->
timeStamp
;
_mapStamp
[
pkt
->
typeId
]
=
pkt
->
timeStamp
;
_pRing
->
write
(
pkt
,
pkt
->
isVideoKeyFrame
());
if
(
!
_pRing
){
weak_ptr
<
RtmpMediaSource
>
weakSelf
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
shared_from_this
());
_pRing
=
std
::
make_shared
<
RingType
>
(
_ringSize
,[
weakSelf
](
const
EventPoller
::
Ptr
&
,
int
size
,
bool
){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
;
}
strongSelf
->
onReaderChanged
(
size
);
});
onReaderChanged
(
0
);
regist
();
}
}
_pRing
->
write
(
pkt
,
pkt
->
isVideoKeyFrame
());
checkNoneReader
();
}
}
uint32_t
getTimeStamp
(
TrackType
trackType
)
override
{
uint32_t
getTimeStamp
(
TrackType
trackType
)
override
{
...
@@ -110,13 +124,38 @@ public:
...
@@ -110,13 +124,38 @@ public:
return
MAX
(
_mapStamp
[
MSG_VIDEO
],
_mapStamp
[
MSG_AUDIO
]);
return
MAX
(
_mapStamp
[
MSG_VIDEO
],
_mapStamp
[
MSG_AUDIO
]);
}
}
}
}
private
:
void
onReaderChanged
(
int
size
){
if
(
size
!=
0
||
readerCount
()
!=
0
){
//还有消费者正在观看该流,我们记录最后一次活动时间
_readerTicker
.
resetTime
();
_asyncEmitNoneReader
=
false
;
return
;
}
_asyncEmitNoneReader
=
true
;
}
void
checkNoneReader
(){
GET_CONFIG_AND_REGISTER
(
int
,
stream_none_reader_delay
,
Broadcast
::
kStreamNoneReaderDelayMS
);
if
(
_asyncEmitNoneReader
&&
_readerTicker
.
elapsedTime
()
>
stream_none_reader_delay
){
_asyncEmitNoneReader
=
false
;
auto
listener
=
_listener
.
lock
();
if
(
!
listener
){
return
;
}
listener
->
onNoneReader
(
*
this
);
}
}
protected
:
protected
:
AMFValue
_metadata
;
AMFValue
_metadata
;
unordered_map
<
int
,
RtmpPacket
::
Ptr
>
_mapCfgFrame
;
unordered_map
<
int
,
RtmpPacket
::
Ptr
>
_mapCfgFrame
;
unordered_map
<
int
,
uint32_t
>
_mapStamp
;
unordered_map
<
int
,
uint32_t
>
_mapStamp
;
mutable
recursive_mutex
_mtxMap
;
mutable
recursive_mutex
_mtxMap
;
RingBuffer
<
RtmpPacket
::
Ptr
>::
Ptr
_pRing
;
//rtp环形缓冲
RingBuffer
<
RtmpPacket
::
Ptr
>::
Ptr
_pRing
;
//rtp环形缓冲
bool
_bRegisted
=
false
;
int
_ringSize
;
Ticker
_readerTicker
;
bool
_asyncEmitNoneReader
=
false
;
};
};
}
/* namespace mediakit */
}
/* namespace mediakit */
...
...
src/Rtmp/RtmpSession.cpp
查看文件 @
b0bf216b
...
@@ -360,7 +360,7 @@ void RtmpSession::sendPlayResponse(const string &err,const RtmpMediaSource::Ptr
...
@@ -360,7 +360,7 @@ void RtmpSession::sendPlayResponse(const string &err,const RtmpMediaSource::Ptr
strongSelf
->
shutdown
();
strongSelf
->
shutdown
();
});
});
_pPlayerSrc
=
src
;
_pPlayerSrc
=
src
;
if
(
src
->
getRing
()
->
readerCount
()
==
1
)
{
if
(
src
->
readerCount
()
==
1
)
{
src
->
seekTo
(
0
);
src
->
seekTo
(
0
);
}
}
...
...
src/Rtmp/RtmpSession.h
查看文件 @
b0bf216b
...
@@ -81,7 +81,10 @@ private:
...
@@ -81,7 +81,10 @@ private:
sendResponse
(
MSG_CMD
,
invoke
.
data
());
sendResponse
(
MSG_CMD
,
invoke
.
data
());
}
}
bool
close
()
override
{
bool
close
(
bool
force
)
override
{
if
(
!
force
&&
_pPublisherSrc
->
readerCount
()
!=
0
){
return
false
;
}
InfoL
<<
"kick out:"
<<
_mediaInfo
.
_vhost
<<
" "
<<
_mediaInfo
.
_app
<<
" "
<<
_mediaInfo
.
_streamid
;
InfoL
<<
"kick out:"
<<
_mediaInfo
.
_vhost
<<
" "
<<
_mediaInfo
.
_app
<<
" "
<<
_mediaInfo
.
_streamid
;
safeShutdown
();
safeShutdown
();
return
true
;
return
true
;
...
...
src/Rtmp/RtmpToRtspMediaSource.h
查看文件 @
b0bf216b
...
@@ -91,7 +91,7 @@ public:
...
@@ -91,7 +91,7 @@ public:
}
}
int
readerCount
()
override
{
int
readerCount
()
override
{
return
RtmpMediaSource
::
readerCount
()
+
_rtspMuxer
->
readerCount
(
);
return
RtmpMediaSource
::
readerCount
()
+
(
_rtspMuxer
?
_rtspMuxer
->
readerCount
()
:
0
);
}
}
private
:
private
:
RtmpDemuxer
::
Ptr
_rtmpDemuxer
;
RtmpDemuxer
::
Ptr
_rtmpDemuxer
;
...
...
src/RtmpMuxer/RtmpMediaSourceMuxer.h
查看文件 @
b0bf216b
...
@@ -49,7 +49,7 @@ public:
...
@@ -49,7 +49,7 @@ public:
_mediaSouce
->
setListener
(
listener
);
_mediaSouce
->
setListener
(
listener
);
}
}
int
readerCount
()
const
{
int
readerCount
()
const
{
return
_mediaSouce
->
getRing
()
->
readerCount
();
return
_mediaSouce
->
readerCount
();
}
}
private
:
private
:
void
onAllTrackReady
()
override
{
void
onAllTrackReady
()
override
{
...
...
src/Rtsp/RtspMediaSource.h
查看文件 @
b0bf216b
...
@@ -55,10 +55,13 @@ public:
...
@@ -55,10 +55,13 @@ public:
typedef
std
::
shared_ptr
<
RtspMediaSource
>
Ptr
;
typedef
std
::
shared_ptr
<
RtspMediaSource
>
Ptr
;
typedef
RingBuffer
<
RtpPacket
::
Ptr
>
RingType
;
typedef
RingBuffer
<
RtpPacket
::
Ptr
>
RingType
;
RtspMediaSource
(
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strId
,
int
ringSize
=
0
)
:
RtspMediaSource
(
const
string
&
strVhost
,
const
string
&
strApp
,
const
string
&
strId
,
int
ringSize
=
0
)
:
MediaSource
(
RTSP_SCHEMA
,
strVhost
,
strApp
,
strId
),
MediaSource
(
RTSP_SCHEMA
,
strVhost
,
strApp
,
strId
),
_
pRing
(
new
RingBuffer
<
RtpPacket
::
Ptr
>
(
ringSize
))
{
_
ringSize
(
ringSize
){}
}
virtual
~
RtspMediaSource
()
{}
virtual
~
RtspMediaSource
()
{}
const
RingType
::
Ptr
&
getRing
()
const
{
const
RingType
::
Ptr
&
getRing
()
const
{
...
@@ -67,7 +70,7 @@ public:
...
@@ -67,7 +70,7 @@ public:
}
}
int
readerCount
()
override
{
int
readerCount
()
override
{
return
_pRing
->
readerCount
()
;
return
_pRing
?
_pRing
->
readerCount
()
:
0
;
}
}
const
string
&
getSdp
()
const
{
const
string
&
getSdp
()
const
{
...
@@ -114,7 +117,6 @@ public:
...
@@ -114,7 +117,6 @@ public:
//派生类设置该媒体源媒体描述信息
//派生类设置该媒体源媒体描述信息
_strSdp
=
sdp
;
_strSdp
=
sdp
;
_sdpAttr
.
load
(
sdp
);
_sdpAttr
.
load
(
sdp
);
regist
();
}
}
void
onWrite
(
const
RtpPacket
::
Ptr
&
rtppt
,
bool
keyPos
)
override
{
void
onWrite
(
const
RtpPacket
::
Ptr
&
rtppt
,
bool
keyPos
)
override
{
...
@@ -124,12 +126,50 @@ public:
...
@@ -124,12 +126,50 @@ public:
track
->
_time_stamp
=
rtppt
->
timeStamp
;
track
->
_time_stamp
=
rtppt
->
timeStamp
;
track
->
_ssrc
=
rtppt
->
ssrc
;
track
->
_ssrc
=
rtppt
->
ssrc
;
}
}
if
(
!
_pRing
){
weak_ptr
<
RtspMediaSource
>
weakSelf
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
shared_from_this
());
_pRing
=
std
::
make_shared
<
RingType
>
(
_ringSize
,[
weakSelf
](
const
EventPoller
::
Ptr
&
,
int
size
,
bool
){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
;
}
strongSelf
->
onReaderChanged
(
size
);
});
onReaderChanged
(
0
);
regist
();
}
_pRing
->
write
(
rtppt
,
keyPos
);
_pRing
->
write
(
rtppt
,
keyPos
);
checkNoneReader
();
}
private
:
void
onReaderChanged
(
int
size
){
if
(
size
!=
0
||
readerCount
()
!=
0
){
//还有消费者正在观看该流,我们记录最后一次活动时间
_readerTicker
.
resetTime
();
_asyncEmitNoneReader
=
false
;
return
;
}
_asyncEmitNoneReader
=
true
;
}
void
checkNoneReader
(){
GET_CONFIG_AND_REGISTER
(
int
,
stream_none_reader_delay
,
Broadcast
::
kStreamNoneReaderDelayMS
);
if
(
_asyncEmitNoneReader
&&
_readerTicker
.
elapsedTime
()
>
stream_none_reader_delay
){
_asyncEmitNoneReader
=
false
;
auto
listener
=
_listener
.
lock
();
if
(
!
listener
){
return
;
}
listener
->
onNoneReader
(
*
this
);
}
}
}
protected
:
protected
:
SdpAttr
_sdpAttr
;
SdpAttr
_sdpAttr
;
string
_strSdp
;
//媒体描述信息
string
_strSdp
;
//媒体描述信息
RingType
::
Ptr
_pRing
;
//rtp环形缓冲
RingType
::
Ptr
_pRing
;
//rtp环形缓冲
int
_ringSize
;
Ticker
_readerTicker
;
bool
_asyncEmitNoneReader
=
false
;
};
};
}
/* namespace mediakit */
}
/* namespace mediakit */
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
b0bf216b
...
@@ -1161,7 +1161,10 @@ inline int RtspSession::getTrackIndexByInterleaved(int interleaved){
...
@@ -1161,7 +1161,10 @@ inline int RtspSession::getTrackIndexByInterleaved(int interleaved){
return
-
1
;
return
-
1
;
}
}
bool
RtspSession
::
close
()
{
bool
RtspSession
::
close
(
bool
force
)
{
if
(
!
force
&&
_pushSrc
->
readerCount
()
!=
0
){
return
false
;
}
InfoL
<<
"kick out:"
<<
_mediaInfo
.
_vhost
<<
" "
<<
_mediaInfo
.
_app
<<
" "
<<
_mediaInfo
.
_streamid
;
InfoL
<<
"kick out:"
<<
_mediaInfo
.
_vhost
<<
" "
<<
_mediaInfo
.
_app
<<
" "
<<
_mediaInfo
.
_streamid
;
safeShutdown
();
safeShutdown
();
return
true
;
return
true
;
...
...
src/Rtsp/RtspSession.h
查看文件 @
b0bf216b
...
@@ -105,7 +105,7 @@ protected:
...
@@ -105,7 +105,7 @@ protected:
//RtpReceiver override
//RtpReceiver override
void
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtppt
,
int
trackidx
)
override
;
void
onRtpSorted
(
const
RtpPacket
::
Ptr
&
rtppt
,
int
trackidx
)
override
;
//MediaSourceEvent override
//MediaSourceEvent override
bool
close
()
override
;
bool
close
(
bool
force
)
override
;
//TcpSession override
//TcpSession override
int
send
(
const
Buffer
::
Ptr
&
pkt
)
override
;
int
send
(
const
Buffer
::
Ptr
&
pkt
)
override
;
...
...
src/Rtsp/RtspToRtmpMediaSource.h
查看文件 @
b0bf216b
...
@@ -65,8 +65,7 @@ public:
...
@@ -65,8 +65,7 @@ public:
_rtmpMuxer
=
std
::
make_shared
<
RtmpMediaSourceMuxer
>
(
getVhost
(),
_rtmpMuxer
=
std
::
make_shared
<
RtmpMediaSourceMuxer
>
(
getVhost
(),
getApp
(),
getApp
(),
getId
(),
getId
(),
std
::
make_shared
<
TitleMete
>
(
std
::
make_shared
<
TitleMete
>
(
_rtspDemuxer
->
getDuration
()));
_rtspDemuxer
->
getDuration
()));
for
(
auto
&
track
:
_rtspDemuxer
->
getTracks
(
false
))
{
for
(
auto
&
track
:
_rtspDemuxer
->
getTracks
(
false
))
{
_rtmpMuxer
->
addTrack
(
track
);
_rtmpMuxer
->
addTrack
(
track
);
_recorder
->
addTrack
(
track
);
_recorder
->
addTrack
(
track
);
...
@@ -86,7 +85,7 @@ public:
...
@@ -86,7 +85,7 @@ public:
}
}
}
}
int
readerCount
()
override
{
int
readerCount
()
override
{
return
RtspMediaSource
::
readerCount
()
+
_rtmpMuxer
->
readerCount
(
);
return
RtspMediaSource
::
readerCount
()
+
(
_rtmpMuxer
?
_rtmpMuxer
->
readerCount
()
:
0
);
}
}
private
:
private
:
RtspDemuxer
::
Ptr
_rtspDemuxer
;
RtspDemuxer
::
Ptr
_rtspDemuxer
;
...
...
src/RtspMuxer/RtspMediaSourceMuxer.h
查看文件 @
b0bf216b
...
@@ -39,8 +39,9 @@ public:
...
@@ -39,8 +39,9 @@ public:
RtspMediaSourceMuxer
(
const
string
&
vhost
,
RtspMediaSourceMuxer
(
const
string
&
vhost
,
const
string
&
strApp
,
const
string
&
strApp
,
const
string
&
strId
,
const
string
&
strId
,
const
TitleSdp
::
Ptr
&
title
=
nullptr
)
:
RtspMuxer
(
title
){
const
TitleSdp
::
Ptr
&
title
=
nullptr
,
_mediaSouce
=
std
::
make_shared
<
RtspMediaSource
>
(
vhost
,
strApp
,
strId
);
bool
masterSrc
=
true
)
:
RtspMuxer
(
title
){
_mediaSouce
=
std
::
make_shared
<
RtspMediaSource
>
(
vhost
,
strApp
,
strId
,
0
,
masterSrc
);
getRtpRing
()
->
setDelegate
(
_mediaSouce
);
getRtpRing
()
->
setDelegate
(
_mediaSouce
);
}
}
virtual
~
RtspMediaSourceMuxer
(){}
virtual
~
RtspMediaSourceMuxer
(){}
...
@@ -49,7 +50,7 @@ public:
...
@@ -49,7 +50,7 @@ public:
_mediaSouce
->
setListener
(
listener
);
_mediaSouce
->
setListener
(
listener
);
}
}
int
readerCount
()
const
{
int
readerCount
()
const
{
return
_mediaSouce
->
getRing
()
->
readerCount
();
return
_mediaSouce
->
readerCount
();
}
}
void
setTimeStamp
(
uint32_t
stamp
){
void
setTimeStamp
(
uint32_t
stamp
){
_mediaSouce
->
setTimeStamp
(
stamp
);
_mediaSouce
->
setTimeStamp
(
stamp
);
...
...
src/Shell/ShellCMD.cpp
查看文件 @
b0bf216b
...
@@ -51,7 +51,7 @@ public:
...
@@ -51,7 +51,7 @@ public:
if
(
!
media
)
{
if
(
!
media
)
{
break
;
break
;
}
}
if
(
!
media
->
close
())
{
if
(
!
media
->
close
(
true
))
{
break
;
break
;
}
}
(
*
stream
)
<<
"
\t
踢出成功:"
(
*
stream
)
<<
"
\t
踢出成功:"
...
@@ -86,9 +86,12 @@ public:
...
@@ -86,9 +86,12 @@ public:
}
}
};
};
static
onceToken
s_token
([]()
{
void
installShellCMD
(){
static
onceToken
s_token
([]()
{
REGIST_CMD
(
media
);
REGIST_CMD
(
media
);
},
nullptr
);
},
nullptr
);
}
}
/* namespace mediakit */
}
/* namespace mediakit */
\ No newline at end of file
src/Shell/ShellSession.cpp
查看文件 @
b0bf216b
...
@@ -33,7 +33,10 @@ using namespace toolkit;
...
@@ -33,7 +33,10 @@ using namespace toolkit;
namespace
mediakit
{
namespace
mediakit
{
extern
void
installShellCMD
();
ShellSession
::
ShellSession
(
const
Socket
::
Ptr
&
_sock
)
:
TcpSession
(
_sock
)
{
ShellSession
::
ShellSession
(
const
Socket
::
Ptr
&
_sock
)
:
TcpSession
(
_sock
)
{
installShellCMD
();
pleaseInputUser
();
pleaseInputUser
();
}
}
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论