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 个修改的文件
包含
364 行增加
和
393 行删除
+364
-393
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
+113
-163
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
...
...
@@ -22,292 +22,242 @@
#include "Common/MediaSink.h"
#include "Extension/Frame.h"
#include "Extension/Track.h"
using
namespace
toolkit
;
namespace
mediakit
{
class
DemuxerBase
:
public
TrackSource
{
class
PlayerBase
:
public
TrackSource
,
public
mINI
{
public
:
typedef
std
::
shared_ptr
<
DemuxerBase
>
Ptr
;
/**
* 获取节目总时长,单位秒
* @return
*/
virtual
float
getDuration
()
const
{
return
0
;}
/**
* 是否初始化完毕,完毕后方可调用getTrack方法
* @param analysisMs 数据流最大分析时间 单位毫秒
* @return
*/
virtual
bool
isInited
(
int
analysisMs
)
{
return
true
;
}
};
using
Ptr
=
std
::
shared_ptr
<
PlayerBase
>
;
using
Event
=
std
::
function
<
void
(
const
SockException
&
ex
)
>
;
class
PlayerBase
:
public
DemuxerBase
,
public
mINI
{
public
:
typedef
std
::
shared_ptr
<
PlayerBase
>
Ptr
;
static
Ptr
createPlayer
(
const
EventPoller
::
Ptr
&
poller
,
const
string
&
strUrl
);
static
Ptr
createPlayer
(
const
EventPoller
::
Ptr
&
poller
,
const
string
&
strUrl
);
PlayerBase
();
virtual
~
PlayerBase
(){}
~
PlayerBase
()
override
=
default
;
/**
* 开始播放
* @param
strU
rl 视频url,支持rtsp/rtmp
* @param
u
rl 视频url,支持rtsp/rtmp
*/
virtual
void
play
(
const
string
&
strUrl
)
{}
virtual
void
play
(
const
string
&
url
)
{};
/**
* 暂停或恢复
* @param bPause
* @param flag true:暂停,false:恢复
*/
virtual
void
pause
(
bool
flag
)
{};
/**
* 获取节目总时长,单位秒
*/
virtual
void
pause
(
bool
bPause
)
{}
virtual
float
getDuration
()
const
{
return
0
;
};
/**
* 倍数播放
* @param speed 1.0 2.0 0.5
*/
virtual
void
speed
(
float
speed
)
{}
virtual
void
speed
(
float
speed
)
{}
;
/**
* 中断播放
*/
virtual
void
teardown
()
{}
virtual
void
teardown
()
{}
;
/**
* 设置异常中断回调
* @param cb
* 获取播放进度,取值 0.0 ~ 1.0
*/
virtual
void
setOnShutdown
(
const
function
<
void
(
const
SockException
&
)
>
&
cb
)
{}
virtual
float
getProgress
()
const
{
return
0
;
};
/**
* 设置播放结果回调
* @param cb
* 获取播放进度pos,取值 相对开始时间增量 单位秒
*/
virtual
void
setOnPlayResult
(
const
function
<
void
(
const
SockException
&
ex
)
>
&
cb
)
{}
virtual
uint32_t
getProgressPos
()
const
{
return
0
;
};
/**
*
设置播放恢复回调
* @param
cb
*
拖动进度条
* @param
progress 进度,取值 0.0 ~ 1.0
*/
virtual
void
se
tOnResume
(
const
function
<
void
()
>
&
cb
)
{}
virtual
void
se
ekTo
(
float
progress
)
{};
/**
*
获取播放进度,取值 0.0 ~ 1.0
* @
return
*
拖动进度条
* @
param pos 进度,取值 相对于开始时间的增量 单位秒
*/
virtual
float
getProgress
()
const
{
return
0
;}
virtual
void
seekTo
(
uint32_t
pos
)
{};
/**
* 获取
播放进度pos,取值 相对开始时间增量 单位秒
* @
return
* 获取
丢包率,只支持rtsp
* @
param type 音频或视频,TrackInvalid时为总丢包率
*/
virtual
uint32_t
getProgressPos
()
const
{
return
0
;
}
virtual
float
getPacketLossRate
(
TrackType
type
)
const
{
return
0
;
};
/**
* 拖动进度条
* @param fProgress 进度,取值 0.0 ~ 1.0
* 获取所有track
*/
v
irtual
void
seekTo
(
float
fProgress
)
{}
v
ector
<
Track
::
Ptr
>
getTracks
(
bool
ready
=
true
)
const
override
{
return
vector
<
Track
::
Ptr
>
();
};
/**
* 拖动进度条
* @param seekPos 进度,取值 相对于开始时间的增量 单位秒
* 设置一个MediaSource,直接生产rtsp/rtmp代理
*/
virtual
void
se
ekTo
(
uint32_t
seekPos
)
{}
virtual
void
se
tMediaSource
(
const
MediaSource
::
Ptr
&
src
)
=
0
;
/**
* 设置一个MediaSource,直接生产rtsp/rtmp代理
* @param src
* 设置异常中断回调
*/
virtual
void
set
MediaSource
(
const
MediaSource
::
Ptr
&
src
)
{}
virtual
void
set
OnShutdown
(
const
Event
&
cb
)
=
0
;
/**
* 获取丢包率,只支持rtsp
* @param trackType 音频或视频,TrackInvalid时为总丢包率
* @return
* 设置播放结果回调
*/
virtual
float
getPacketLossRate
(
TrackType
trackType
)
const
{
return
0
;
}
virtual
void
setOnPlayResult
(
const
Event
&
cb
)
=
0
;
/**
*
获取所有track
*
设置播放恢复回调
*/
vector
<
Track
::
Ptr
>
getTracks
(
bool
trackReady
=
true
)
const
override
{
return
vector
<
Track
::
Ptr
>
();
}
virtual
void
setOnResume
(
const
function
<
void
()
>
&
cb
)
=
0
;
protected
:
virtual
void
onShutdown
(
const
SockException
&
ex
)
{}
virtual
void
onPlayResult
(
const
SockException
&
ex
)
{}
/**
* 暂停后恢复播放时间
*/
virtual
void
onResume
(){};
virtual
void
onResume
()
=
0
;
virtual
void
onShutdown
(
const
SockException
&
ex
)
=
0
;
virtual
void
onPlayResult
(
const
SockException
&
ex
)
=
0
;
};
template
<
typename
Parent
,
typename
Delegate
>
template
<
typename
Parent
,
typename
Delegate
>
class
PlayerImp
:
public
Parent
{
public
:
typedef
std
::
shared_ptr
<
PlayerImp
>
Ptr
;
using
Ptr
=
std
::
shared_ptr
<
PlayerImp
>
;
template
<
typename
...
ArgsType
>
PlayerImp
(
ArgsType
&&
...
args
)
:
Parent
(
std
::
forward
<
ArgsType
>
(
args
)...)
{}
virtual
~
PlayerImp
()
{}
PlayerImp
(
ArgsType
&&
...
args
)
:
Parent
(
std
::
forward
<
ArgsType
>
(
args
)...)
{}
~
PlayerImp
()
override
=
default
;
void
setOnShutdown
(
const
function
<
void
(
const
SockException
&
)
>
&
cb
)
override
{
if
(
_delegate
)
{
_delegate
->
setOnShutdown
(
cb
);
}
_shutdownCB
=
cb
;
void
play
(
const
string
&
url
)
override
{
return
_delegate
?
_delegate
->
play
(
url
)
:
Parent
::
play
(
url
);
}
void
setOnPlayResult
(
const
function
<
void
(
const
SockException
&
ex
)
>
&
cb
)
override
{
if
(
_delegate
)
{
_delegate
->
setOnPlayResult
(
cb
);
}
_playResultCB
=
cb
;
void
pause
(
bool
flag
)
override
{
return
_delegate
?
_delegate
->
pause
(
flag
)
:
Parent
::
pause
(
flag
);
}
void
setOnResume
(
const
function
<
void
()
>
&
cb
)
override
{
if
(
_delegate
)
{
_delegate
->
setOnResume
(
cb
);
}
_resumeCB
=
cb
;
void
speed
(
float
speed
)
override
{
return
_delegate
?
_delegate
->
speed
(
speed
)
:
Parent
::
speed
(
speed
);
}
bool
isInited
(
int
analysisMs
)
override
{
if
(
_delegate
)
{
return
_delegate
->
isInited
(
analysisMs
);
}
return
Parent
::
isInited
(
analysisMs
);
void
teardown
()
override
{
return
_delegate
?
_delegate
->
teardown
()
:
Parent
::
teardown
();
}
float
getPacketLossRate
(
TrackType
type
)
const
override
{
return
_delegate
?
_delegate
->
getPacketLossRate
(
type
)
:
Parent
::
getPacketLossRate
(
type
);
}
float
getDuration
()
const
override
{
if
(
_delegate
)
{
return
_delegate
->
getDuration
();
}
return
Parent
::
getDuration
();
return
_delegate
?
_delegate
->
getDuration
()
:
Parent
::
getDuration
();
}
float
getProgress
()
const
override
{
if
(
_delegate
)
{
return
_delegate
->
getProgress
();
}
return
Parent
::
getProgress
();
return
_delegate
?
_delegate
->
getProgress
()
:
Parent
::
getProgress
();
}
uint32_t
getProgressPos
()
const
override
{
if
(
_delegate
)
{
return
_delegate
->
getProgressPos
();
}
return
Parent
::
getProgressPos
();
return
_delegate
?
_delegate
->
getProgressPos
()
:
Parent
::
getProgressPos
();
}
void
seekTo
(
float
fProgress
)
override
{
if
(
_delegate
)
{
return
_delegate
->
seekTo
(
fProgress
);
}
return
Parent
::
seekTo
(
fProgress
);
void
seekTo
(
float
progress
)
override
{
return
_delegate
?
_delegate
->
seekTo
(
progress
)
:
Parent
::
seekTo
(
progress
);
}
void
seekTo
(
uint32_t
seekPos
)
override
{
if
(
_delegate
)
{
return
_delegate
->
seekTo
(
seekPos
);
}
return
Parent
::
seekTo
(
seekPos
);
void
seekTo
(
uint32_t
pos
)
override
{
return
_delegate
?
_delegate
->
seekTo
(
pos
)
:
Parent
::
seekTo
(
pos
);
}
vector
<
Track
::
Ptr
>
getTracks
(
bool
ready
=
true
)
const
override
{
return
_delegate
?
_delegate
->
getTracks
(
ready
)
:
Parent
::
getTracks
(
ready
);
}
std
::
shared_ptr
<
SockInfo
>
getSockInfo
()
const
{
return
dynamic_pointer_cast
<
SockInfo
>
(
_delegate
);
}
void
setMediaSource
(
const
MediaSource
::
Ptr
&
src
)
override
{
if
(
_delegate
)
{
_delegate
->
setMediaSource
(
src
);
}
_pMediaSrc
=
src
;
_media_src
=
src
;
}
void
setOnShutdown
(
const
function
<
void
(
const
SockException
&
)
>
&
cb
)
override
{
if
(
_delegate
)
{
_delegate
->
setOnShutdown
(
cb
);
}
_on_shutdown
=
cb
;
}
v
ector
<
Track
::
Ptr
>
getTracks
(
bool
trackReady
=
true
)
const
override
{
v
oid
setOnPlayResult
(
const
function
<
void
(
const
SockException
&
ex
)
>
&
cb
)
override
{
if
(
_delegate
)
{
return
_delegate
->
getTracks
(
trackReady
);
_delegate
->
setOnPlayResult
(
cb
);
}
return
Parent
::
getTracks
(
trackReady
)
;
_on_play_result
=
cb
;
}
std
::
shared_ptr
<
SockInfo
>
getSockInfo
()
const
{
return
dynamic_pointer_cast
<
SockInfo
>
(
_delegate
);
void
setOnResume
(
const
function
<
void
()
>
&
cb
)
override
{
if
(
_delegate
)
{
_delegate
->
setOnResume
(
cb
);
}
_on_resume
=
cb
;
}
protected
:
void
onShutdown
(
const
SockException
&
ex
)
override
{
if
(
_
shutdownCB
)
{
_
shutdownCB
(
ex
);
_
shutdownCB
=
nullptr
;
if
(
_
on_shutdown
)
{
_
on_shutdown
(
ex
);
_
on_shutdown
=
nullptr
;
}
}
void
onPlayResult
(
const
SockException
&
ex
)
override
{
if
(
_playResultCB
)
{
_
playResultCB
(
ex
);
_
playResultCB
=
nullptr
;
if
(
_on_play_result
)
{
_
on_play_result
(
ex
);
_
on_play_result
=
nullptr
;
}
}
void
onResume
()
override
{
if
(
_resumeCB
)
{
_
resumeCB
();
void
onResume
()
override
{
if
(
_on_resume
)
{
_
on_resume
();
}
}
protected
:
function
<
void
(
const
SockException
&
ex
)
>
_shutdownCB
;
function
<
void
(
const
SockException
&
ex
)
>
_playResultCB
;
function
<
void
()
>
_resumeCB
;
function
<
void
()
>
_on_resume
;
PlayerBase
::
Event
_on_shutdown
;
PlayerBase
::
Event
_on_play_result
;
MediaSource
::
Ptr
_media_src
;
std
::
shared_ptr
<
Delegate
>
_delegate
;
MediaSource
::
Ptr
_pMediaSrc
;
};
class
Demuxer
:
p
ublic
PlayerBase
,
public
TrackListener
{
class
Demuxer
:
p
rotected
MediaSink
{
public
:
Demuxer
()
=
default
;
~
Demuxer
()
override
=
default
;
/**
* 返回是否完成初始化完毕
* 在构造RtspDemuxer对象时有些rtsp的sdp不包含sps pps信息
* 所以要等待接收到到sps的rtp包后才能完成
*
* 在构造RtmpDemuxer对象时是无法获取sps pps aac_cfg等这些信息,
* 所以要调用inputRtmp后才会获取到这些信息,这时才初始化成功
* @param analysisMs 数据流最大分析时间 单位毫秒
* @return
*/
bool
isInited
(
int
analysisMs
)
override
;
/**
* 获取所有Track
* @return 所有Track
*/
vector
<
Track
::
Ptr
>
getTracks
(
bool
trackReady
=
true
)
const
override
;
/**
* 获取节目总时长
* @return 节目总时长,单位秒
*/
float
getDuration
()
const
override
;
/**
* 设置track监听器
*/
void
setTrackListener
(
TrackListener
*
listener
);
vector
<
Track
::
Ptr
>
getTracks
(
bool
ready
=
true
)
const
override
;
protected
:
bool
addTrack
(
const
Track
::
Ptr
&
track
)
override
;
void
addTrackCompleted
()
override
;
bool
addTrack
(
const
Track
::
Ptr
&
track
)
override
;
void
resetTracks
()
override
;
bool
onTrackReady
(
const
Track
::
Ptr
&
track
)
override
;
void
onAllTrackReady
()
override
;
bool
onTrackFrame
(
const
Frame
::
Ptr
&
frame
)
override
;
protected
:
float
_fDuration
=
0
;
Ticker
_ticker
;
AudioTrack
::
Ptr
_audioTrack
;
VideoTrack
::
Ptr
_videoTrack
;
private
:
Track
::
Ptr
_tracks
[
TrackMax
];
TrackListener
*
_listener
=
nullptr
;
};
...
...
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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论