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
9e26a02f
Commit
9e26a02f
authored
4 years ago
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
实现rtsp/rtmp按需转协议功能
parent
aff9963f
显示空白字符变更
内嵌
并排
正在显示
23 个修改的文件
包含
170 行增加
和
153 行删除
+170
-153
api/include/mk_events_objects.h
+0
-2
api/source/mk_events.cpp
+4
-5
api/source/mk_events_objects.cpp
+1
-2
api/tests/server.c
+2
-2
conf/config.ini
+0
-2
server/WebHook.cpp
+7
-15
src/Common/MediaSource.cpp
+31
-32
src/Common/MediaSource.h
+9
-5
src/Common/MultiMediaSourceMuxer.cpp
+1
-7
src/Common/MultiMediaSourceMuxer.h
+0
-2
src/Common/config.cpp
+0
-2
src/Common/config.h
+1
-4
src/Record/HlsMediaSource.h
+7
-9
src/Rtmp/RtmpMediaSource.h
+7
-11
src/Rtmp/RtmpMediaSourceImp.h
+2
-3
src/Rtmp/RtmpMediaSourceMuxer.h
+31
-3
src/Rtmp/RtmpSession.cpp
+9
-10
src/Rtp/RtpProcess.cpp
+3
-4
src/Rtsp/RtspMediaSource.h
+7
-11
src/Rtsp/RtspMediaSourceImp.h
+2
-3
src/Rtsp/RtspMediaSourceMuxer.h
+37
-9
src/Rtsp/RtspSession.cpp
+8
-9
tests/test_server.cpp
+1
-1
没有找到文件。
api/include/mk_events_objects.h
查看文件 @
9e26a02f
...
...
@@ -276,13 +276,11 @@ typedef void* mk_publish_auth_invoker;
/**
* 执行Broadcast::PublishAuthInvoker
* @param err_msg 为空或null则代表鉴权成功
* @param enable_rtxp rtmp推流时是否运行转rtsp;rtsp推流时,是否允许转rtmp
* @param enable_hls 是否允许转换hls
* @param enable_mp4 是否运行MP4录制
*/
API_EXPORT
void
API_CALL
mk_publish_auth_invoker_do
(
const
mk_publish_auth_invoker
ctx
,
const
char
*
err_msg
,
int
enable_rtxp
,
int
enable_hls
,
int
enable_mp4
);
...
...
This diff is collapsed.
Click to expand it.
api/source/mk_events.cpp
查看文件 @
9e26a02f
...
...
@@ -101,11 +101,10 @@ API_EXPORT void API_CALL mk_events_listen(const mk_events *events){
s_events
.
on_mk_media_publish
((
mk_media_info
)
&
args
,
(
mk_publish_auth_invoker
)
&
invoker
,
(
mk_sock_info
)
&
sender
);
}
else
{
GET_CONFIG
(
bool
,
toRtxp
,
General
::
kPublishToRtxp
);
GET_CONFIG
(
bool
,
toHls
,
General
::
kPublishToHls
);
GET_CONFIG
(
bool
,
toMP4
,
General
::
kPublishToMP4
);
invoker
(
""
,
toRtxp
,
toHls
,
toMP4
);
}
else
{
GET_CONFIG
(
bool
,
toHls
,
General
::
kPublishToHls
);
GET_CONFIG
(
bool
,
toMP4
,
General
::
kPublishToMP4
);
invoker
(
""
,
toHls
,
toMP4
);
}
});
...
...
This diff is collapsed.
Click to expand it.
api/source/mk_events_objects.cpp
查看文件 @
9e26a02f
...
...
@@ -382,12 +382,11 @@ API_EXPORT void API_CALL mk_rtsp_auth_invoker_clone_release(const mk_rtsp_auth_i
///////////////////////////////////////////Broadcast::PublishAuthInvoker/////////////////////////////////////////////
API_EXPORT
void
API_CALL
mk_publish_auth_invoker_do
(
const
mk_publish_auth_invoker
ctx
,
const
char
*
err_msg
,
int
enable_rtxp
,
int
enable_hls
,
int
enable_mp4
){
assert
(
ctx
);
Broadcast
::
PublishAuthInvoker
*
invoker
=
(
Broadcast
::
PublishAuthInvoker
*
)
ctx
;
(
*
invoker
)(
err_msg
?
err_msg
:
""
,
enable_
rtxp
,
enable_
hls
,
enable_mp4
);
(
*
invoker
)(
err_msg
?
err_msg
:
""
,
enable_hls
,
enable_mp4
);
}
API_EXPORT
mk_publish_auth_invoker
API_CALL
mk_publish_auth_invoker_clone
(
const
mk_publish_auth_invoker
ctx
){
...
...
This diff is collapsed.
Click to expand it.
api/tests/server.c
查看文件 @
9e26a02f
...
...
@@ -61,8 +61,8 @@ void API_CALL on_mk_media_publish(const mk_media_info url_info,
mk_media_info_get_stream
(
url_info
),
mk_media_info_get_params
(
url_info
));
//允许推流,并且允许转
rtxp/
hls/mp4
mk_publish_auth_invoker_do
(
invoker
,
NULL
,
1
,
1
,
1
);
//允许推流,并且允许转hls/mp4
mk_publish_auth_invoker_do
(
invoker
,
NULL
,
1
,
1
);
}
/**
...
...
This diff is collapsed.
Click to expand it.
conf/config.ini
查看文件 @
9e26a02f
...
...
@@ -40,8 +40,6 @@ addMuteAudio=1
#拉流代理时如果断流再重连成功是否删除前一次的媒体流数据,如果删除将重新开始,
#如果不删除将会接着上一次的数据继续写(录制hls/mp4时会继续在前一个文件后面写)
resetWhenRePlay
=
1
#是否默认推流时转换成rtsp或rtmp,hook接口(on_publish)中可以覆盖该设置
publishToRtxp
=
1
#是否默认推流时转换成hls,hook接口(on_publish)中可以覆盖该设置
publishToHls
=
1
#是否默认推流时mp4录像,hook接口(on_publish)中可以覆盖该设置
...
...
This diff is collapsed.
Click to expand it.
server/WebHook.cpp
查看文件 @
9e26a02f
...
...
@@ -195,11 +195,10 @@ void installWebHook(){
GET_CONFIG
(
string
,
hook_http_access
,
Hook
::
kOnHttpAccess
);
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastMediaPublish
,[](
BroadcastMediaPublishArgs
){
GET_CONFIG
(
bool
,
toRtxp
,
General
::
kPublishToRtxp
);
GET_CONFIG
(
bool
,
toHls
,
General
::
kPublishToHls
);
GET_CONFIG
(
bool
,
toMP4
,
General
::
kPublishToMP4
);
if
(
!
hook_enable
||
args
.
_param_strs
==
hook_adminparams
||
hook_publish
.
empty
()
||
sender
.
get_peer_ip
()
==
"127.0.0.1"
){
invoker
(
""
,
toRtxp
,
toHls
,
toMP4
);
invoker
(
""
,
toHls
,
toMP4
);
return
;
}
//异步执行该hook api,防止阻塞NoticeCenter
...
...
@@ -211,27 +210,20 @@ void installWebHook(){
do_http_hook
(
hook_publish
,
body
,[
invoker
](
const
Value
&
obj
,
const
string
&
err
){
if
(
err
.
empty
()){
//推流鉴权成功
bool
enableRtxp
=
toRtxp
;
bool
enableHls
=
toHls
;
bool
enableMP4
=
toMP4
;
//兼容用户不传递enableRtxp、enableHls、enableMP4参数
if
(
obj
.
isMember
(
"enableRtxp"
)){
enableRtxp
=
obj
[
"enableRtxp"
].
asBool
();
}
if
(
obj
.
isMember
(
"enableHls"
)){
//兼容用户不传递enableHls、enableMP4参数
if
(
obj
.
isMember
(
"enableHls"
))
{
enableHls
=
obj
[
"enableHls"
].
asBool
();
}
if
(
obj
.
isMember
(
"enableMP4"
)){
if
(
obj
.
isMember
(
"enableMP4"
))
{
enableMP4
=
obj
[
"enableMP4"
].
asBool
();
}
invoker
(
err
,
enableRtxp
,
enableHls
,
enableMP4
);
}
else
{
invoker
(
err
,
enableHls
,
enableMP4
);
}
else
{
//推流鉴权失败
invoker
(
err
,
false
,
false
,
false
);
invoker
(
err
,
false
,
false
);
}
});
...
...
This diff is collapsed.
Click to expand it.
src/Common/MediaSource.cpp
查看文件 @
9e26a02f
...
...
@@ -93,13 +93,10 @@ bool MediaSource::close(bool force) {
return
listener
->
close
(
*
this
,
force
);
}
void
MediaSource
::
on
NoneReader
()
{
void
MediaSource
::
on
ReaderChanged
(
int
size
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
){
return
;
}
if
(
listener
->
totalReaderCount
(
*
this
)
==
0
)
{
listener
->
onNoneReader
(
*
this
);
if
(
listener
)
{
listener
->
onReaderChanged
(
*
this
,
size
);
}
}
...
...
@@ -475,45 +472,47 @@ MediaSource::Ptr MediaSource::createFromMP4(const string &schema, const string &
/////////////////////////////////////MediaSourceEvent//////////////////////////////////////
void
MediaSourceEvent
::
onNoneReader
(
MediaSource
&
sender
){
void
MediaSourceEvent
::
onReaderChanged
(
MediaSource
&
sender
,
int
size
){
if
(
size
||
totalReaderCount
(
sender
))
{
//还有人观看该视频,不触发关闭事件
return
;
}
//没有任何人观看该视频源,表明该源可以关闭了
GET_CONFIG
(
string
,
record_app
,
Record
::
kAppName
);
GET_CONFIG
(
int
,
stream_none_reader_delay
,
General
::
kStreamNoneReaderDelayMS
);
//如果mp4点播, 无人观看时我们强制关闭点播
bool
is_mp4_vod
=
sender
.
getApp
()
==
record_app
;
weak_ptr
<
MediaSource
>
weak_sender
=
sender
.
shared_from_this
();
//没有任何人观看该视频源,表明该源可以关闭了
weak_ptr
<
MediaSource
>
weakSender
=
sender
.
shared_from_this
();
_async_close_timer
=
std
::
make_shared
<
Timer
>
(
stream_none_reader_delay
/
1000.0
,
[
weakSender
,
is_mp4_vod
]()
{
auto
strongSender
=
weakSender
.
lock
();
if
(
!
strongSender
)
{
_async_close_timer
=
std
::
make_shared
<
Timer
>
(
stream_none_reader_delay
/
1000.0
,
[
weak_sender
,
is_mp4_vod
]()
{
auto
strong_sender
=
weak_sender
.
lock
();
if
(
!
strong_sender
)
{
//对象已经销毁
return
false
;
}
if
(
strong
Sender
->
totalReaderCount
()
!=
0
)
{
//还有人
消费
if
(
strong
_sender
->
totalReaderCount
()
)
{
//还有人
观看该视频,不触发关闭事件
return
false
;
}
if
(
!
is_mp4_vod
)
{
if
(
!
is_mp4_vod
)
{
//直播时触发无人观看事件,让开发者自行选择是否关闭
WarnL
<<
"无人观看事件:"
<<
strong
S
ender
->
getSchema
()
<<
"/"
<<
strong
S
ender
->
getVhost
()
<<
"/"
<<
strong
S
ender
->
getApp
()
<<
"/"
<<
strong
S
ender
->
getId
();
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastStreamNoneReader
,
*
strong
S
ender
);
}
else
{
<<
strong
_s
ender
->
getSchema
()
<<
"/"
<<
strong
_s
ender
->
getVhost
()
<<
"/"
<<
strong
_s
ender
->
getApp
()
<<
"/"
<<
strong
_s
ender
->
getId
();
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastStreamNoneReader
,
*
strong
_s
ender
);
}
else
{
//这个是mp4点播,我们自动关闭
WarnL
<<
"MP4点播无人观看,自动关闭:"
<<
strong
S
ender
->
getSchema
()
<<
"/"
<<
strong
S
ender
->
getVhost
()
<<
"/"
<<
strong
S
ender
->
getApp
()
<<
"/"
<<
strong
S
ender
->
getId
();
strong
S
ender
->
close
(
false
);
<<
strong
_s
ender
->
getSchema
()
<<
"/"
<<
strong
_s
ender
->
getVhost
()
<<
"/"
<<
strong
_s
ender
->
getApp
()
<<
"/"
<<
strong
_s
ender
->
getId
();
strong
_s
ender
->
close
(
false
);
}
return
false
;
},
nullptr
);
}
...
...
@@ -542,13 +541,13 @@ int MediaSourceEventInterceptor::totalReaderCount(MediaSource &sender) {
return
listener
->
totalReaderCount
(
sender
);
}
void
MediaSourceEventInterceptor
::
on
NoneReader
(
MediaSource
&
sender
)
{
void
MediaSourceEventInterceptor
::
on
ReaderChanged
(
MediaSource
&
sender
,
int
size
)
{
auto
listener
=
_listener
.
lock
();
if
(
!
listener
)
{
MediaSourceEvent
::
onNoneReader
(
sender
);
return
;
MediaSourceEvent
::
onReaderChanged
(
sender
,
size
);
}
else
{
listener
->
onReaderChanged
(
sender
,
size
);
}
listener
->
onNoneReader
(
sender
);
}
void
MediaSourceEventInterceptor
::
onRegist
(
MediaSource
&
sender
,
bool
regist
)
{
...
...
This diff is collapsed.
Click to expand it.
src/Common/MediaSource.h
查看文件 @
9e26a02f
...
...
@@ -49,8 +49,8 @@ public:
virtual
bool
close
(
MediaSource
&
sender
,
bool
force
)
{
return
false
;
}
// 获取观看总人数
virtual
int
totalReaderCount
(
MediaSource
&
sender
)
=
0
;
// 通知
无人观看
virtual
void
on
NoneReader
(
MediaSource
&
sender
);
// 通知
观看人数变化
virtual
void
on
ReaderChanged
(
MediaSource
&
sender
,
int
size
);
//流注册或注销事件
virtual
void
onRegist
(
MediaSource
&
sender
,
bool
regist
)
{};
...
...
@@ -79,7 +79,7 @@ public:
bool
seekTo
(
MediaSource
&
sender
,
uint32_t
stamp
)
override
;
bool
close
(
MediaSource
&
sender
,
bool
force
)
override
;
int
totalReaderCount
(
MediaSource
&
sender
)
override
;
void
on
NoneReader
(
MediaSource
&
sender
)
override
;
void
on
ReaderChanged
(
MediaSource
&
sender
,
int
size
)
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
;
...
...
@@ -160,8 +160,8 @@ public:
bool
seekTo
(
uint32_t
stamp
);
// 关闭该流
bool
close
(
bool
force
);
// 该流
无人观看
void
on
NoneReader
(
);
// 该流
观看人数变化
void
on
ReaderChanged
(
int
size
);
// 开启或关闭录制
bool
setupRecord
(
Recorder
::
type
type
,
bool
start
,
const
string
&
custom_path
);
// 获取录制状态
...
...
@@ -249,6 +249,10 @@ public:
}
}
virtual
void
clearCache
()
{
_cache
->
clear
();
}
virtual
void
onFlush
(
std
::
shared_ptr
<
packet_list
>
&
,
bool
key_pos
)
=
0
;
private
:
...
...
This diff is collapsed.
Click to expand it.
src/Common/MultiMediaSourceMuxer.cpp
查看文件 @
9e26a02f
...
...
@@ -18,21 +18,17 @@ MultiMuxerPrivate::MultiMuxerPrivate(const string &vhost, const string &app, con
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
;
}
if
(
enable_rtsp
)
{
_rtsp
=
std
::
make_shared
<
RtspMediaSourceMuxer
>
(
vhost
,
app
,
stream
,
std
::
make_shared
<
TitleSdp
>
(
dur_sec
));
_enable_rtxp
=
true
;
}
if
(
enable_hls
)
{
_hls
=
Recorder
::
createRecorder
(
Recorder
::
type_hls
,
vhost
,
app
,
stream
);
_enable_record
=
true
;
}
if
(
enable_mp4
)
{
_mp4
=
Recorder
::
createRecorder
(
Recorder
::
type_mp4
,
vhost
,
app
,
stream
);
_enable_record
=
true
;
}
}
...
...
@@ -101,7 +97,6 @@ bool MultiMuxerPrivate::setupRecord(MediaSource &sender, Recorder::type type, bo
//停止录制
_hls
=
nullptr
;
}
_enable_record
=
_hls
||
_mp4
;
return
true
;
}
case
Recorder
:
:
type_mp4
:
{
...
...
@@ -112,7 +107,6 @@ bool MultiMuxerPrivate::setupRecord(MediaSource &sender, Recorder::type type, bo
//停止录制
_mp4
=
nullptr
;
}
_enable_record
=
_hls
||
_mp4
;
return
true
;
}
default
:
return
false
;
...
...
@@ -164,7 +158,7 @@ void MultiMuxerPrivate::onTrackReady(const Track::Ptr &track) {
}
bool
MultiMuxerPrivate
::
isEnabled
(){
return
_enable_rtxp
||
_enable_record
;
return
(
_rtmp
?
_rtmp
->
isEnabled
()
:
false
)
||
(
_rtsp
?
_rtsp
->
isEnabled
()
:
false
)
||
_hls
||
_mp4
;
}
void
MultiMuxerPrivate
::
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
{
...
...
This diff is collapsed.
Click to expand it.
src/Common/MultiMediaSourceMuxer.h
查看文件 @
9e26a02f
...
...
@@ -49,8 +49,6 @@ private:
MediaSource
::
Ptr
getHlsMediaSource
()
const
;
private
:
bool
_enable_rtxp
=
false
;
bool
_enable_record
=
false
;
Listener
*
_track_listener
=
nullptr
;
RtmpMediaSourceMuxer
::
Ptr
_rtmp
;
RtspMediaSourceMuxer
::
Ptr
_rtsp
;
...
...
This diff is collapsed.
Click to expand it.
src/Common/config.cpp
查看文件 @
9e26a02f
...
...
@@ -63,7 +63,6 @@ const string kMaxStreamWaitTimeMS = GENERAL_FIELD"maxStreamWaitMS";
const
string
kEnableVhost
=
GENERAL_FIELD
"enableVhost"
;
const
string
kAddMuteAudio
=
GENERAL_FIELD
"addMuteAudio"
;
const
string
kResetWhenRePlay
=
GENERAL_FIELD
"resetWhenRePlay"
;
const
string
kPublishToRtxp
=
GENERAL_FIELD
"publishToRtxp"
;
const
string
kPublishToHls
=
GENERAL_FIELD
"publishToHls"
;
const
string
kPublishToMP4
=
GENERAL_FIELD
"publishToMP4"
;
const
string
kMergeWriteMS
=
GENERAL_FIELD
"mergeWriteMS"
;
...
...
@@ -76,7 +75,6 @@ onceToken token([](){
mINI
::
Instance
()[
kEnableVhost
]
=
0
;
mINI
::
Instance
()[
kAddMuteAudio
]
=
1
;
mINI
::
Instance
()[
kResetWhenRePlay
]
=
1
;
mINI
::
Instance
()[
kPublishToRtxp
]
=
1
;
mINI
::
Instance
()[
kPublishToHls
]
=
1
;
mINI
::
Instance
()[
kPublishToMP4
]
=
0
;
mINI
::
Instance
()[
kMergeWriteMS
]
=
0
;
...
...
This diff is collapsed.
Click to expand it.
src/Common/config.h
查看文件 @
9e26a02f
...
...
@@ -86,8 +86,7 @@ extern const string kBroadcastOnRtspAuth;
//如果errMessage为空则代表鉴权成功
//enableHls: 是否允许转换hls
//enableMP4: 是否运行MP4录制
//enableRtxp: rtmp推流时是否运行转rtsp;rtsp推流时,是否允许转rtmp
typedef
std
::
function
<
void
(
const
string
&
errMessage
,
bool
enableRtxp
,
bool
enableHls
,
bool
enableMP4
)
>
PublishAuthInvoker
;
typedef
std
::
function
<
void
(
const
string
&
errMessage
,
bool
enableHls
,
bool
enableMP4
)
>
PublishAuthInvoker
;
//收到rtsp/rtmp推流事件广播,通过该事件控制推流鉴权
extern
const
string
kBroadcastMediaPublish
;
...
...
@@ -165,8 +164,6 @@ extern const string kAddMuteAudio;
//拉流代理时如果断流再重连成功是否删除前一次的媒体流数据,如果删除将重新开始,
//如果不删除将会接着上一次的数据继续写(录制hls/mp4时会继续在前一个文件后面写)
extern
const
string
kResetWhenRePlay
;
//是否默认推流时转换成rtsp或rtmp,hook接口(on_publish)中可以覆盖该设置
extern
const
string
kPublishToRtxp
;
//是否默认推流时转换成hls,hook接口(on_publish)中可以覆盖该设置
extern
const
string
kPublishToHls
;
//是否默认推流时mp4录像,hook接口(on_publish)中可以覆盖该设置
...
...
This diff is collapsed.
Click to expand it.
src/Record/HlsMediaSource.h
查看文件 @
9e26a02f
...
...
@@ -26,7 +26,7 @@ public:
_ring
=
std
::
make_shared
<
RingType
>
();
}
virtual
~
HlsMediaSource
()
=
default
;
~
HlsMediaSource
()
override
=
default
;
/**
* 获取媒体源的环形缓冲
...
...
@@ -47,10 +47,10 @@ public:
* 注册hls
*/
void
registHls
(){
if
(
!
_registed
){
regist
();
if
(
!
_registed
)
{
_registed
=
true
;
onNoneReader
();
onReaderChanged
(
0
);
regist
();
}
}
...
...
@@ -62,12 +62,10 @@ private:
void
modifyReaderCount
(
bool
add
)
{
if
(
add
)
{
++
_readerCount
;
return
;
}
if
(
--
_readerCount
==
0
)
{
onNoneReader
();
}
else
{
--
_readerCount
;
}
onReaderChanged
(
_readerCount
);
}
private
:
atomic_int
_readerCount
;
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/RtmpMediaSource.h
查看文件 @
9e26a02f
...
...
@@ -60,7 +60,7 @@ public:
MediaSource
(
RTMP_SCHEMA
,
vhost
,
app
,
stream_id
),
_ring_size
(
ring_size
)
{
}
virtual
~
RtmpMediaSource
()
{}
~
RtmpMediaSource
()
override
{}
/**
* 获取媒体源的环形缓冲
...
...
@@ -134,7 +134,7 @@ public:
if
(
!
_ring
)
{
weak_ptr
<
RtmpMediaSource
>
weakSelf
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
shared_from_this
());
auto
lam
=
[
weakSelf
](
const
EventPoller
::
Ptr
&
,
int
size
,
bool
)
{
auto
lam
=
[
weakSelf
](
int
size
)
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
...
...
@@ -174,6 +174,11 @@ public:
return
ret
;
}
void
clearCache
()
override
{
PacketCache
<
RtmpPacket
>::
clearCache
();
_ring
->
clearCache
();
}
private
:
/**
* 批量flush rtmp包时触发该函数
...
...
@@ -185,15 +190,6 @@ private:
_ring
->
write
(
rtmp_list
,
_have_video
?
key_pos
:
true
);
}
/**
* 每次增减消费者都会触发该函数
*/
void
onReaderChanged
(
int
size
)
{
if
(
size
==
0
)
{
onNoneReader
();
}
}
private
:
bool
_have_video
=
false
;
int
_ring_size
;
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/RtmpMediaSourceImp.h
查看文件 @
9e26a02f
...
...
@@ -77,13 +77,12 @@ public:
/**
* 设置协议转换
* @param enableRtsp 是否转换成rtsp
* @param enableHls 是否转换成hls
* @param enableMP4 是否mp4录制
*/
void
setProtocolTranslation
(
bool
enable
Rtsp
,
bool
enable
Hls
,
bool
enableMP4
)
{
void
setProtocolTranslation
(
bool
enableHls
,
bool
enableMP4
)
{
//不重复生成rtmp
_muxer
=
std
::
make_shared
<
MultiMediaSourceMuxer
>
(
getVhost
(),
getApp
(),
getId
(),
_demuxer
->
getDuration
(),
enableRtsp
,
false
,
enableHls
,
enableMP4
);
_muxer
=
std
::
make_shared
<
MultiMediaSourceMuxer
>
(
getVhost
(),
getApp
(),
getId
(),
_demuxer
->
getDuration
(),
true
,
false
,
enableHls
,
enableMP4
);
_muxer
->
setMediaListener
(
getListener
());
_muxer
->
setTrackListener
(
static_pointer_cast
<
RtmpMediaSourceImp
>
(
shared_from_this
()));
//让_muxer对象拦截一部分事件(比如说录像相关事件)
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/RtmpMediaSourceMuxer.h
查看文件 @
9e26a02f
...
...
@@ -16,7 +16,8 @@
namespace
mediakit
{
class
RtmpMediaSourceMuxer
:
public
RtmpMuxer
{
class
RtmpMediaSourceMuxer
:
public
RtmpMuxer
,
public
MediaSourceEventInterceptor
,
public
std
::
enable_shared_from_this
<
RtmpMediaSourceMuxer
>
{
public
:
typedef
std
::
shared_ptr
<
RtmpMediaSourceMuxer
>
Ptr
;
...
...
@@ -27,10 +28,11 @@ public:
_media_src
=
std
::
make_shared
<
RtmpMediaSource
>
(
vhost
,
strApp
,
strId
);
getRtmpRing
()
->
setDelegate
(
_media_src
);
}
virtual
~
RtmpMediaSourceMuxer
(){}
~
RtmpMediaSourceMuxer
()
override
{}
void
setListener
(
const
std
::
weak_ptr
<
MediaSourceEvent
>
&
listener
){
_
media_src
->
setListener
(
listener
)
;
_
listener
=
listener
;
}
void
setTimeStamp
(
uint32_t
stamp
){
...
...
@@ -43,10 +45,36 @@ public:
void
onAllTrackReady
(){
makeConfigPacket
();
_media_src
->
setListener
(
shared_from_this
());
_media_src
->
setMetaData
(
getMetadata
());
}
void
onReaderChanged
(
MediaSource
&
sender
,
int
size
)
override
{
_enabled
=
size
;
if
(
!
size
)
{
_clear_cache
=
true
;
}
MediaSourceEventInterceptor
::
onReaderChanged
(
sender
,
size
);
}
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
{
if
(
_clear_cache
)
{
_clear_cache
=
false
;
_media_src
->
clearCache
();
}
if
(
_enabled
)
{
RtmpMuxer
::
inputFrame
(
frame
);
}
}
bool
isEnabled
()
{
//缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存
return
_clear_cache
?
true
:
_enabled
;
}
private
:
bool
_enabled
=
true
;
bool
_clear_cache
=
false
;
RtmpMediaSource
::
Ptr
_media_src
;
};
...
...
This diff is collapsed.
Click to expand it.
src/Rtmp/RtmpSession.cpp
查看文件 @
9e26a02f
...
...
@@ -126,7 +126,7 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
_media_info
.
parse
(
_tc_url
+
"/"
+
getStreamId
(
dec
.
load
<
std
::
string
>
()));
_media_info
.
_schema
=
RTMP_SCHEMA
;
auto
on_res
=
[
this
,
pToken
](
const
string
&
err
,
bool
enable
Rtxp
,
bool
enable
Hls
,
bool
enableMP4
){
auto
on_res
=
[
this
,
pToken
](
const
string
&
err
,
bool
enableHls
,
bool
enableMP4
){
auto
src
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
MediaSource
::
find
(
RTMP_SCHEMA
,
_media_info
.
_vhost
,
_media_info
.
_app
,
...
...
@@ -150,7 +150,7 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
_publisher_src
.
reset
(
new
RtmpMediaSourceImp
(
_media_info
.
_vhost
,
_media_info
.
_app
,
_media_info
.
_streamid
));
_publisher_src
->
setListener
(
dynamic_pointer_cast
<
MediaSourceEvent
>
(
shared_from_this
()));
//设置转协议
_publisher_src
->
setProtocolTranslation
(
enable
Rtxp
,
enable
Hls
,
enableMP4
);
_publisher_src
->
setProtocolTranslation
(
enableHls
,
enableMP4
);
//如果是rtmp推流客户端,那么加大TCP接收缓存,这样能提升接收性能
getSock
()
->
setReadBuffer
(
std
::
make_shared
<
BufferRaw
>
(
256
*
1024
));
...
...
@@ -159,30 +159,29 @@ void RtmpSession::onCmd_publish(AMFDecoder &dec) {
if
(
_media_info
.
_app
.
empty
()
||
_media_info
.
_streamid
.
empty
()){
//不允许莫名其妙的推流url
on_res
(
"rtmp推流url非法"
,
false
,
false
,
false
);
on_res
(
"rtmp推流url非法"
,
false
,
false
);
return
;
}
Broadcast
::
PublishAuthInvoker
invoker
=
[
weak_self
,
on_res
,
pToken
](
const
string
&
err
,
bool
enableRtxp
,
bool
enableHls
,
bool
enableMP4
)
{
Broadcast
::
PublishAuthInvoker
invoker
=
[
weak_self
,
on_res
,
pToken
](
const
string
&
err
,
bool
enableHls
,
bool
enableMP4
)
{
auto
strongSelf
=
weak_self
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
async
([
weak_self
,
on_res
,
err
,
pToken
,
enableRtxp
,
enableHls
,
enableMP4
]()
{
strongSelf
->
async
([
weak_self
,
on_res
,
err
,
pToken
,
enableHls
,
enableMP4
]()
{
auto
strongSelf
=
weak_self
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
;
}
on_res
(
err
,
enable
Rtxp
,
enable
Hls
,
enableMP4
);
on_res
(
err
,
enableHls
,
enableMP4
);
});
};
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPublish
,
_media_info
,
invoker
,
static_cast
<
SockInfo
&>
(
*
this
));
if
(
!
flag
){
//该事件无人监听,默认鉴权成功
GET_CONFIG
(
bool
,
to_rtxp
,
General
::
kPublishToRtxp
);
GET_CONFIG
(
bool
,
to_hls
,
General
::
kPublishToHls
);
GET_CONFIG
(
bool
,
to_mp4
,
General
::
kPublishToMP4
);
on_res
(
""
,
to_
rtxp
,
to_
hls
,
to_mp4
);
on_res
(
""
,
to_hls
,
to_mp4
);
}
}
...
...
This diff is collapsed.
Click to expand it.
src/Rtp/RtpProcess.cpp
查看文件 @
9e26a02f
...
...
@@ -243,7 +243,7 @@ void RtpProcess::setListener(const std::weak_ptr<MediaSourceEvent> &listener){
void
RtpProcess
::
emitOnPublish
()
{
weak_ptr
<
RtpProcess
>
weak_self
=
shared_from_this
();
Broadcast
::
PublishAuthInvoker
invoker
=
[
weak_self
](
const
string
&
err
,
bool
enable
Rtxp
,
bool
enable
Hls
,
bool
enableMP4
)
{
Broadcast
::
PublishAuthInvoker
invoker
=
[
weak_self
](
const
string
&
err
,
bool
enableHls
,
bool
enableMP4
)
{
auto
strongSelf
=
weak_self
.
lock
();
if
(
!
strongSelf
)
{
return
;
...
...
@@ -252,7 +252,7 @@ void RtpProcess::emitOnPublish() {
strongSelf
->
_muxer
=
std
::
make_shared
<
MultiMediaSourceMuxer
>
(
strongSelf
->
_media_info
.
_vhost
,
strongSelf
->
_media_info
.
_app
,
strongSelf
->
_media_info
.
_streamid
,
0
,
enableRtxp
,
enableRtxp
,
enableHls
,
enableMP4
);
true
,
true
,
enableHls
,
enableMP4
);
strongSelf
->
_muxer
->
setMediaListener
(
strongSelf
->
_listener
);
InfoP
(
strongSelf
)
<<
"允许RTP推流"
;
}
else
{
...
...
@@ -264,10 +264,9 @@ void RtpProcess::emitOnPublish() {
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPublish
,
_media_info
,
invoker
,
static_cast
<
SockInfo
&>
(
*
this
));
if
(
!
flag
){
//该事件无人监听,默认不鉴权
GET_CONFIG
(
bool
,
toRtxp
,
General
::
kPublishToRtxp
);
GET_CONFIG
(
bool
,
toHls
,
General
::
kPublishToHls
);
GET_CONFIG
(
bool
,
toMP4
,
General
::
kPublishToMP4
);
invoker
(
""
,
to
Rtxp
,
to
Hls
,
toMP4
);
invoker
(
""
,
toHls
,
toMP4
);
}
}
...
...
This diff is collapsed.
Click to expand it.
src/Rtsp/RtspMediaSource.h
查看文件 @
9e26a02f
...
...
@@ -56,7 +56,7 @@ public:
int
ring_size
=
RTP_GOP_SIZE
)
:
MediaSource
(
RTSP_SCHEMA
,
vhost
,
app
,
stream_id
),
_ring_size
(
ring_size
)
{}
virtual
~
RtspMediaSource
()
{}
~
RtspMediaSource
()
override
{}
/**
* 获取媒体源的环形缓冲
...
...
@@ -166,7 +166,7 @@ public:
}
if
(
!
_ring
)
{
weak_ptr
<
RtspMediaSource
>
weakSelf
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
shared_from_this
());
auto
lam
=
[
weakSelf
](
const
EventPoller
::
Ptr
&
,
int
size
,
bool
)
{
auto
lam
=
[
weakSelf
](
int
size
)
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
...
...
@@ -184,6 +184,11 @@ public:
PacketCache
<
RtpPacket
>::
inputPacket
(
rtp
->
type
==
TrackVideo
,
rtp
,
keyPos
);
}
void
clearCache
()
override
{
PacketCache
<
RtpPacket
>::
clearCache
();
_ring
->
clearCache
();
}
private
:
/**
* 批量flush rtp包时触发该函数
...
...
@@ -195,15 +200,6 @@ private:
_ring
->
write
(
rtp_list
,
_have_video
?
key_pos
:
true
);
}
/**
* 每次增减消费者都会触发该函数
*/
void
onReaderChanged
(
int
size
)
{
if
(
size
==
0
)
{
onNoneReader
();
}
}
private
:
bool
_have_video
=
false
;
int
_ring_size
;
...
...
This diff is collapsed.
Click to expand it.
src/Rtsp/RtspMediaSourceImp.h
查看文件 @
9e26a02f
...
...
@@ -68,13 +68,12 @@ public:
/**
* 设置协议转换
* @param enableRtmp 是否转换成rtmp
* @param enableHls 是否转换成hls
* @param enableMP4 是否mp4录制
*/
void
setProtocolTranslation
(
bool
enable
Rtmp
,
bool
enable
Hls
,
bool
enableMP4
){
void
setProtocolTranslation
(
bool
enableHls
,
bool
enableMP4
){
//不重复生成rtsp
_muxer
=
std
::
make_shared
<
MultiMediaSourceMuxer
>
(
getVhost
(),
getApp
(),
getId
(),
_demuxer
->
getDuration
(),
false
,
enableRtmp
,
enableHls
,
enableMP4
);
_muxer
=
std
::
make_shared
<
MultiMediaSourceMuxer
>
(
getVhost
(),
getApp
(),
getId
(),
_demuxer
->
getDuration
(),
false
,
true
,
enableHls
,
enableMP4
);
_muxer
->
setMediaListener
(
getListener
());
_muxer
->
setTrackListener
(
static_pointer_cast
<
RtspMediaSourceImp
>
(
shared_from_this
()));
//让_muxer对象拦截一部分事件(比如说录像相关事件)
...
...
This diff is collapsed.
Click to expand it.
src/Rtsp/RtspMediaSourceMuxer.h
查看文件 @
9e26a02f
...
...
@@ -16,7 +16,8 @@
namespace
mediakit
{
class
RtspMediaSourceMuxer
:
public
RtspMuxer
{
class
RtspMediaSourceMuxer
:
public
RtspMuxer
,
public
MediaSourceEventInterceptor
,
public
std
::
enable_shared_from_this
<
RtspMediaSourceMuxer
>
{
public
:
typedef
std
::
shared_ptr
<
RtspMediaSourceMuxer
>
Ptr
;
...
...
@@ -24,29 +25,56 @@ public:
const
string
&
strApp
,
const
string
&
strId
,
const
TitleSdp
::
Ptr
&
title
=
nullptr
)
:
RtspMuxer
(
title
){
_media
Souce
=
std
::
make_shared
<
RtspMediaSource
>
(
vhost
,
strApp
,
strId
);
getRtpRing
()
->
setDelegate
(
_media
Souce
);
_media
_src
=
std
::
make_shared
<
RtspMediaSource
>
(
vhost
,
strApp
,
strId
);
getRtpRing
()
->
setDelegate
(
_media
_src
);
}
virtual
~
RtspMediaSourceMuxer
(){}
~
RtspMediaSourceMuxer
()
override
{}
void
setListener
(
const
std
::
weak_ptr
<
MediaSourceEvent
>
&
listener
){
_
mediaSouce
->
setListener
(
listener
)
;
_
listener
=
listener
;
}
int
readerCount
()
const
{
return
_media
Souce
->
readerCount
();
return
_media
_src
->
readerCount
();
}
void
setTimeStamp
(
uint32_t
stamp
){
_media
Souce
->
setTimeStamp
(
stamp
);
_media
_src
->
setTimeStamp
(
stamp
);
}
void
onAllTrackReady
(){
_mediaSouce
->
setSdp
(
getSdp
());
_media_src
->
setListener
(
shared_from_this
());
_media_src
->
setSdp
(
getSdp
());
}
void
onReaderChanged
(
MediaSource
&
sender
,
int
size
)
override
{
_enabled
=
size
;
if
(
!
size
)
{
_clear_cache
=
true
;
}
MediaSourceEventInterceptor
::
onReaderChanged
(
sender
,
size
);
}
void
inputFrame
(
const
Frame
::
Ptr
&
frame
)
override
{
if
(
_clear_cache
)
{
_clear_cache
=
false
;
_media_src
->
clearCache
();
}
if
(
_enabled
)
{
RtspMuxer
::
inputFrame
(
frame
);
}
}
bool
isEnabled
()
{
//缓存尚未清空时,还允许触发inputFrame函数,以便及时清空缓存
return
_clear_cache
?
true
:
_enabled
;
}
private
:
RtspMediaSource
::
Ptr
_mediaSouce
;
bool
_enabled
=
true
;
bool
_clear_cache
=
false
;
RtspMediaSource
::
Ptr
_media_src
;
};
...
...
This diff is collapsed.
Click to expand it.
src/Rtsp/RtspSession.cpp
查看文件 @
9e26a02f
...
...
@@ -252,7 +252,7 @@ void RtspSession::handleReq_RECORD(const Parser &parser){
send_SessionNotFound
();
throw
SockException
(
Err_shutdown
,
_sdp_track
.
empty
()
?
"can not find any availabe track when record"
:
"session not found when record"
);
}
auto
onRes
=
[
this
](
const
string
&
err
,
bool
enableRtxp
,
bool
enableHls
,
bool
enableMP4
){
auto
onRes
=
[
this
](
const
string
&
err
,
bool
enableHls
,
bool
enableMP4
){
bool
authSuccess
=
err
.
empty
();
if
(
!
authSuccess
){
sendRtspResponse
(
"401 Unauthorized"
,
{
"Content-Type"
,
"text/plain"
},
err
);
...
...
@@ -261,7 +261,7 @@ void RtspSession::handleReq_RECORD(const Parser &parser){
}
//设置转协议
_push_src
->
setProtocolTranslation
(
enable
Rtxp
,
enable
Hls
,
enableMP4
);
_push_src
->
setProtocolTranslation
(
enableHls
,
enableMP4
);
_StrPrinter
rtp_info
;
for
(
auto
&
track
:
_sdp_track
){
...
...
@@ -283,17 +283,17 @@ void RtspSession::handleReq_RECORD(const Parser &parser){
};
weak_ptr
<
RtspSession
>
weakSelf
=
dynamic_pointer_cast
<
RtspSession
>
(
shared_from_this
());
Broadcast
::
PublishAuthInvoker
invoker
=
[
weakSelf
,
onRes
](
const
string
&
err
,
bool
enableRtxp
,
bool
enableHls
,
bool
enableMP4
)
{
Broadcast
::
PublishAuthInvoker
invoker
=
[
weakSelf
,
onRes
](
const
string
&
err
,
bool
enableHls
,
bool
enableMP4
)
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
async
([
weakSelf
,
onRes
,
err
,
enableRtxp
,
enableHls
,
enableMP4
]()
{
strongSelf
->
async
([
weakSelf
,
onRes
,
err
,
enableHls
,
enableMP4
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
;
}
onRes
(
err
,
enableRtxp
,
enableHls
,
enableMP4
);
onRes
(
err
,
enableHls
,
enableMP4
);
});
};
...
...
@@ -301,10 +301,9 @@ void RtspSession::handleReq_RECORD(const Parser &parser){
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPublish
,
_media_info
,
invoker
,
static_cast
<
SockInfo
&>
(
*
this
));
if
(
!
flag
){
//该事件无人监听,默认不鉴权
GET_CONFIG
(
bool
,
toRtxp
,
General
::
kPublishToRtxp
);
GET_CONFIG
(
bool
,
toHls
,
General
::
kPublishToHls
);
GET_CONFIG
(
bool
,
toMP4
,
General
::
kPublishToMP4
);
onRes
(
""
,
to
Rtxp
,
to
Hls
,
toMP4
);
onRes
(
""
,
toHls
,
toMP4
);
}
}
...
...
This diff is collapsed.
Click to expand it.
tests/test_server.cpp
查看文件 @
9e26a02f
...
...
@@ -141,7 +141,7 @@ void initEventListener() {
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Broadcast
::
kBroadcastMediaPublish
,
[](
BroadcastMediaPublishArgs
)
{
DebugL
<<
"推流鉴权:"
<<
args
.
_schema
<<
" "
<<
args
.
_vhost
<<
" "
<<
args
.
_app
<<
" "
<<
args
.
_streamid
<<
" "
<<
args
.
_param_strs
;
invoker
(
""
,
true
,
true
,
false
);
//鉴权成功
invoker
(
""
,
true
,
false
);
//鉴权成功
//invoker("this is auth failed message");//鉴权失败
});
...
...
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论