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
34838b1b
Commit
34838b1b
authored
Sep 30, 2022
by
ziyue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rtmp点播采用简单握手,发送心跳包,兼容fms服务器: #2007
parent
bfebcd62
隐藏空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
46 行增加
和
30 行删除
+46
-30
src/Rtmp/RtmpPlayer.cpp
+26
-23
src/Rtmp/RtmpProtocol.cpp
+15
-4
src/Rtmp/RtmpProtocol.h
+5
-3
没有找到文件。
src/Rtmp/RtmpPlayer.cpp
查看文件 @
34838b1b
...
...
@@ -44,11 +44,16 @@ void RtmpPlayer::teardown() {
_deque_on_status
.
clear
();
}
void
RtmpPlayer
::
play
(
const
string
&
strU
rl
)
{
void
RtmpPlayer
::
play
(
const
string
&
u
rl
)
{
teardown
();
string
host_url
=
FindField
(
strUrl
.
data
(),
"://"
,
"/"
);
_app
=
FindField
(
strUrl
.
data
(),
(
host_url
+
"/"
).
data
(),
"/"
);
_stream_id
=
FindField
(
strUrl
.
data
(),
(
host_url
+
"/"
+
_app
+
"/"
).
data
(),
NULL
);
string
host_url
=
FindField
(
url
.
data
(),
"://"
,
"/"
);
{
auto
pos
=
url
.
find_last_of
(
'/'
);
if
(
pos
!=
string
::
npos
)
{
_stream_id
=
url
.
substr
(
pos
+
1
);
}
}
_app
=
FindField
(
url
.
data
(),
(
host_url
+
"/"
).
data
(),
(
"/"
+
_stream_id
).
data
());
_tc_url
=
string
(
"rtmp://"
)
+
host_url
+
"/"
+
_app
;
if
(
!
_app
.
size
()
||
!
_stream_id
.
size
())
{
...
...
@@ -109,16 +114,16 @@ void RtmpPlayer::onPlayResult_l(const SockException &ex, bool handshake_done) {
//播放成功,恢复rtmp接收超时定时器
_rtmp_recv_ticker
.
resetTime
();
auto
timeout_ms
=
(
*
this
)[
Client
::
kMediaTimeoutMS
].
as
<
uint64_t
>
();
weak_ptr
<
RtmpPlayer
>
weak
S
elf
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
auto
lam
=
[
weak
S
elf
,
timeout_ms
]()
{
auto
strong
Self
=
weakS
elf
.
lock
();
if
(
!
strong
S
elf
)
{
weak_ptr
<
RtmpPlayer
>
weak
_s
elf
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
auto
lam
=
[
weak
_s
elf
,
timeout_ms
]()
{
auto
strong
_self
=
weak_s
elf
.
lock
();
if
(
!
strong
_s
elf
)
{
return
false
;
}
if
(
strong
S
elf
->
_rtmp_recv_ticker
.
elapsedTime
()
>
timeout_ms
)
{
if
(
strong
_s
elf
->
_rtmp_recv_ticker
.
elapsedTime
()
>
timeout_ms
)
{
//接收rtmp媒体数据超时
SockException
ex
(
Err_timeout
,
"receive rtmp timeout"
);
strong
S
elf
->
onPlayResult_l
(
ex
,
true
);
strong
_s
elf
->
onPlayResult_l
(
ex
,
true
);
return
false
;
}
return
true
;
...
...
@@ -130,19 +135,17 @@ void RtmpPlayer::onPlayResult_l(const SockException &ex, bool handshake_done) {
}
}
void
RtmpPlayer
::
onConnect
(
const
SockException
&
err
){
void
RtmpPlayer
::
onConnect
(
const
SockException
&
err
)
{
if
(
err
.
getErrCode
()
!=
Err_success
)
{
onPlayResult_l
(
err
,
false
);
return
;
}
weak_ptr
<
RtmpPlayer
>
weakSelf
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
startClientSession
([
weakSelf
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
return
;
weak_ptr
<
RtmpPlayer
>
weak_self
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
startClientSession
([
weak_self
]()
{
if
(
auto
strong_self
=
weak_self
.
lock
())
{
strong_self
->
send_connect
();
}
strongSelf
->
send_connect
();
});
},
_app
.
find
(
"vod"
)
!=
0
);
// 实测发现vod点播时,使用复杂握手fms无响应:issue #2007
}
void
RtmpPlayer
::
onRecv
(
const
Buffer
::
Ptr
&
buf
){
...
...
@@ -249,14 +252,14 @@ inline void RtmpPlayer::send_pause(bool pause) {
_beat_timer
.
reset
();
if
(
pause
)
{
weak_ptr
<
RtmpPlayer
>
weak
S
elf
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
_beat_timer
.
reset
(
new
Timer
((
*
this
)[
Client
::
kBeatIntervalMS
].
as
<
int
>
()
/
1000.0
f
,
[
weak
S
elf
]()
{
auto
strong
Self
=
weakS
elf
.
lock
();
if
(
!
strong
S
elf
)
{
weak_ptr
<
RtmpPlayer
>
weak
_s
elf
=
dynamic_pointer_cast
<
RtmpPlayer
>
(
shared_from_this
());
_beat_timer
.
reset
(
new
Timer
((
*
this
)[
Client
::
kBeatIntervalMS
].
as
<
int
>
()
/
1000.0
f
,
[
weak
_s
elf
]()
{
auto
strong
_self
=
weak_s
elf
.
lock
();
if
(
!
strong
_s
elf
)
{
return
false
;
}
uint32_t
timeStamp
=
(
uint32_t
)
::
time
(
NULL
);
strong
S
elf
->
sendUserControl
(
CONTROL_PING_REQUEST
,
timeStamp
);
strong
_s
elf
->
sendUserControl
(
CONTROL_PING_REQUEST
,
timeStamp
);
return
true
;
},
getPoller
()));
}
...
...
src/Rtmp/RtmpProtocol.cpp
查看文件 @
34838b1b
...
...
@@ -288,12 +288,14 @@ const char *RtmpProtocol::onSearchPacketTail(const char *data,size_t len){
}
////for client////
void
RtmpProtocol
::
startClientSession
(
const
function
<
void
()
>
&
func
)
{
void
RtmpProtocol
::
startClientSession
(
const
function
<
void
()
>
&
func
,
bool
complex
)
{
//发送 C0C1
char
handshake_head
=
HANDSHAKE_PLAINTEXT
;
onSendRawData
(
obtainBuffer
(
&
handshake_head
,
1
));
RtmpHandshake
c1
(
0
);
c1
.
create_complex_c0c1
();
if
(
complex
)
{
c1
.
create_complex_c0c1
();
}
onSendRawData
(
obtainBuffer
((
char
*
)
(
&
c1
),
sizeof
(
c1
)));
_next_step_func
=
[
this
,
func
](
const
char
*
data
,
size_t
len
)
{
//等待 S0+S1+S2
...
...
@@ -754,7 +756,8 @@ void RtmpProtocol::handle_chunk(RtmpPacket::Ptr packet) {
case
MSG_WIN_SIZE
:
{
//如果窗口太小,会导致发送sendAcknowledgement时无限递归:https://github.com/ZLMediaKit/ZLMediaKit/issues/1839
_windows_size
=
max
(
load_be32
(
&
chunk_data
.
buffer
[
0
]),
32
*
1024U
);
//窗口太大,也可能导致fms服务器认为播放器心跳超时
_windows_size
=
min
(
max
(
load_be32
(
&
chunk_data
.
buffer
[
0
]),
32
*
1024U
),
1280
*
1024U
);
TraceL
<<
"MSG_WIN_SIZE:"
<<
_windows_size
;
break
;
}
...
...
@@ -806,7 +809,15 @@ void RtmpProtocol::handle_chunk(RtmpPacket::Ptr packet) {
break
;
}
default
:
onRtmpChunk
(
std
::
move
(
packet
));
break
;
default
:
{
_bytes_recv
+=
packet
->
size
();
if
(
_windows_size
>
0
&&
_bytes_recv
-
_bytes_recv_last
>=
_windows_size
)
{
_bytes_recv_last
=
_bytes_recv
;
sendAcknowledgement
(
_bytes_recv
);
}
onRtmpChunk
(
std
::
move
(
packet
));
break
;
}
}
}
...
...
src/Rtmp/RtmpProtocol.h
查看文件 @
34838b1b
...
...
@@ -32,7 +32,7 @@ public:
void
onParseRtmp
(
const
char
*
data
,
size_t
size
);
//作为客户端发送c0c1,等待s0s1s2并且回调
void
startClientSession
(
const
std
::
function
<
void
()
>
&
cb
);
void
startClientSession
(
const
std
::
function
<
void
()
>
&
cb
,
bool
complex
=
true
);
protected
:
virtual
void
onSendRawData
(
toolkit
::
Buffer
::
Ptr
buffer
)
=
0
;
...
...
@@ -94,8 +94,10 @@ private:
size_t
_chunk_size_in
=
DEFAULT_CHUNK_LEN
;
size_t
_chunk_size_out
=
DEFAULT_CHUNK_LEN
;
////////////Acknowledgement////////////
uint32_t
_bytes_sent
=
0
;
uint32_t
_bytes_sent_last
=
0
;
uint64_t
_bytes_sent
=
0
;
uint64_t
_bytes_sent_last
=
0
;
uint64_t
_bytes_recv
=
0
;
uint64_t
_bytes_recv_last
=
0
;
uint32_t
_windows_size
=
0
;
///////////PeerBandwidth///////////
uint32_t
_bandwidth
=
2500000
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论