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
fdfde17e
Commit
fdfde17e
authored
Nov 10, 2021
by
ziyue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Demuxer/Player: 修改解复用与播放器底层逻辑,确保触发播放成功回调时不丢帧
parent
37fdb8d1
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
251 行增加
和
230 行删除
+251
-230
src/Common/MediaSink.cpp
+4
-3
src/Common/config.cpp
+0
-1
src/Common/config.h
+0
-2
src/Player/MediaPlayer.cpp
+4
-26
src/Player/MediaPlayer.h
+4
-6
src/Player/PlayerBase.cpp
+53
-59
src/Player/PlayerBase.h
+0
-0
src/Player/PlayerProxy.cpp
+5
-5
src/Rtmp/RtmpDemuxer.cpp
+37
-31
src/Rtmp/RtmpDemuxer.h
+11
-2
src/Rtmp/RtmpPlayerImp.h
+41
-23
src/Rtsp/RtspDemuxer.cpp
+50
-44
src/Rtsp/RtspDemuxer.h
+12
-1
src/Rtsp/RtspPlayerImp.h
+30
-27
没有找到文件。
src/Common/MediaSink.cpp
查看文件 @
fdfde17e
...
...
@@ -181,7 +181,7 @@ void MediaSink::emitAllTrackReady() {
void
MediaSink
::
onAllTrackReady_l
()
{
//是否添加静音音频
GET_CONFIG
(
bool
,
addMuteAudio
,
General
::
kAddMuteAudio
);
if
(
addMuteAudio
&&
!
_track_map
[
TrackAudio
]
)
{
if
(
addMuteAudio
&&
_track_map
.
find
(
TrackAudio
)
==
_track_map
.
end
()
)
{
addMuteAudioTrack
();
}
onAllTrackReady
();
...
...
@@ -253,11 +253,12 @@ bool MuteAudioMaker::inputFrame(const Frame::Ptr &frame) {
}
bool
MediaSink
::
addMuteAudioTrack
()
{
if
(
getTrack
(
TrackAudio
,
false
))
{
if
(
_track_map
.
find
(
TrackAudio
)
!=
_track_map
.
end
(
))
{
WarnL
<<
"audio track already existed"
;
return
false
;
}
if
(
addTrack
(
std
::
make_shared
<
AACTrack
>
()))
{
if
(
MediaSink
::
addTrack
(
std
::
make_shared
<
AACTrack
>
(
makeAacConfig
(
MUTE_ADTS_DATA
,
ADTS_HEADER_LEN
))))
{
_mute_audio_maker
=
std
::
make_shared
<
MuteAudioMaker
>
();
_mute_audio_maker
->
addDelegate
(
std
::
make_shared
<
FrameWriterInterfaceHelper
>
([
this
](
const
Frame
::
Ptr
&
frame
)
{
return
inputFrame
(
frame
);
...
...
src/Common/config.cpp
查看文件 @
fdfde17e
...
...
@@ -305,7 +305,6 @@ const string kRtspPwdIsMD5 = "rtsp_pwd_md5";
const
string
kTimeoutMS
=
"protocol_timeout_ms"
;
const
string
kMediaTimeoutMS
=
"media_timeout_ms"
;
const
string
kBeatIntervalMS
=
"beat_interval_ms"
;
const
string
kMaxAnalysisMS
=
"max_analysis_ms"
;
const
string
kBenchmarkMode
=
"benchmark_mode"
;
}
...
...
src/Common/config.h
查看文件 @
fdfde17e
...
...
@@ -329,8 +329,6 @@ extern const string kTimeoutMS;
extern
const
string
kMediaTimeoutMS
;
//rtsp/rtmp心跳时间,默认5000毫秒
extern
const
string
kBeatIntervalMS
;
//Track编码格式探测最大时间,单位毫秒,默认2000
extern
const
string
kMaxAnalysisMS
;
//是否为性能测试模式,性能测试模式开启后不会解析rtp或rtmp包
extern
const
string
kBenchmarkMode
;
}
...
...
src/Player/MediaPlayer.cpp
查看文件 @
fdfde17e
...
...
@@ -20,9 +20,6 @@ MediaPlayer::MediaPlayer(const EventPoller::Ptr &poller) {
_poller
=
poller
?
poller
:
EventPollerPool
::
Instance
().
getPoller
();
}
MediaPlayer
::~
MediaPlayer
()
{
}
static
void
setOnCreateSocket_l
(
const
std
::
shared_ptr
<
PlayerBase
>
&
delegate
,
const
Socket
::
onCreateSocket
&
cb
){
auto
helper
=
dynamic_pointer_cast
<
SocketHelper
>
(
delegate
);
if
(
helper
)
{
...
...
@@ -41,10 +38,10 @@ void MediaPlayer::play(const string &url) {
_delegate
=
PlayerBase
::
createPlayer
(
_poller
,
url
);
assert
(
_delegate
);
setOnCreateSocket_l
(
_delegate
,
_on_create_socket
);
_delegate
->
setOnShutdown
(
_
shutdownCB
);
_delegate
->
setOnPlayResult
(
_
playResultCB
);
_delegate
->
setOnResume
(
_
resumeCB
);
_delegate
->
setMediaSource
(
_
pMediaS
rc
);
_delegate
->
setOnShutdown
(
_
on_shutdown
);
_delegate
->
setOnPlayResult
(
_
on_play_result
);
_delegate
->
setOnResume
(
_
on_resume
);
_delegate
->
setMediaSource
(
_
media_s
rc
);
_delegate
->
mINI
::
operator
=
(
*
this
);
_delegate
->
play
(
url
);
}
...
...
@@ -58,23 +55,4 @@ void MediaPlayer::setOnCreateSocket(Socket::onCreateSocket cb){
_on_create_socket
=
std
::
move
(
cb
);
}
void
MediaPlayer
::
pause
(
bool
pause
)
{
if
(
_delegate
)
{
_delegate
->
pause
(
pause
);
}
}
void
MediaPlayer
::
speed
(
float
speed
)
{
if
(
_delegate
)
{
_delegate
->
speed
(
speed
);
}
}
void
MediaPlayer
::
teardown
()
{
if
(
_delegate
)
{
_delegate
->
teardown
();
}
}
}
/* namespace mediakit */
src/Player/MediaPlayer.h
查看文件 @
fdfde17e
...
...
@@ -21,16 +21,14 @@ using namespace toolkit;
namespace
mediakit
{
class
MediaPlayer
:
public
PlayerImp
<
PlayerBase
,
PlayerBase
>
{
class
MediaPlayer
:
public
PlayerImp
<
PlayerBase
,
PlayerBase
>
{
public
:
typedef
std
::
shared_ptr
<
MediaPlayer
>
Ptr
;
using
Ptr
=
std
::
shared_ptr
<
MediaPlayer
>
;
MediaPlayer
(
const
EventPoller
::
Ptr
&
poller
=
nullptr
);
virtual
~
MediaPlayer
();
~
MediaPlayer
()
override
=
default
;
void
play
(
const
string
&
url
)
override
;
void
pause
(
bool
pause
)
override
;
void
speed
(
float
speed
)
override
;
void
teardown
()
override
;
EventPoller
::
Ptr
getPoller
();
void
setOnCreateSocket
(
Socket
::
onCreateSocket
cb
);
...
...
src/Player/PlayerBase.cpp
查看文件 @
fdfde17e
...
...
@@ -13,14 +13,15 @@
#include "Rtsp/RtspPlayerImp.h"
#include "Rtmp/RtmpPlayerImp.h"
#include "Http/HlsPlayer.h"
using
namespace
toolkit
;
namespace
mediakit
{
PlayerBase
::
Ptr
PlayerBase
::
createPlayer
(
const
EventPoller
::
Ptr
&
poller
,
const
string
&
url_in
)
{
static
auto
releasePlayer
=
[](
PlayerBase
*
ptr
){
onceToken
token
(
nullptr
,
[
&
]()
{
delete
ptr
;
PlayerBase
::
Ptr
PlayerBase
::
createPlayer
(
const
EventPoller
::
Ptr
&
poller
,
const
string
&
url_in
)
{
static
auto
releasePlayer
=
[](
PlayerBase
*
ptr
)
{
onceToken
token
(
nullptr
,
[
&
]()
{
delete
ptr
;
});
ptr
->
teardown
();
};
...
...
@@ -32,98 +33,91 @@ PlayerBase::Ptr PlayerBase::createPlayer(const EventPoller::Ptr &poller,const st
url
=
url
.
substr
(
0
,
pos
);
}
if
(
strcasecmp
(
"rtsps"
,
prefix
.
data
())
==
0
)
{
return
PlayerBase
::
Ptr
(
new
TcpClientWithSSL
<
RtspPlayerImp
>
(
poller
),
releasePlayer
);
if
(
strcasecmp
(
"rtsps"
,
prefix
.
data
())
==
0
)
{
return
PlayerBase
::
Ptr
(
new
TcpClientWithSSL
<
RtspPlayerImp
>
(
poller
),
releasePlayer
);
}
if
(
strcasecmp
(
"rtsp"
,
prefix
.
data
())
==
0
)
{
return
PlayerBase
::
Ptr
(
new
RtspPlayerImp
(
poller
),
releasePlayer
);
if
(
strcasecmp
(
"rtsp"
,
prefix
.
data
())
==
0
)
{
return
PlayerBase
::
Ptr
(
new
RtspPlayerImp
(
poller
),
releasePlayer
);
}
if
(
strcasecmp
(
"rtmps"
,
prefix
.
data
())
==
0
)
{
return
PlayerBase
::
Ptr
(
new
TcpClientWithSSL
<
RtmpPlayerImp
>
(
poller
),
releasePlayer
);
if
(
strcasecmp
(
"rtmps"
,
prefix
.
data
())
==
0
)
{
return
PlayerBase
::
Ptr
(
new
TcpClientWithSSL
<
RtmpPlayerImp
>
(
poller
),
releasePlayer
);
}
if
(
strcasecmp
(
"rtmp"
,
prefix
.
data
())
==
0
)
{
return
PlayerBase
::
Ptr
(
new
RtmpPlayerImp
(
poller
),
releasePlayer
);
if
(
strcasecmp
(
"rtmp"
,
prefix
.
data
())
==
0
)
{
return
PlayerBase
::
Ptr
(
new
RtmpPlayerImp
(
poller
),
releasePlayer
);
}
if
((
strcasecmp
(
"http"
,
prefix
.
data
())
==
0
||
strcasecmp
(
"https"
,
prefix
.
data
())
==
0
)
&&
end_with
(
url
,
".m3u8"
))
{
return
PlayerBase
::
Ptr
(
new
HlsPlayerImp
(
poller
),
releasePlayer
);
if
((
strcasecmp
(
"http"
,
prefix
.
data
())
==
0
||
strcasecmp
(
"https"
,
prefix
.
data
())
==
0
)
&&
end_with
(
url
,
".m3u8"
))
{
return
PlayerBase
::
Ptr
(
new
HlsPlayerImp
(
poller
),
releasePlayer
);
}
return
PlayerBase
::
Ptr
(
new
RtspPlayerImp
(
poller
),
releasePlayer
);
return
PlayerBase
::
Ptr
(
new
RtspPlayerImp
(
poller
),
releasePlayer
);
}
PlayerBase
::
PlayerBase
()
{
this
->
mINI
::
operator
[](
kTimeoutMS
)
=
10000
;
this
->
mINI
::
operator
[](
kMediaTimeoutMS
)
=
5000
;
this
->
mINI
::
operator
[](
kBeatIntervalMS
)
=
5000
;
this
->
mINI
::
operator
[](
kMaxAnalysisMS
)
=
5000
;
}
///////////////////////////Demuxer//////////////////////////////
bool
Demuxer
::
isInited
(
int
analysisMs
)
{
if
(
analysisMs
&&
_ticker
.
createdTime
()
>
(
uint64_t
)
analysisMs
){
//analysisMs毫秒后强制初始化完毕
return
true
;
}
if
(
_videoTrack
&&
!
_videoTrack
->
ready
())
{
//视频未准备好
return
false
;
}
if
(
_audioTrack
&&
!
_audioTrack
->
ready
())
{
//音频未准备好
return
false
;
}
return
true
;
}
vector
<
Track
::
Ptr
>
Demuxer
::
getTracks
(
bool
trackReady
)
const
{
vector
<
Track
::
Ptr
>
ret
;
if
(
_videoTrack
){
if
(
trackReady
){
if
(
_videoTrack
->
ready
()){
ret
.
emplace_back
(
_videoTrack
);
}
}
else
{
ret
.
emplace_back
(
_videoTrack
);
}
}
if
(
_audioTrack
){
if
(
trackReady
){
if
(
_audioTrack
->
ready
()){
ret
.
emplace_back
(
_audioTrack
);
}
}
else
{
ret
.
emplace_back
(
_audioTrack
);
}
bool
Demuxer
::
addTrack
(
const
Track
::
Ptr
&
track
)
{
auto
ret
=
MediaSink
::
addTrack
(
track
);
if
(
ret
)
{
track
->
addDelegate
(
std
::
make_shared
<
FrameWriterInterfaceHelper
>
([
this
](
const
Frame
::
Ptr
&
frame
)
{
return
inputFrame
(
frame
);
}));
}
return
ret
;
}
float
Demuxer
::
getDuration
()
const
{
return
_fDuration
;
void
Demuxer
::
setTrackListener
(
TrackListener
*
listener
)
{
_listener
=
listener
;
}
bool
Demuxer
::
addTrack
(
const
Track
::
Ptr
&
track
){
return
_listener
?
_listener
->
addTrack
(
track
)
:
false
;
bool
Demuxer
::
onTrackReady
(
const
Track
::
Ptr
&
track
)
{
_tracks
[
track
->
getTrackType
()]
=
track
->
clone
();
return
true
;
}
void
Demuxer
::
addTrackCompleted
(){
if
(
_listener
){
_listener
->
addTrackCompleted
();
void
Demuxer
::
onAllTrackReady
()
{
if
(
!
_listener
)
{
return
;
}
for
(
auto
&
track
:
_tracks
)
{
if
(
track
)
{
_listener
->
addTrack
(
track
);
}
}
_listener
->
addTrackCompleted
();
}
bool
Demuxer
::
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
{
return
_tracks
[
frame
->
getTrackType
()]
->
inputFrame
(
frame
);
}
void
Demuxer
::
resetTracks
()
{
MediaSink
::
resetTracks
();
for
(
auto
&
track
:
_tracks
)
{
track
=
nullptr
;
}
if
(
_listener
)
{
_listener
->
resetTracks
();
}
}
void
Demuxer
::
setTrackListener
(
TrackListener
*
listener
)
{
_listener
=
listener
;
vector
<
Track
::
Ptr
>
Demuxer
::
getTracks
(
bool
ready
)
const
{
vector
<
Track
::
Ptr
>
ret
;
for
(
auto
&
track
:
_tracks
)
{
if
(
!
track
||
(
ready
&&
!
track
->
ready
()))
{
continue
;
}
ret
.
emplace_back
(
track
);
}
return
ret
;
}
}
/* namespace mediakit */
src/Player/PlayerBase.h
查看文件 @
fdfde17e
差异被折叠。
点击展开。
src/Player/PlayerProxy.cpp
查看文件 @
fdfde17e
...
...
@@ -160,7 +160,7 @@ bool PlayerProxy::close(MediaSource &sender, bool force) {
}
int
PlayerProxy
::
totalReaderCount
()
{
return
(
_muxer
?
_muxer
->
totalReaderCount
()
:
0
)
+
(
_
pMediaSrc
?
_pMediaS
rc
->
readerCount
()
:
0
);
return
(
_muxer
?
_muxer
->
totalReaderCount
()
:
0
)
+
(
_
media_src
?
_media_s
rc
->
readerCount
()
:
0
);
}
int
PlayerProxy
::
totalReaderCount
(
MediaSource
&
sender
)
{
...
...
@@ -181,12 +181,12 @@ std::shared_ptr<SockInfo> PlayerProxy::getOriginSock(MediaSource &sender) const
void
PlayerProxy
::
onPlaySuccess
()
{
GET_CONFIG
(
bool
,
resetWhenRePlay
,
General
::
kResetWhenRePlay
);
if
(
dynamic_pointer_cast
<
RtspMediaSource
>
(
_
pMediaS
rc
))
{
if
(
dynamic_pointer_cast
<
RtspMediaSource
>
(
_
media_s
rc
))
{
//rtsp拉流代理
if
(
resetWhenRePlay
||
!
_muxer
)
{
_muxer
.
reset
(
new
MultiMediaSourceMuxer
(
_vhost
,
_app
,
_stream_id
,
getDuration
(),
false
,
true
,
_enable_hls
,
_enable_mp4
));
}
}
else
if
(
dynamic_pointer_cast
<
RtmpMediaSource
>
(
_
pMediaS
rc
))
{
}
else
if
(
dynamic_pointer_cast
<
RtmpMediaSource
>
(
_
media_s
rc
))
{
//rtmp拉流代理
if
(
resetWhenRePlay
||
!
_muxer
)
{
_muxer
.
reset
(
new
MultiMediaSourceMuxer
(
_vhost
,
_app
,
_stream_id
,
getDuration
(),
true
,
false
,
_enable_hls
,
_enable_mp4
));
...
...
@@ -218,9 +218,9 @@ void PlayerProxy::onPlaySuccess() {
//添加完毕所有track,防止单track情况下最大等待3秒
_muxer
->
addTrackCompleted
();
if
(
_
pMediaS
rc
)
{
if
(
_
media_s
rc
)
{
//让_muxer对象拦截一部分事件(比如说录像相关事件)
_
pMediaS
rc
->
setListener
(
_muxer
);
_
media_s
rc
->
setListener
(
_muxer
);
}
}
...
...
src/Rtmp/RtmpDemuxer.cpp
查看文件 @
fdfde17e
...
...
@@ -25,7 +25,7 @@ bool RtmpDemuxer::loadMetaData(const AMFValue &val){
const
AMFValue
*
videocodecid
=
nullptr
;
val
.
object_for_each
([
&
](
const
string
&
key
,
const
AMFValue
&
val
)
{
if
(
key
==
"duration"
)
{
_
fD
uration
=
(
float
)
val
.
as_number
();
_
d
uration
=
(
float
)
val
.
as_number
();
return
;
}
if
(
key
==
"audiosamplerate"
)
{
...
...
@@ -80,6 +80,10 @@ bool RtmpDemuxer::loadMetaData(const AMFValue &val){
return
ret
;
}
float
RtmpDemuxer
::
getDuration
()
const
{
return
_duration
;
}
void
RtmpDemuxer
::
inputRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
)
{
switch
(
pkt
->
type_id
)
{
case
MSG_VIDEO
:
{
...
...
@@ -111,41 +115,42 @@ void RtmpDemuxer::inputRtmp(const RtmpPacket::Ptr &pkt) {
void
RtmpDemuxer
::
makeVideoTrack
(
const
AMFValue
&
videoCodec
,
int
bit_rate
)
{
//生成Track对象
_videoTrack
=
dynamic_pointer_cast
<
VideoTrack
>
(
Factory
::
getVideoTrackByAmf
(
videoCodec
));
if
(
_videoTrack
)
{
_videoTrack
->
setBitRate
(
bit_rate
);
//生成rtmpCodec对象以便解码rtmp
_video_rtmp_decoder
=
Factory
::
getRtmpCodecByTrack
(
_videoTrack
,
false
);
if
(
_video_rtmp_decoder
)
{
//设置rtmp解码器代理,生成的frame写入该Track
_video_rtmp_decoder
->
addDelegate
(
_videoTrack
);
addTrack
(
_videoTrack
);
_try_get_video_track
=
true
;
}
else
{
//找不到相应的rtmp解码器,该track无效
_videoTrack
.
reset
();
}
_video_track
=
dynamic_pointer_cast
<
VideoTrack
>
(
Factory
::
getVideoTrackByAmf
(
videoCodec
));
if
(
!
_video_track
)
{
return
;
}
//生成rtmpCodec对象以便解码rtmp
_video_rtmp_decoder
=
Factory
::
getRtmpCodecByTrack
(
_video_track
,
false
);
if
(
!
_video_rtmp_decoder
)
{
//找不到相应的rtmp解码器,该track无效
_video_track
.
reset
();
return
;
}
_video_track
->
setBitRate
(
bit_rate
);
//设置rtmp解码器代理,生成的frame写入该Track
_video_rtmp_decoder
->
addDelegate
(
_video_track
);
addTrack
(
_video_track
);
_try_get_video_track
=
true
;
}
void
RtmpDemuxer
::
makeAudioTrack
(
const
AMFValue
&
audioCodec
,
int
sample_rate
,
int
channels
,
int
sample_bit
,
int
bit_rate
)
{
//生成Track对象
_audioTrack
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
getAudioTrackByAmf
(
audioCodec
,
sample_rate
,
channels
,
sample_bit
));
if
(
_audioTrack
)
{
_audioTrack
->
setBitRate
(
bit_rate
);
//生成rtmpCodec对象以便解码rtmp
_audio_rtmp_decoder
=
Factory
::
getRtmpCodecByTrack
(
_audioTrack
,
false
);
if
(
_audio_rtmp_decoder
)
{
//设置rtmp解码器代理,生成的frame写入该Track
_audio_rtmp_decoder
->
addDelegate
(
_audioTrack
);
addTrack
(
_audioTrack
);
_try_get_audio_track
=
true
;
}
else
{
//找不到相应的rtmp解码器,该track无效
_audioTrack
.
reset
();
}
_audio_track
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
getAudioTrackByAmf
(
audioCodec
,
sample_rate
,
channels
,
sample_bit
));
if
(
!
_audio_track
)
{
return
;
}
//生成rtmpCodec对象以便解码rtmp
_audio_rtmp_decoder
=
Factory
::
getRtmpCodecByTrack
(
_audio_track
,
false
);
if
(
!
_audio_rtmp_decoder
)
{
//找不到相应的rtmp解码器,该track无效
_audio_track
.
reset
();
return
;
}
_audio_track
->
setBitRate
(
bit_rate
);
//设置rtmp解码器代理,生成的frame写入该Track
_audio_rtmp_decoder
->
addDelegate
(
_audio_track
);
addTrack
(
_audio_track
);
_try_get_audio_track
=
true
;
}
}
/* namespace mediakit */
}
/* namespace mediakit */
\ No newline at end of file
src/Rtmp/RtmpDemuxer.h
查看文件 @
fdfde17e
...
...
@@ -23,9 +23,9 @@ using namespace toolkit;
namespace
mediakit
{
class
RtmpDemuxer
:
public
Demuxer
{
class
RtmpDemuxer
:
public
Demuxer
{
public
:
typedef
std
::
shared_ptr
<
RtmpDemuxer
>
Ptr
;
using
Ptr
=
std
::
shared_ptr
<
RtmpDemuxer
>
;
RtmpDemuxer
()
=
default
;
~
RtmpDemuxer
()
override
=
default
;
...
...
@@ -38,6 +38,12 @@ public:
*/
void
inputRtmp
(
const
RtmpPacket
::
Ptr
&
pkt
);
/**
* 获取节目总时长
* @return 节目总时长,单位秒
*/
float
getDuration
()
const
;
private
:
void
makeVideoTrack
(
const
AMFValue
&
val
,
int
bit_rate
);
void
makeAudioTrack
(
const
AMFValue
&
val
,
int
sample_rate
,
int
channels
,
int
sample_bit
,
int
bit_rate
);
...
...
@@ -45,6 +51,9 @@ private:
private
:
bool
_try_get_video_track
=
false
;
bool
_try_get_audio_track
=
false
;
float
_duration
=
0
;
AudioTrack
::
Ptr
_audio_track
;
VideoTrack
::
Ptr
_video_track
;
RtmpCodec
::
Ptr
_audio_rtmp_decoder
;
RtmpCodec
::
Ptr
_video_rtmp_decoder
;
};
...
...
src/Rtmp/RtmpPlayerImp.h
查看文件 @
fdfde17e
...
...
@@ -24,11 +24,12 @@ using namespace mediakit::Client;
namespace
mediakit
{
class
RtmpPlayerImp
:
public
PlayerImp
<
RtmpPlayer
,
RtmpDemuxer
>
{
class
RtmpPlayerImp
:
public
PlayerImp
<
RtmpPlayer
,
PlayerBase
>
,
private
TrackListener
{
public
:
typedef
std
::
shared_ptr
<
RtmpPlayerImp
>
Ptr
;
using
Ptr
=
std
::
shared_ptr
<
RtmpPlayerImp
>
;
using
Super
=
PlayerImp
<
RtmpPlayer
,
PlayerBase
>
;
RtmpPlayerImp
(
const
EventPoller
::
Ptr
&
poller
)
:
PlayerImp
<
RtmpPlayer
,
RtmpDemuxer
>
(
poller
)
{};
RtmpPlayerImp
(
const
EventPoller
::
Ptr
&
poller
)
:
Super
(
poller
)
{};
~
RtmpPlayerImp
()
override
{
DebugL
<<
endl
;
...
...
@@ -50,43 +51,60 @@ public:
uint32_t
pos
=
MAX
(
float
(
0
),
MIN
(
seekPos
,
getDuration
()))
*
1000
;
seekToMilliSecond
(
pos
);
}
void
play
(
const
string
&
strUrl
)
override
{
PlayerImp
<
RtmpPlayer
,
RtmpDemuxer
>::
play
(
strUrl
);
float
getDuration
()
const
override
{
return
_demuxer
?
_demuxer
->
getDuration
()
:
0
;
}
vector
<
Track
::
Ptr
>
getTracks
(
bool
ready
=
true
)
const
override
{
return
_demuxer
?
_demuxer
->
getTracks
(
ready
)
:
Super
::
getTracks
(
ready
);
}
private
:
//派生类回调函数
bool
onCheckMeta
(
const
AMFValue
&
val
)
override
{
_rtmp_src
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
_pMediaSrc
);
if
(
_rtmp_src
)
{
_rtmp_src
->
setMetaData
(
val
);
_set_meta_data
=
true
;
}
_delegate
.
reset
(
new
RtmpDemuxer
);
_delegate
->
loadMetaData
(
val
);
onCheckMeta_l
(
val
);
return
true
;
}
void
onMediaData
(
RtmpPacket
::
Ptr
chunkData
)
override
{
if
(
!
_de
legate
)
{
//
这个流没有
metadata
_delegate
.
reset
(
new
RtmpDemuxer
());
if
(
!
_de
muxer
)
{
//
有些rtmp流没
metadata
onCheckMeta_l
(
TitleMeta
().
getMetadata
());
}
_delegate
->
inputRtmp
(
chunkData
);
_demuxer
->
inputRtmp
(
chunkData
);
if
(
_rtmp_src
)
{
if
(
!
_set_meta_data
&&
!
chunkData
->
isCfgFrame
())
{
_set_meta_data
=
true
;
_rtmp_src
->
setMetaData
(
TitleMeta
().
getMetadata
());
}
_rtmp_src
->
onWrite
(
std
::
move
(
chunkData
));
}
}
void
onPlayResult
(
const
SockException
&
ex
)
override
{
if
(
ex
)
{
Super
::
onPlayResult
(
ex
);
return
;
}
}
bool
addTrack
(
const
Track
::
Ptr
&
track
)
override
{
return
true
;
}
void
addTrackCompleted
()
override
{
Super
::
onPlayResult
(
SockException
(
Err_success
,
"play success"
));
}
private
:
void
onCheckMeta_l
(
const
AMFValue
&
val
)
{
_rtmp_src
=
dynamic_pointer_cast
<
RtmpMediaSource
>
(
_media_src
);
if
(
_rtmp_src
)
{
_rtmp_src
->
setMetaData
(
val
);
}
_demuxer
=
std
::
make_shared
<
RtmpDemuxer
>
();
_demuxer
->
setTrackListener
(
this
);
_demuxer
->
loadMetaData
(
val
);
}
private
:
RtmpDemuxer
::
Ptr
_demuxer
;
RtmpMediaSource
::
Ptr
_rtmp_src
;
bool
_set_meta_data
=
false
;
};
...
...
src/Rtsp/RtspDemuxer.cpp
查看文件 @
fdfde17e
...
...
@@ -18,13 +18,13 @@ using namespace std;
namespace
mediakit
{
void
RtspDemuxer
::
loadSdp
(
const
string
&
sdp
){
void
RtspDemuxer
::
loadSdp
(
const
string
&
sdp
)
{
loadSdp
(
SdpParser
(
sdp
));
}
void
RtspDemuxer
::
loadSdp
(
const
SdpParser
&
attr
)
{
auto
tracks
=
attr
.
getAvailableTrack
();
for
(
auto
&
track
:
tracks
){
for
(
auto
&
track
:
tracks
)
{
switch
(
track
->
_type
)
{
case
TrackVideo
:
{
makeVideoTrack
(
track
);
...
...
@@ -42,31 +42,35 @@ void RtspDemuxer::loadSdp(const SdpParser &attr) {
addTrackCompleted
();
auto
titleTrack
=
attr
.
getTrack
(
TrackTitle
);
if
(
titleTrack
)
{
_
fD
uration
=
titleTrack
->
_duration
;
if
(
titleTrack
)
{
_
d
uration
=
titleTrack
->
_duration
;
}
}
bool
RtspDemuxer
::
inputRtp
(
const
RtpPacket
::
Ptr
&
rtp
)
{
float
RtspDemuxer
::
getDuration
()
const
{
return
_duration
;
}
bool
RtspDemuxer
::
inputRtp
(
const
RtpPacket
::
Ptr
&
rtp
)
{
switch
(
rtp
->
type
)
{
case
TrackVideo
:{
if
(
_videoRtpDecoder
){
return
_videoRtpDecoder
->
inputRtp
(
rtp
,
true
);
case
TrackVideo
:
{
if
(
_videoRtpDecoder
)
{
return
_videoRtpDecoder
->
inputRtp
(
rtp
,
true
);
}
return
false
;
}
return
false
;
}
case
TrackAudio
:{
if
(
_audioRtpDecoder
){
_audioRtpDecoder
->
inputRtp
(
rtp
,
false
);
case
TrackAudio
:
{
if
(
_audioRtpDecoder
)
{
_audioRtpDecoder
->
inputRtp
(
rtp
,
false
);
return
false
;
}
return
false
;
}
return
false
;
}
default
:
return
false
;
default
:
return
false
;
}
}
static
void
setBitRate
(
const
SdpTrack
::
Ptr
&
sdp
,
const
Track
::
Ptr
&
track
){
static
void
setBitRate
(
const
SdpTrack
::
Ptr
&
sdp
,
const
Track
::
Ptr
&
track
)
{
if
(
!
sdp
->
_b
.
empty
())
{
int
data_rate
=
0
;
sscanf
(
sdp
->
_b
.
data
(),
"AS:%d"
,
&
data_rate
);
...
...
@@ -78,38 +82,40 @@ static void setBitRate(const SdpTrack::Ptr &sdp, const Track::Ptr &track){
void
RtspDemuxer
::
makeAudioTrack
(
const
SdpTrack
::
Ptr
&
audio
)
{
//生成Track对象
_audioTrack
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
getTrackBySdp
(
audio
));
if
(
_audioTrack
){
setBitRate
(
audio
,
_audioTrack
);
//生成RtpCodec对象以便解码rtp
_audioRtpDecoder
=
Factory
::
getRtpDecoderByTrack
(
_audioTrack
);
if
(
_audioRtpDecoder
){
//设置rtp解码器代理,生成的frame写入该Track
_audioRtpDecoder
->
addDelegate
(
_audioTrack
);
addTrack
(
_audioTrack
);
}
else
{
//找不到相应的rtp解码器,该track无效
_audioTrack
.
reset
();
}
_audio_track
=
dynamic_pointer_cast
<
AudioTrack
>
(
Factory
::
getTrackBySdp
(
audio
));
if
(
!
_audio_track
)
{
return
;
}
setBitRate
(
audio
,
_audio_track
);
//生成RtpCodec对象以便解码rtp
_audioRtpDecoder
=
Factory
::
getRtpDecoderByTrack
(
_audio_track
);
if
(
!
_audioRtpDecoder
)
{
//找不到相应的rtp解码器,该track无效
_audio_track
.
reset
();
return
;
}
//设置rtp解码器代理,生成的frame写入该Track
_audioRtpDecoder
->
addDelegate
(
_audio_track
);
addTrack
(
_audio_track
);
}
void
RtspDemuxer
::
makeVideoTrack
(
const
SdpTrack
::
Ptr
&
video
)
{
//生成Track对象
_videoTrack
=
dynamic_pointer_cast
<
VideoTrack
>
(
Factory
::
getTrackBySdp
(
video
));
if
(
_videoTrack
){
setBitRate
(
video
,
_videoTrack
);
//生成RtpCodec对象以便解码rtp
_videoRtpDecoder
=
Factory
::
getRtpDecoderByTrack
(
_videoTrack
);
if
(
_videoRtpDecoder
){
//设置rtp解码器代理,生成的frame写入该Track
_videoRtpDecoder
->
addDelegate
(
_videoTrack
);
addTrack
(
_videoTrack
);
}
else
{
//找不到相应的rtp解码器,该track无效
_videoTrack
.
reset
();
}
_video_track
=
dynamic_pointer_cast
<
VideoTrack
>
(
Factory
::
getTrackBySdp
(
video
));
if
(
!
_video_track
)
{
return
;
}
setBitRate
(
video
,
_video_track
);
//生成RtpCodec对象以便解码rtp
_videoRtpDecoder
=
Factory
::
getRtpDecoderByTrack
(
_video_track
);
if
(
!
_videoRtpDecoder
)
{
//找不到相应的rtp解码器,该track无效
_video_track
.
reset
();
return
;
}
//设置rtp解码器代理,生成的frame写入该Track
_videoRtpDecoder
->
addDelegate
(
_video_track
);
addTrack
(
_video_track
);
}
}
/* namespace mediakit */
src/Rtsp/RtspDemuxer.h
查看文件 @
fdfde17e
...
...
@@ -21,7 +21,7 @@ using namespace toolkit;
namespace
mediakit
{
class
RtspDemuxer
:
public
Demuxer
{
class
RtspDemuxer
:
public
Demuxer
{
public
:
typedef
std
::
shared_ptr
<
RtspDemuxer
>
Ptr
;
RtspDemuxer
()
=
default
;
...
...
@@ -38,11 +38,22 @@ public:
* @return true 代表是i帧第一个rtp包
*/
bool
inputRtp
(
const
RtpPacket
::
Ptr
&
rtp
);
/**
* 获取节目总时长
* @return 节目总时长,单位秒
*/
float
getDuration
()
const
;
private
:
void
makeAudioTrack
(
const
SdpTrack
::
Ptr
&
audio
);
void
makeVideoTrack
(
const
SdpTrack
::
Ptr
&
video
);
void
loadSdp
(
const
SdpParser
&
parser
);
private
:
float
_duration
=
0
;
AudioTrack
::
Ptr
_audio_track
;
VideoTrack
::
Ptr
_video_track
;
RtpCodec
::
Ptr
_audioRtpDecoder
;
RtpCodec
::
Ptr
_videoRtpDecoder
;
};
...
...
src/Rtsp/RtspPlayerImp.h
查看文件 @
fdfde17e
...
...
@@ -25,12 +25,14 @@ using namespace toolkit;
namespace
mediakit
{
class
RtspPlayerImp
:
public
PlayerImp
<
RtspPlayer
,
RtspDemuxer
>
{
class
RtspPlayerImp
:
public
PlayerImp
<
RtspPlayer
,
PlayerBase
>
,
private
TrackListener
{
public
:
typedef
std
::
shared_ptr
<
RtspPlayerImp
>
Ptr
;
using
Ptr
=
std
::
shared_ptr
<
RtspPlayerImp
>
;
using
Super
=
PlayerImp
<
RtspPlayer
,
PlayerBase
>
;
RtspPlayerImp
(
const
EventPoller
::
Ptr
&
poller
)
:
PlayerImp
<
RtspPlayer
,
RtspDemuxer
>
(
poller
)
{}
~
RtspPlayerImp
()
override
{
RtspPlayerImp
(
const
EventPoller
::
Ptr
&
poller
)
:
Super
(
poller
)
{}
~
RtspPlayerImp
()
override
{
DebugL
<<
endl
;
}
...
...
@@ -39,7 +41,6 @@ public:
return
getProgressMilliSecond
()
/
(
getDuration
()
*
1000
);
}
return
PlayerBase
::
getProgress
();
}
uint32_t
getProgressPos
()
const
override
{
...
...
@@ -55,29 +56,33 @@ public:
}
void
seekTo
(
uint32_t
seekPos
)
override
{
uint32_t
pos
=
MAX
(
float
(
0
),
MIN
(
seekPos
,
getDuration
()))
*
1000
;
uint32_t
pos
=
MAX
(
float
(
0
),
MIN
(
seekPos
,
getDuration
()))
*
1000
;
seekToMilliSecond
(
pos
);
}
float
getDuration
()
const
override
{
return
_demuxer
?
_demuxer
->
getDuration
()
:
0
;
}
vector
<
Track
::
Ptr
>
getTracks
(
bool
ready
=
true
)
const
override
{
return
_demuxer
?
_demuxer
->
getTracks
(
ready
)
:
Super
::
getTracks
(
ready
);
}
private
:
//派生类回调函数
bool
onCheckSDP
(
const
string
&
sdp
)
override
{
_rtsp_media_src
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
_
pMediaS
rc
);
_rtsp_media_src
=
dynamic_pointer_cast
<
RtspMediaSource
>
(
_
media_s
rc
);
if
(
_rtsp_media_src
)
{
_rtsp_media_src
->
setSdp
(
sdp
);
}
_delegate
.
reset
(
new
RtspDemuxer
);
_delegate
->
loadSdp
(
sdp
);
_demuxer
=
std
::
make_shared
<
RtspDemuxer
>
();
_demuxer
->
setTrackListener
(
this
);
_demuxer
->
loadSdp
(
sdp
);
return
true
;
}
void
onRecvRTP
(
RtpPacket
::
Ptr
rtp
,
const
SdpTrack
::
Ptr
&
track
)
override
{
_delegate
->
inputRtp
(
rtp
);
if
(
_max_analysis_ms
&&
_delegate
->
isInited
(
_max_analysis_ms
))
{
PlayerImp
<
RtspPlayer
,
RtspDemuxer
>::
onPlayResult
(
SockException
(
Err_success
,
"play rtsp success"
));
_max_analysis_ms
=
0
;
}
_demuxer
->
inputRtp
(
rtp
);
if
(
_rtsp_media_src
)
{
// rtsp直接代理是无法判断该rtp是否是I帧,所以GOP缓存基本是无效的
// 为了减少内存使用,那么我们设置为一直关键帧以便清空GOP缓存
...
...
@@ -85,23 +90,21 @@ private:
}
}
//在RtspPlayer中触发onPlayResult事件只是代表收到play回复了,
//并不代表所有track初始化成功了(这跟rtmp播放器不一样)
//如果sdp里面信息不完整,只能尝试延后从rtp中恢复关键信息并初始化track
//如果超过这个时间还未获取成功,那么会强制触发onPlayResult事件(虽然此时有些track还未初始化成功)
void
onPlayResult
(
const
SockException
&
ex
)
override
{
//isInited判断条件:无超时
if
(
ex
||
_delegate
->
isInited
(
0
))
{
//已经初始化成功,说明sdp里面有完善的信息
PlayerImp
<
RtspPlayer
,
RtspDemuxer
>::
onPlayResult
(
ex
);
}
else
{
//还没初始化成功,说明sdp里面信息不完善,还有一些track未初始化成功
_max_analysis_ms
=
(
*
this
)[
Client
::
kMaxAnalysisMS
];
if
(
ex
)
{
Super
::
onPlayResult
(
ex
);
return
;
}
}
bool
addTrack
(
const
Track
::
Ptr
&
track
)
override
{
return
true
;
}
void
addTrackCompleted
()
override
{
Super
::
onPlayResult
(
SockException
(
Err_success
,
"play success"
));
}
private
:
int
_max_analysis_ms
=
0
;
RtspDemuxer
::
Ptr
_demuxer
;
RtspMediaSource
::
Ptr
_rtsp_media_src
;
};
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论