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
ec902f51
Commit
ec902f51
authored
Feb 05, 2018
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加 http-flv/rtmp/rtsp通用鉴权接口
parent
6da3a577
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
263 行增加
和
167 行删除
+263
-167
src/Common/MediaSource.cpp
+2
-2
src/Common/MediaSource.h
+2
-0
src/Common/config.cpp
+2
-2
src/Common/config.h
+16
-2
src/Http/HttpSession.cpp
+108
-78
src/Rtmp/RtmpSession.cpp
+0
-0
src/Rtsp/Rtsp.h
+12
-6
src/Rtsp/RtspSession.cpp
+105
-77
tests/test_server.cpp
+16
-0
没有找到文件。
src/Common/MediaSource.cpp
查看文件 @
ec902f51
...
...
@@ -150,8 +150,8 @@ void MediaInfo::parse(const string &url){
auto
pos
=
steamid
.
find
(
"?"
);
if
(
pos
!=
string
::
npos
){
m_streamid
=
steamid
.
substr
(
0
,
pos
);
auto
param
s
=
steamid
.
substr
(
pos
+
1
);
m_params
=
Parser
::
parseArgs
(
param
s
);
m_param_str
s
=
steamid
.
substr
(
pos
+
1
);
m_params
=
Parser
::
parseArgs
(
m_param_str
s
);
if
(
m_params
.
find
(
VHOST_KEY
)
!=
m_params
.
end
()){
m_vhost
=
m_params
[
VHOST_KEY
];
}
...
...
src/Common/MediaSource.h
查看文件 @
ec902f51
...
...
@@ -83,6 +83,8 @@ public:
string
m_app
;
string
m_streamid
;
StrCaseMap
m_params
;
string
m_param_strs
;
};
...
...
src/Common/config.cpp
查看文件 @
ec902f51
...
...
@@ -47,13 +47,13 @@ void loadIniConfig(){
}
////////////广播名称///////////
namespace
Broadcast
{
const
char
kBroadcastMediaPlayed
[]
=
"kBroadcastMediaPlayed"
;
const
char
kBroadcastMediaChanged
[]
=
"kBroadcastMediaChanged"
;
const
char
kBroadcastRecordMP4
[]
=
"kBroadcastRecordMP4"
;
const
char
kBroadcastHttpRequest
[]
=
"kBroadcastHttpRequest"
;
const
char
kBroadcastOnGetRtspRealm
[]
=
"kBroadcastOnGetRtspRealm"
;
const
char
kBroadcastOnRtspAuth
[]
=
"kBroadcastOnRtspAuth"
;
const
char
kBroadcastMediaPlayed
[]
=
"kBroadcastMediaPlayed"
;
const
char
kBroadcastRtmpPublish
[]
=
"kBroadcastRtmpPublish"
;
}
//namespace Broadcast
//代理失败最大重试次数
...
...
src/Common/config.h
查看文件 @
ec902f51
...
...
@@ -51,6 +51,7 @@ void loadIniConfig();
#define SERVER_NAME "ZLMediaKit"
#define VHOST_KEY "vhost"
#define HTTP_SCHEMA "http"
#define RTSP_SCHEMA "rtsp"
#define RTMP_SCHEMA "rtmp"
#define DEFAULT_VHOST "__defaultVhost__"
...
...
@@ -59,15 +60,16 @@ void loadIniConfig();
////////////广播名称///////////
namespace
Broadcast
{
extern
const
char
kBroadcastMediaPlayed
[];
#define BroadcastMediaPlayedArgs const char *schema,const char *vhost,const char *app,const char *stream
//注册或反注册MediaSource事件广播
extern
const
char
kBroadcastMediaChanged
[];
#define BroadcastMediaChangedArgs bool bRegist, const char *schema,const char *vhost,const char *app,const char *stream
//录制mp4文件成功后广播
extern
const
char
kBroadcastRecordMP4
[];
#define BroadcastRecordMP4Args const Mp4Info &info
//收到http api请求广播
extern
const
char
kBroadcastHttpRequest
[];
#define BroadcastHttpRequestArgs const Parser &parser,HttpSession::HttpResponseInvoker &invoker,bool &consumed
...
...
@@ -80,6 +82,18 @@ extern const char kBroadcastOnGetRtspRealm[];
extern
const
char
kBroadcastOnRtspAuth
[];
#define BroadcastOnRtspAuthArgs const char *user_name,bool must_no_encrypt,const RtspSession::onAuth &invoker
//鉴权结果回调对象
typedef
std
::
function
<
void
(
bool
success
)
>
AuthInvoker
;
//收到rtmp推流事件广播,通过该事件控制推流鉴权
extern
const
char
kBroadcastRtmpPublish
[];
#define BroadcastRtmpPublishArgs MediaInfo &args,Broadcast::AuthInvoker &invoker
//播放rtsp或rtmp事件广播,通过该事件控制播放鉴权
extern
const
char
kBroadcastMediaPlayed
[];
#define BroadcastMediaPlayedArgs MediaInfo &args,Broadcast::AuthInvoker &invoker
}
//namespace Broadcast
//代理失败最大重试次数
...
...
src/Http/HttpSession.cpp
查看文件 @
ec902f51
...
...
@@ -171,7 +171,8 @@ void HttpSession::onManager() {
shutdown
();
}
}
//http-flv 链接格式:http://vhost-url:port/app/streamid.flv?key1=value1&key2=value2
//如果url(除去?以及后面的参数)后缀是.flv,那么表明该url是一个http-flv直播。
inline
bool
HttpSession
::
checkLiveFlvStream
(){
auto
pos
=
strrchr
(
m_parser
.
Url
().
data
(),
'.'
);
if
(
!
pos
){
...
...
@@ -182,87 +183,118 @@ inline bool HttpSession::checkLiveFlvStream(){
//未找到".flv"后缀
return
false
;
}
auto
fullUrl
=
string
(
"http://"
)
+
m_parser
[
"Host"
]
+
FindField
(
m_parser
.
Url
().
data
(),
NULL
,
pos
);
//拼接成完整url
auto
fullUrl
=
string
(
HTTP_SCHEMA
)
+
"://"
+
m_parser
[
"Host"
]
+
m_parser
.
FullUrl
();
MediaInfo
info
(
fullUrl
);
if
(
!
m_parser
.
getUrlArgs
()[
VHOST_KEY
].
empty
()){
info
.
m_vhost
=
m_parser
.
getUrlArgs
()[
VHOST_KEY
];
}
info
.
m_streamid
.
erase
(
info
.
m_streamid
.
size
()
-
4
);
//去除.flv后缀
auto
mediaSrc
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
MediaSource
::
find
(
RTMP_SCHEMA
,
info
.
m_vhost
,
info
.
m_app
,
info
.
m_streamid
));
if
(
!
mediaSrc
){
//该rtmp源不存在
return
false
;
sendNotFound
(
true
);
shutdown
();
return
true
;
}
if
(
!
mediaSrc
->
ready
()){
//未准备好
return
false
;
}
//找到rtmp源,发送http头,负载后续发送
sendResponse
(
"200 OK"
,
makeHttpHeader
(
false
,
0
,
get_mime_type
(
m_parser
.
Url
().
data
())),
""
);
//发送flv文件头
char
flv_file_header
[]
=
"FLV\x1\x5\x0\x0\x0\x9"
;
// have audio and have video
bool
is_have_audio
=
false
,
is_have_video
=
false
;
mediaSrc
->
getConfigFrame
([
&
](
const
RtmpPacket
::
Ptr
&
pkt
){
if
(
pkt
->
typeId
==
MSG_VIDEO
){
is_have_video
=
true
;
}
if
(
pkt
->
typeId
==
MSG_AUDIO
){
is_have_audio
=
true
;
}
});
if
(
is_have_audio
&&
is_have_video
)
{
flv_file_header
[
4
]
=
0x05
;
}
else
if
(
is_have_audio
&&
!
is_have_video
)
{
flv_file_header
[
4
]
=
0x04
;
}
else
if
(
!
is_have_audio
&&
is_have_video
)
{
flv_file_header
[
4
]
=
0x01
;
}
else
{
flv_file_header
[
4
]
=
0x00
;
}
//send flv header
send
(
flv_file_header
,
sizeof
(
flv_file_header
)
-
1
);
//send metadata
AMFEncoder
invoke
;
invoke
<<
"onMetaData"
<<
mediaSrc
->
getMetaData
();
sendRtmp
(
MSG_DATA
,
invoke
.
data
(),
0
);
//send config frame
mediaSrc
->
getConfigFrame
([
&
](
const
RtmpPacket
::
Ptr
&
pkt
){
onSendMedia
(
pkt
);
});
//开始发送rtmp负载
m_pRingReader
=
mediaSrc
->
getRing
()
->
attach
();
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
m_pRingReader
->
setReadCB
([
weakSelf
](
const
RtmpPacket
::
Ptr
&
pkt
){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
async
([
pkt
,
weakSelf
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
onSendMedia
(
pkt
);
});
});
m_pRingReader
->
setDetachCB
([
weakSelf
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
async_first
([
weakSelf
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
shutdown
();
});
});
return
true
;
sendNotFound
(
true
);
shutdown
();
return
true
;
}
auto
onRes
=
[
this
,
mediaSrc
](
bool
authSuccess
){
if
(
!
authSuccess
){
string
status
=
"401 Unauthorized"
;
sendResponse
(
status
.
data
(),
makeHttpHeader
(
true
,
status
.
size
()),
status
);
shutdown
();
return
;
}
//找到rtmp源,发送http头,负载后续发送
sendResponse
(
"200 OK"
,
makeHttpHeader
(
false
,
0
,
get_mime_type
(
".flv"
)),
""
);
//发送flv文件头
char
flv_file_header
[]
=
"FLV\x1\x5\x0\x0\x0\x9"
;
// have audio and have video
bool
is_have_audio
=
false
,
is_have_video
=
false
;
mediaSrc
->
getConfigFrame
([
&
](
const
RtmpPacket
::
Ptr
&
pkt
){
if
(
pkt
->
typeId
==
MSG_VIDEO
){
is_have_video
=
true
;
}
if
(
pkt
->
typeId
==
MSG_AUDIO
){
is_have_audio
=
true
;
}
});
if
(
is_have_audio
&&
is_have_video
)
{
flv_file_header
[
4
]
=
0x05
;
}
else
if
(
is_have_audio
&&
!
is_have_video
)
{
flv_file_header
[
4
]
=
0x04
;
}
else
if
(
!
is_have_audio
&&
is_have_video
)
{
flv_file_header
[
4
]
=
0x01
;
}
else
{
flv_file_header
[
4
]
=
0x00
;
}
//send flv header
send
(
flv_file_header
,
sizeof
(
flv_file_header
)
-
1
);
//send metadata
AMFEncoder
invoke
;
invoke
<<
"onMetaData"
<<
mediaSrc
->
getMetaData
();
sendRtmp
(
MSG_DATA
,
invoke
.
data
(),
0
);
//send config frame
mediaSrc
->
getConfigFrame
([
&
](
const
RtmpPacket
::
Ptr
&
pkt
){
onSendMedia
(
pkt
);
});
//开始发送rtmp负载
m_pRingReader
=
mediaSrc
->
getRing
()
->
attach
();
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
m_pRingReader
->
setReadCB
([
weakSelf
](
const
RtmpPacket
::
Ptr
&
pkt
){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
async
([
pkt
,
weakSelf
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
onSendMedia
(
pkt
);
});
});
m_pRingReader
->
setDetachCB
([
weakSelf
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
async_first
([
weakSelf
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
shutdown
();
});
});
};
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
Broadcast
::
AuthInvoker
invoker
=
[
weakSelf
,
onRes
](
bool
authSuccess
){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
;
}
strongSelf
->
async
([
weakSelf
,
onRes
,
authSuccess
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
;
}
onRes
(
authSuccess
);
});
};
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPlayed
,
info
,
invoker
);
if
(
!
flag
){
//该事件无人监听,默认不鉴权
onRes
(
true
);
}
return
true
;
}
inline
HttpSession
::
HttpCode
HttpSession
::
Handle_Req_GET
()
{
//先看看该http事件是否被拦截
...
...
@@ -274,11 +306,9 @@ inline HttpSession::HttpCode HttpSession::Handle_Req_GET() {
}
//事件未被拦截,则认为是http下载请求
auto
fullUrl
=
string
(
"http://"
)
+
m_parser
[
"Host"
]
+
m_parser
.
Url
();
auto
fullUrl
=
string
(
HTTP_SCHEMA
)
+
"://"
+
m_parser
[
"Host"
]
+
m_parser
.
Full
Url
();
MediaInfo
info
(
fullUrl
);
if
(
!
m_parser
.
getUrlArgs
()[
VHOST_KEY
].
empty
()){
info
.
m_vhost
=
m_parser
.
getUrlArgs
()[
VHOST_KEY
];
}
string
strFile
=
m_strPath
+
"/"
+
info
.
m_vhost
+
m_parser
.
Url
();
/////////////HTTP连接是否需要被关闭////////////////
static
uint32_t
reqCnt
=
mINI
::
Instance
()[
Config
::
Http
::
kMaxReqCount
].
as
<
uint32_t
>
();
...
...
src/Rtmp/RtmpSession.cpp
查看文件 @
ec902f51
差异被折叠。
点击展开。
src/Rtsp/Rtsp.h
查看文件 @
ec902f51
...
...
@@ -101,15 +101,15 @@ public:
}
if
(
start
==
buf
)
{
m_strMethod
=
FindField
(
line
.
c_str
(),
NULL
,
" "
);
auto
full_u
rl
=
FindField
(
line
.
c_str
(),
" "
,
" "
);
auto
args_pos
=
full_u
rl
.
find
(
'?'
);
m_strFullU
rl
=
FindField
(
line
.
c_str
(),
" "
,
" "
);
auto
args_pos
=
m_strFullU
rl
.
find
(
'?'
);
if
(
args_pos
!=
string
::
npos
){
m_strUrl
=
full_u
rl
.
substr
(
0
,
args_pos
);
m_mapUrlArgs
=
parseArgs
(
full_u
rl
.
substr
(
args_pos
+
1
));
m_strUrl
=
m_strFullU
rl
.
substr
(
0
,
args_pos
);
m_mapUrlArgs
=
parseArgs
(
m_strFullU
rl
.
substr
(
args_pos
+
1
));
}
else
{
m_strUrl
=
full_u
rl
;
m_strUrl
=
m_strFullU
rl
;
}
m_strTail
=
FindField
(
line
.
c_str
(),
(
full_u
rl
+
" "
).
c_str
(),
NULL
);
m_strTail
=
FindField
(
line
.
c_str
(),
(
m_strFullU
rl
+
" "
).
c_str
(),
NULL
);
}
else
{
auto
field
=
FindField
(
line
.
c_str
(),
NULL
,
": "
);
auto
value
=
FindField
(
line
.
c_str
(),
": "
,
NULL
);
...
...
@@ -132,6 +132,10 @@ public:
//rtsp url
return
m_strUrl
;
}
const
string
&
FullUrl
()
const
{
//rtsp url with args
return
m_strFullUrl
;
}
const
string
&
Tail
()
const
{
//RTSP/1.0
return
m_strTail
;
...
...
@@ -150,6 +154,7 @@ public:
void
Clear
()
{
m_strMethod
.
clear
();
m_strUrl
.
clear
();
m_strFullUrl
.
clear
();
m_strTail
.
clear
();
m_strContent
.
clear
();
m_mapValues
.
clear
();
...
...
@@ -189,6 +194,7 @@ private:
string
m_strTail
;
string
m_strContent
;
string
m_strNull
;
string
m_strFullUrl
;
mutable
StrCaseMap
m_mapValues
;
mutable
StrCaseMap
m_mapUrlArgs
;
};
...
...
src/Rtsp/RtspSession.cpp
查看文件 @
ec902f51
...
...
@@ -193,10 +193,7 @@ bool RtspSession::handleReq_Describe() {
{
//解析url获取媒体名称
m_strUrl
=
m_parser
.
Url
();
m_mediaInfo
.
parse
(
m_strUrl
);
if
(
!
m_parser
.
getUrlArgs
()[
VHOST_KEY
].
empty
()){
m_mediaInfo
.
m_vhost
=
m_parser
.
getUrlArgs
()[
VHOST_KEY
];
}
m_mediaInfo
.
parse
(
m_parser
.
FullUrl
());
}
if
(
!
findStream
())
{
...
...
@@ -644,82 +641,113 @@ bool RtspSession::handleReq_Play() {
send_SessionNotFound
();
return
false
;
}
auto
onRes
=
[
this
](
bool
authSuccess
){
char
response
[
2
*
1024
];
m_pcBuf
=
response
;
if
(
!
authSuccess
&&
m_bFirstPlay
){
//第一次play是播放,否则是恢复播放。只对播放鉴权
int
n
=
sprintf
(
m_pcBuf
,
"RTSP/1.0 401 Unauthorized
\r\n
"
"CSeq: %d
\r\n
"
"Server: %s-%0.2f(build in %s)
\r\n
"
"%s
\r\n
"
,
m_iCseq
,
SERVER_NAME
,
RTSP_VERSION
,
RTSP_BUILDTIME
,
dateHeader
().
data
());
send
(
m_pcBuf
,
n
);
shutdown
();
return
;
}
if
(
m_pRtpReader
){
weak_ptr
<
RtspSession
>
weakSelf
=
dynamic_pointer_cast
<
RtspSession
>
(
shared_from_this
());
SockUtil
::
setNoDelay
(
m_pSender
->
rawFD
(),
false
);
m_pRtpReader
->
setReadCB
([
weakSelf
](
const
RtpPacket
::
Ptr
&
pack
)
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
async
([
weakSelf
,
pack
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
sendRtpPacket
(
pack
);
});
});
}
if
(
m_pRtpReader
){
weak_ptr
<
RtspSession
>
weakSelf
=
dynamic_pointer_cast
<
RtspSession
>
(
shared_from_this
());
SockUtil
::
setNoDelay
(
m_pSender
->
rawFD
(),
false
);
m_pRtpReader
->
setReadCB
([
weakSelf
](
const
RtpPacket
::
Ptr
&
pack
)
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
async
([
weakSelf
,
pack
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
}
strongSelf
->
sendRtpPacket
(
pack
);
});
});
}
auto
pMediaSrc
=
m_pMediaSrc
.
lock
();
uint32_t
iStamp
=
0
;
if
(
pMediaSrc
){
auto
strRange
=
m_parser
[
"Range"
];
if
(
strRange
.
size
()
&&
!
m_bFirstPlay
)
{
auto
strStart
=
FindField
(
strRange
.
data
(),
"npt="
,
"-"
);
if
(
strStart
==
"now"
)
{
strStart
=
"0"
;
}
auto
iStartTime
=
atof
(
strStart
.
data
());
InfoL
<<
"rtsp seekTo:"
<<
iStartTime
;
pMediaSrc
->
seekTo
(
iStartTime
*
1000
);
iStamp
=
pMediaSrc
->
getStamp
();
}
else
if
(
pMediaSrc
->
getRing
()
->
readerCount
()
==
1
){
//第一个消费者
pMediaSrc
->
seekTo
(
0
);
iStamp
=
0
;
}
else
{
iStamp
=
pMediaSrc
->
getStamp
();
auto
pMediaSrc
=
m_pMediaSrc
.
lock
();
uint32_t
iStamp
=
0
;
if
(
pMediaSrc
){
auto
strRange
=
m_parser
[
"Range"
];
if
(
strRange
.
size
()
&&
!
m_bFirstPlay
)
{
auto
strStart
=
FindField
(
strRange
.
data
(),
"npt="
,
"-"
);
if
(
strStart
==
"now"
)
{
strStart
=
"0"
;
}
auto
iStartTime
=
atof
(
strStart
.
data
());
InfoL
<<
"rtsp seekTo:"
<<
iStartTime
;
pMediaSrc
->
seekTo
(
iStartTime
*
1000
);
iStamp
=
pMediaSrc
->
getStamp
();
}
else
if
(
pMediaSrc
->
getRing
()
->
readerCount
()
==
1
){
//第一个消费者
pMediaSrc
->
seekTo
(
0
);
iStamp
=
0
;
}
else
{
iStamp
=
pMediaSrc
->
getStamp
();
}
for
(
unsigned
int
i
=
0
;
i
<
m_uiTrackCnt
;
i
++
)
{
auto
&
track
=
m_aTrackInfo
[
i
];
track
.
ssrc
=
pMediaSrc
->
getSsrc
(
track
.
trackId
);
track
.
seq
=
pMediaSrc
->
getSeqence
(
track
.
trackId
);
track
.
timeStamp
=
pMediaSrc
->
getTimestamp
(
track
.
trackId
);
}
}
for
(
unsigned
int
i
=
0
;
i
<
m_uiTrackCnt
;
i
++
)
{
auto
&
track
=
m_aTrackInfo
[
i
];
track
.
ssrc
=
pMediaSrc
->
getSsrc
(
track
.
trackId
);
track
.
seq
=
pMediaSrc
->
getSeqence
(
track
.
trackId
);
track
.
timeStamp
=
pMediaSrc
->
getTimestamp
(
track
.
trackId
);
}
}
m_bFirstPlay
=
false
;
int
iLen
=
sprintf
(
m_pcBuf
,
"RTSP/1.0 200 OK
\r\n
"
"CSeq: %d
\r\n
"
"Server: %s-%0.2f(build in %s)
\r\n
"
"%s"
"Session: %s
\r\n
"
"Range: npt=%.2f-
\r\n
"
"RTP-Info: "
,
m_iCseq
,
SERVER_NAME
,
RTSP_VERSION
,
RTSP_BUILDTIME
,
dateHeader
().
data
(),
m_strSession
.
data
(),
iStamp
/
1000.0
);
m_bFirstPlay
=
false
;
int
iLen
=
sprintf
(
m_pcBuf
,
"RTSP/1.0 200 OK
\r\n
"
"CSeq: %d
\r\n
"
"Server: %s-%0.2f(build in %s)
\r\n
"
"%s"
"Session: %s
\r\n
"
"Range: npt=%.2f-
\r\n
"
"RTP-Info: "
,
m_iCseq
,
SERVER_NAME
,
RTSP_VERSION
,
RTSP_BUILDTIME
,
dateHeader
().
data
(),
m_strSession
.
data
(),
iStamp
/
1000.0
);
for
(
unsigned
int
i
=
0
;
i
<
m_uiTrackCnt
;
i
++
)
{
auto
&
track
=
m_aTrackInfo
[
i
];
if
(
track
.
inited
==
false
)
{
//还有track没有setup
shutdown
();
return
;
}
iLen
+=
sprintf
(
m_pcBuf
+
iLen
,
"url=%s/%s%d;seq=%d;rtptime=%u,"
,
m_strUrl
.
data
(),
track
.
trackStyle
.
data
(),
track
.
trackId
,
track
.
seq
,
track
.
timeStamp
);
}
iLen
-=
1
;
(
m_pcBuf
)[
iLen
]
=
'\0'
;
iLen
+=
sprintf
(
m_pcBuf
+
iLen
,
"
\r\n\r\n
"
);
send
(
m_pcBuf
,
iLen
);
};
for
(
unsigned
int
i
=
0
;
i
<
m_uiTrackCnt
;
i
++
)
{
auto
&
track
=
m_aTrackInfo
[
i
];
if
(
track
.
inited
==
false
)
{
//还有track没有setup
return
false
;
}
iLen
+=
sprintf
(
m_pcBuf
+
iLen
,
"url=%s/%s%d;seq=%d;rtptime=%u,"
,
m_strUrl
.
data
(),
track
.
trackStyle
.
data
(),
track
.
trackId
,
track
.
seq
,
track
.
timeStamp
);
}
iLen
-=
1
;
(
m_pcBuf
)[
iLen
]
=
'\0'
;
iLen
+=
sprintf
(
m_pcBuf
+
iLen
,
"
\r\n\r\n
"
);
send
(
m_pcBuf
,
iLen
)
;
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPlayed
,
RTSP_SCHEMA
,
m_mediaInfo
.
m_vhost
.
data
(),
m_mediaInfo
.
m_app
.
data
(),
m_mediaInfo
.
m_streamid
.
data
());
weak_ptr
<
RtspSession
>
weakSelf
=
dynamic_pointer_cast
<
RtspSession
>
(
shared_from_this
());
Broadcast
::
AuthInvoker
invoker
=
[
weakSelf
,
onRes
](
bool
authSuccess
){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
;
}
strongSelf
->
async
([
weakSelf
,
onRes
,
authSuccess
](){
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
){
return
;
}
onRes
(
authSuccess
)
;
}
);
}
;
auto
flag
=
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastMediaPlayed
,
m_mediaInfo
,
invoker
);
if
(
!
flag
){
//该事件无人监听,默认不鉴权
onRes
(
true
);
}
return
true
;
}
...
...
tests/test_server.cpp
查看文件 @
ec902f51
...
...
@@ -107,6 +107,22 @@ static onceToken s_token([](){
invoker
(
false
,
user
);
});
});
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Config
::
Broadcast
::
kBroadcastRtmpPublish
,[](
BroadcastRtmpPublishArgs
){
InfoL
<<
args
.
m_vhost
<<
" "
<<
args
.
m_app
<<
" "
<<
args
.
m_streamid
<<
" "
<<
args
.
m_param_strs
;
EventPoller
::
Instance
().
async
([
invoker
](){
invoker
(
true
);
});
});
NoticeCenter
::
Instance
().
addListener
(
nullptr
,
Config
::
Broadcast
::
kBroadcastMediaPlayed
,[](
BroadcastMediaPlayedArgs
){
InfoL
<<
args
.
m_schema
<<
" "
<<
args
.
m_vhost
<<
" "
<<
args
.
m_app
<<
" "
<<
args
.
m_streamid
<<
" "
<<
args
.
m_param_strs
;
EventPoller
::
Instance
().
async
([
invoker
](){
invoker
(
true
);
});
});
},
nullptr
);
int
main
(
int
argc
,
char
*
argv
[]){
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论