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