mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-03 17:27:33 +08:00
tab统一替换为4个空格键:#242
This commit is contained in:
@@ -42,29 +42,29 @@ MediaPlayer::MediaPlayer(const EventPoller::Ptr &poller) {
|
||||
MediaPlayer::~MediaPlayer() {
|
||||
}
|
||||
void MediaPlayer::play(const string &strUrl) {
|
||||
_delegate = PlayerBase::createPlayer(_poller,strUrl);
|
||||
_delegate->setOnShutdown(_shutdownCB);
|
||||
_delegate->setOnPlayResult(_playResultCB);
|
||||
_delegate = PlayerBase::createPlayer(_poller,strUrl);
|
||||
_delegate->setOnShutdown(_shutdownCB);
|
||||
_delegate->setOnPlayResult(_playResultCB);
|
||||
_delegate->setOnResume(_resumeCB);
|
||||
_delegate->setMediaSouce(_pMediaSrc);
|
||||
_delegate->mINI::operator=(*this);
|
||||
_delegate->play(strUrl);
|
||||
_delegate->mINI::operator=(*this);
|
||||
_delegate->play(strUrl);
|
||||
}
|
||||
|
||||
EventPoller::Ptr MediaPlayer::getPoller(){
|
||||
return _poller;
|
||||
return _poller;
|
||||
}
|
||||
|
||||
void MediaPlayer::pause(bool bPause) {
|
||||
if (_delegate) {
|
||||
_delegate->pause(bPause);
|
||||
}
|
||||
if (_delegate) {
|
||||
_delegate->pause(bPause);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaPlayer::teardown() {
|
||||
if (_delegate) {
|
||||
_delegate->teardown();
|
||||
}
|
||||
if (_delegate) {
|
||||
_delegate->teardown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,16 +39,16 @@ namespace mediakit {
|
||||
|
||||
class MediaPlayer : public PlayerImp<PlayerBase,PlayerBase> {
|
||||
public:
|
||||
typedef std::shared_ptr<MediaPlayer> Ptr;
|
||||
typedef std::shared_ptr<MediaPlayer> Ptr;
|
||||
|
||||
MediaPlayer(const EventPoller::Ptr &poller = nullptr);
|
||||
virtual ~MediaPlayer();
|
||||
void play(const string &strUrl) override;
|
||||
void pause(bool bPause) override;
|
||||
void teardown() override;
|
||||
EventPoller::Ptr getPoller();
|
||||
MediaPlayer(const EventPoller::Ptr &poller = nullptr);
|
||||
virtual ~MediaPlayer();
|
||||
void play(const string &strUrl) override;
|
||||
void pause(bool bPause) override;
|
||||
void teardown() override;
|
||||
EventPoller::Ptr getPoller();
|
||||
private:
|
||||
EventPoller::Ptr _poller;
|
||||
EventPoller::Ptr _poller;
|
||||
};
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
||||
@@ -33,92 +33,92 @@ using namespace toolkit;
|
||||
namespace mediakit {
|
||||
|
||||
PlayerBase::Ptr PlayerBase::createPlayer(const EventPoller::Ptr &poller,const string &strUrl) {
|
||||
static auto releasePlayer = [](PlayerBase *ptr){
|
||||
onceToken token(nullptr,[&](){
|
||||
delete ptr;
|
||||
});
|
||||
ptr->teardown();
|
||||
};
|
||||
string prefix = FindField(strUrl.data(), NULL, "://");
|
||||
static auto releasePlayer = [](PlayerBase *ptr){
|
||||
onceToken token(nullptr,[&](){
|
||||
delete ptr;
|
||||
});
|
||||
ptr->teardown();
|
||||
};
|
||||
string prefix = FindField(strUrl.data(), NULL, "://");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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() > analysisMs){
|
||||
//analysisMs毫秒后强制初始化完毕
|
||||
return true;
|
||||
}
|
||||
if (_videoTrack && !_videoTrack->ready()) {
|
||||
//视频未准备好
|
||||
return false;
|
||||
}
|
||||
if (_audioTrack && !_audioTrack->ready()) {
|
||||
//音频未准备好
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if(analysisMs && _ticker.createdTime() > 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);
|
||||
}
|
||||
}
|
||||
return std::move(ret);
|
||||
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);
|
||||
}
|
||||
}
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
float Demuxer::getDuration() const {
|
||||
return _fDuration;
|
||||
return _fDuration;
|
||||
}
|
||||
|
||||
void Demuxer::onAddTrack(const Track::Ptr &track){
|
||||
if(_listener){
|
||||
_listener->onAddTrack(track);
|
||||
}
|
||||
if(_listener){
|
||||
_listener->onAddTrack(track);
|
||||
}
|
||||
}
|
||||
|
||||
void Demuxer::setTrackListener(Demuxer::Listener *listener) {
|
||||
_listener = listener;
|
||||
_listener = listener;
|
||||
}
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
||||
@@ -43,59 +43,59 @@ namespace mediakit {
|
||||
|
||||
class DemuxerBase : public TrackSource{
|
||||
public:
|
||||
typedef std::shared_ptr<DemuxerBase> Ptr;
|
||||
typedef std::shared_ptr<DemuxerBase> Ptr;
|
||||
|
||||
/**
|
||||
* 获取节目总时长,单位秒
|
||||
* @return
|
||||
*/
|
||||
virtual float getDuration() const { return 0;}
|
||||
/**
|
||||
* 获取节目总时长,单位秒
|
||||
* @return
|
||||
*/
|
||||
virtual float getDuration() const { return 0;}
|
||||
|
||||
/**
|
||||
* 是否初始化完毕,完毕后方可调用getTrack方法
|
||||
* @param analysisMs 数据流最大分析时间 单位毫秒
|
||||
* @return
|
||||
*/
|
||||
virtual bool isInited(int analysisMs) { return true; }
|
||||
/**
|
||||
* 是否初始化完毕,完毕后方可调用getTrack方法
|
||||
* @param analysisMs 数据流最大分析时间 单位毫秒
|
||||
* @return
|
||||
*/
|
||||
virtual bool isInited(int analysisMs) { return true; }
|
||||
};
|
||||
|
||||
|
||||
class PlayerBase : public DemuxerBase, public mINI{
|
||||
public:
|
||||
typedef std::shared_ptr<PlayerBase> Ptr;
|
||||
typedef std::shared_ptr<PlayerBase> Ptr;
|
||||
static Ptr createPlayer(const EventPoller::Ptr &poller,const string &strUrl);
|
||||
|
||||
PlayerBase();
|
||||
virtual ~PlayerBase(){}
|
||||
PlayerBase();
|
||||
virtual ~PlayerBase(){}
|
||||
|
||||
/**
|
||||
* 开始播放
|
||||
* @param strUrl 视频url,支持rtsp/rtmp
|
||||
*/
|
||||
virtual void play(const string &strUrl) {}
|
||||
/**
|
||||
* 开始播放
|
||||
* @param strUrl 视频url,支持rtsp/rtmp
|
||||
*/
|
||||
virtual void play(const string &strUrl) {}
|
||||
|
||||
/**
|
||||
* 暂停或恢复
|
||||
* @param bPause
|
||||
*/
|
||||
virtual void pause(bool bPause) {}
|
||||
/**
|
||||
* 暂停或恢复
|
||||
* @param bPause
|
||||
*/
|
||||
virtual void pause(bool bPause) {}
|
||||
|
||||
/**
|
||||
* 中断播放
|
||||
*/
|
||||
virtual void teardown() {}
|
||||
/**
|
||||
* 中断播放
|
||||
*/
|
||||
virtual void teardown() {}
|
||||
|
||||
/**
|
||||
* 设置异常中断回调
|
||||
* @param cb
|
||||
*/
|
||||
virtual void setOnShutdown( const function<void(const SockException &)> &cb) {}
|
||||
/**
|
||||
* 设置异常中断回调
|
||||
* @param cb
|
||||
*/
|
||||
virtual void setOnShutdown( const function<void(const SockException &)> &cb) {}
|
||||
|
||||
/**
|
||||
* 设置播放结果回调
|
||||
* @param cb
|
||||
*/
|
||||
virtual void setOnPlayResult( const function<void(const SockException &ex)> &cb) {}
|
||||
/**
|
||||
* 设置播放结果回调
|
||||
* @param cb
|
||||
*/
|
||||
virtual void setOnPlayResult( const function<void(const SockException &ex)> &cb) {}
|
||||
|
||||
/**
|
||||
* 设置播放恢复回调
|
||||
@@ -103,10 +103,10 @@ public:
|
||||
*/
|
||||
virtual void setOnResume( const function<void()> &cb) {}
|
||||
|
||||
/**
|
||||
* 获取播放进度,取值 0.0 ~ 1.0
|
||||
* @return
|
||||
*/
|
||||
/**
|
||||
* 获取播放进度,取值 0.0 ~ 1.0
|
||||
* @return
|
||||
*/
|
||||
virtual float getProgress() const { return 0;}
|
||||
|
||||
/**
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
* @param trackType 音频或视频,TrackInvalid时为总丢包率
|
||||
* @return
|
||||
*/
|
||||
virtual float getPacketLossRate(TrackType trackType) const {return 0; }
|
||||
virtual float getPacketLossRate(TrackType trackType) const {return 0; }
|
||||
|
||||
/**
|
||||
* 获取所有track
|
||||
@@ -146,24 +146,24 @@ protected:
|
||||
template<typename Parent,typename Delegate>
|
||||
class PlayerImp : public Parent {
|
||||
public:
|
||||
typedef std::shared_ptr<PlayerImp> Ptr;
|
||||
typedef std::shared_ptr<PlayerImp> Ptr;
|
||||
|
||||
template<typename ...ArgsType>
|
||||
PlayerImp(ArgsType &&...args):Parent(std::forward<ArgsType>(args)...){}
|
||||
template<typename ...ArgsType>
|
||||
PlayerImp(ArgsType &&...args):Parent(std::forward<ArgsType>(args)...){}
|
||||
|
||||
virtual ~PlayerImp(){}
|
||||
void setOnShutdown(const function<void(const SockException &)> &cb) override {
|
||||
if (_delegate) {
|
||||
_delegate->setOnShutdown(cb);
|
||||
}
|
||||
_shutdownCB = cb;
|
||||
}
|
||||
void setOnPlayResult(const function<void(const SockException &ex)> &cb) override {
|
||||
if (_delegate) {
|
||||
_delegate->setOnPlayResult(cb);
|
||||
}
|
||||
_playResultCB = cb;
|
||||
}
|
||||
virtual ~PlayerImp(){}
|
||||
void setOnShutdown(const function<void(const SockException &)> &cb) override {
|
||||
if (_delegate) {
|
||||
_delegate->setOnShutdown(cb);
|
||||
}
|
||||
_shutdownCB = cb;
|
||||
}
|
||||
void setOnPlayResult(const function<void(const SockException &ex)> &cb) override {
|
||||
if (_delegate) {
|
||||
_delegate->setOnPlayResult(cb);
|
||||
}
|
||||
_playResultCB = cb;
|
||||
}
|
||||
|
||||
void setOnResume(const function<void()> &cb) override {
|
||||
if (_delegate) {
|
||||
@@ -178,12 +178,12 @@ public:
|
||||
}
|
||||
return Parent::isInited(analysisMs);
|
||||
}
|
||||
float getDuration() const override {
|
||||
if (_delegate) {
|
||||
return _delegate->getDuration();
|
||||
}
|
||||
return Parent::getDuration();
|
||||
}
|
||||
float getDuration() const override {
|
||||
if (_delegate) {
|
||||
return _delegate->getDuration();
|
||||
}
|
||||
return Parent::getDuration();
|
||||
}
|
||||
float getProgress() const override{
|
||||
if (_delegate) {
|
||||
return _delegate->getProgress();
|
||||
@@ -198,95 +198,95 @@ public:
|
||||
}
|
||||
|
||||
void setMediaSouce(const MediaSource::Ptr & src) override {
|
||||
if (_delegate) {
|
||||
_delegate->setMediaSouce(src);
|
||||
}
|
||||
_pMediaSrc = src;
|
||||
if (_delegate) {
|
||||
_delegate->setMediaSouce(src);
|
||||
}
|
||||
_pMediaSrc = src;
|
||||
}
|
||||
|
||||
vector<Track::Ptr> getTracks(bool trackReady = true) const override{
|
||||
if (_delegate) {
|
||||
return _delegate->getTracks(trackReady);
|
||||
}
|
||||
return Parent::getTracks(trackReady);
|
||||
}
|
||||
if (_delegate) {
|
||||
return _delegate->getTracks(trackReady);
|
||||
}
|
||||
return Parent::getTracks(trackReady);
|
||||
}
|
||||
protected:
|
||||
void onShutdown(const SockException &ex) override {
|
||||
if (_shutdownCB) {
|
||||
_shutdownCB(ex);
|
||||
_shutdownCB = nullptr;
|
||||
}
|
||||
}
|
||||
void onShutdown(const SockException &ex) override {
|
||||
if (_shutdownCB) {
|
||||
_shutdownCB(ex);
|
||||
_shutdownCB = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void onPlayResult(const SockException &ex) override {
|
||||
if(_playResultCB) {
|
||||
_playResultCB(ex);
|
||||
_playResultCB = nullptr;
|
||||
}
|
||||
}
|
||||
void onPlayResult(const SockException &ex) override {
|
||||
if(_playResultCB) {
|
||||
_playResultCB(ex);
|
||||
_playResultCB = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void onResume() override{
|
||||
void onResume() override{
|
||||
if(_resumeCB){
|
||||
_resumeCB();
|
||||
}
|
||||
}
|
||||
protected:
|
||||
function<void(const SockException &ex)> _shutdownCB;
|
||||
function<void(const SockException &ex)> _playResultCB;
|
||||
function<void(const SockException &ex)> _shutdownCB;
|
||||
function<void(const SockException &ex)> _playResultCB;
|
||||
function<void()> _resumeCB;
|
||||
std::shared_ptr<Delegate> _delegate;
|
||||
MediaSource::Ptr _pMediaSrc;
|
||||
MediaSource::Ptr _pMediaSrc;
|
||||
};
|
||||
|
||||
|
||||
class Demuxer : public PlayerBase{
|
||||
public:
|
||||
class Listener{
|
||||
public:
|
||||
Listener() = default;
|
||||
virtual ~Listener() = default;
|
||||
virtual void onAddTrack(const Track::Ptr &track) = 0;
|
||||
};
|
||||
class Listener{
|
||||
public:
|
||||
Listener() = default;
|
||||
virtual ~Listener() = default;
|
||||
virtual void onAddTrack(const Track::Ptr &track) = 0;
|
||||
};
|
||||
|
||||
Demuxer(){};
|
||||
virtual ~Demuxer(){};
|
||||
Demuxer(){};
|
||||
virtual ~Demuxer(){};
|
||||
|
||||
/**
|
||||
* 返回是否完成初始化完毕
|
||||
* 在构造RtspDemuxer对象时有些rtsp的sdp不包含sps pps信息
|
||||
* 所以要等待接收到到sps的rtp包后才能完成
|
||||
*
|
||||
* 在构造RtmpDemuxer对象时是无法获取sps pps aac_cfg等这些信息,
|
||||
* 所以要调用inputRtmp后才会获取到这些信息,这时才初始化成功
|
||||
* @param analysisMs 数据流最大分析时间 单位毫秒
|
||||
* @return
|
||||
*/
|
||||
bool isInited(int analysisMs) override;
|
||||
/**
|
||||
* 返回是否完成初始化完毕
|
||||
* 在构造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;
|
||||
/**
|
||||
* 获取所有Track
|
||||
* @return 所有Track
|
||||
*/
|
||||
vector<Track::Ptr> getTracks(bool trackReady = true) const override;
|
||||
|
||||
/**
|
||||
* 获取节目总时长
|
||||
* @return 节目总时长,单位秒
|
||||
*/
|
||||
float getDuration() const override;
|
||||
/**
|
||||
* 获取节目总时长
|
||||
* @return 节目总时长,单位秒
|
||||
*/
|
||||
float getDuration() const override;
|
||||
|
||||
/**
|
||||
* 设置track监听器
|
||||
*/
|
||||
void setTrackListener(Listener *listener);
|
||||
/**
|
||||
* 设置track监听器
|
||||
*/
|
||||
void setTrackListener(Listener *listener);
|
||||
protected:
|
||||
void onAddTrack(const Track::Ptr &track);
|
||||
void onAddTrack(const Track::Ptr &track);
|
||||
protected:
|
||||
Listener *_listener = nullptr;
|
||||
AudioTrack::Ptr _audioTrack;
|
||||
VideoTrack::Ptr _videoTrack;
|
||||
Ticker _ticker;
|
||||
float _fDuration = 0;
|
||||
Listener *_listener = nullptr;
|
||||
AudioTrack::Ptr _audioTrack;
|
||||
VideoTrack::Ptr _videoTrack;
|
||||
Ticker _ticker;
|
||||
float _fDuration = 0;
|
||||
};
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
||||
@@ -65,17 +65,17 @@ static uint8_t s_mute_adts[] = {0xff, 0xf1, 0x6c, 0x40, 0x2d, 0x3f, 0xfc, 0x00,
|
||||
PlayerProxy::PlayerProxy(const string &strVhost,
|
||||
const string &strApp,
|
||||
const string &strSrc,
|
||||
bool bEnableRtsp,
|
||||
bool bEnableRtmp,
|
||||
bool bEnableRtsp,
|
||||
bool bEnableRtmp,
|
||||
bool bEnableHls,
|
||||
bool bEnableMp4,
|
||||
int iRetryCount,
|
||||
const EventPoller::Ptr &poller) : MediaPlayer(poller){
|
||||
_strVhost = strVhost;
|
||||
_strApp = strApp;
|
||||
_strSrc = strSrc;
|
||||
_bEnableRtsp = bEnableRtsp;
|
||||
_bEnableRtmp = bEnableRtmp;
|
||||
const EventPoller::Ptr &poller) : MediaPlayer(poller){
|
||||
_strVhost = strVhost;
|
||||
_strApp = strApp;
|
||||
_strSrc = strSrc;
|
||||
_bEnableRtsp = bEnableRtsp;
|
||||
_bEnableRtmp = bEnableRtmp;
|
||||
_bEnableHls = bEnableHls;
|
||||
_bEnableMp4 = bEnableMp4;
|
||||
_iRetryCount = iRetryCount;
|
||||
@@ -90,88 +90,88 @@ void PlayerProxy::setOnClose(const function<void()> &cb){
|
||||
}
|
||||
|
||||
void PlayerProxy::play(const string &strUrlTmp) {
|
||||
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
||||
std::shared_ptr<int> piFailedCnt(new int(0)); //连续播放失败次数
|
||||
setOnPlayResult([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) {
|
||||
auto strongSelf = weakSelf.lock();
|
||||
if(!strongSelf) {
|
||||
return;
|
||||
}
|
||||
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
||||
std::shared_ptr<int> piFailedCnt(new int(0)); //连续播放失败次数
|
||||
setOnPlayResult([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) {
|
||||
auto strongSelf = weakSelf.lock();
|
||||
if(!strongSelf) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(strongSelf->_playCB) {
|
||||
if(strongSelf->_playCB) {
|
||||
strongSelf->_playCB(err);
|
||||
strongSelf->_playCB = nullptr;
|
||||
}
|
||||
|
||||
if(!err) {
|
||||
// 播放成功
|
||||
*piFailedCnt = 0;//连续播放失败次数清0
|
||||
strongSelf->onPlaySuccess();
|
||||
}else if(*piFailedCnt < strongSelf->_iRetryCount || strongSelf->_iRetryCount < 0) {
|
||||
// 播放失败,延时重试播放
|
||||
strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++);
|
||||
}
|
||||
});
|
||||
setOnShutdown([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) {
|
||||
auto strongSelf = weakSelf.lock();
|
||||
if(!strongSelf) {
|
||||
return;
|
||||
}
|
||||
if(strongSelf->_mediaMuxer) {
|
||||
auto tracks = strongSelf->getTracks(false);
|
||||
for (auto & track : tracks){
|
||||
track->delDelegate(strongSelf->_mediaMuxer.get());
|
||||
}
|
||||
if(!err) {
|
||||
// 播放成功
|
||||
*piFailedCnt = 0;//连续播放失败次数清0
|
||||
strongSelf->onPlaySuccess();
|
||||
}else if(*piFailedCnt < strongSelf->_iRetryCount || strongSelf->_iRetryCount < 0) {
|
||||
// 播放失败,延时重试播放
|
||||
strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++);
|
||||
}
|
||||
});
|
||||
setOnShutdown([weakSelf,strUrlTmp,piFailedCnt](const SockException &err) {
|
||||
auto strongSelf = weakSelf.lock();
|
||||
if(!strongSelf) {
|
||||
return;
|
||||
}
|
||||
if(strongSelf->_mediaMuxer) {
|
||||
auto tracks = strongSelf->getTracks(false);
|
||||
for (auto & track : tracks){
|
||||
track->delDelegate(strongSelf->_mediaMuxer.get());
|
||||
}
|
||||
|
||||
GET_CONFIG(bool,resetWhenRePlay,General::kResetWhenRePlay);
|
||||
if (resetWhenRePlay) {
|
||||
strongSelf->_mediaMuxer.reset();
|
||||
} else {
|
||||
strongSelf->_mediaMuxer->resetTracks();
|
||||
}
|
||||
}
|
||||
//播放异常中断,延时重试播放
|
||||
if(*piFailedCnt < strongSelf->_iRetryCount || strongSelf->_iRetryCount < 0) {
|
||||
strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++);
|
||||
}
|
||||
});
|
||||
MediaPlayer::play(strUrlTmp);
|
||||
GET_CONFIG(bool,resetWhenRePlay,General::kResetWhenRePlay);
|
||||
if (resetWhenRePlay) {
|
||||
strongSelf->_mediaMuxer.reset();
|
||||
} else {
|
||||
strongSelf->_mediaMuxer->resetTracks();
|
||||
}
|
||||
}
|
||||
//播放异常中断,延时重试播放
|
||||
if(*piFailedCnt < strongSelf->_iRetryCount || strongSelf->_iRetryCount < 0) {
|
||||
strongSelf->rePlay(strUrlTmp,(*piFailedCnt)++);
|
||||
}
|
||||
});
|
||||
MediaPlayer::play(strUrlTmp);
|
||||
|
||||
MediaSource::Ptr mediaSource;
|
||||
if(dynamic_pointer_cast<RtspPlayer>(_delegate)){
|
||||
//rtsp拉流
|
||||
GET_CONFIG(bool,directProxy,Rtsp::kDirectProxy);
|
||||
if(directProxy && _bEnableRtsp){
|
||||
mediaSource = std::make_shared<RtspMediaSource>(_strVhost,_strApp,_strSrc);
|
||||
}
|
||||
} else if(dynamic_pointer_cast<RtmpPlayer>(_delegate)){
|
||||
//rtmp拉流
|
||||
if(_bEnableRtmp){
|
||||
mediaSource = std::make_shared<RtmpMediaSource>(_strVhost,_strApp,_strSrc);
|
||||
}
|
||||
}
|
||||
if(mediaSource){
|
||||
setMediaSouce(mediaSource);
|
||||
mediaSource->setListener(shared_from_this());
|
||||
}
|
||||
MediaSource::Ptr mediaSource;
|
||||
if(dynamic_pointer_cast<RtspPlayer>(_delegate)){
|
||||
//rtsp拉流
|
||||
GET_CONFIG(bool,directProxy,Rtsp::kDirectProxy);
|
||||
if(directProxy && _bEnableRtsp){
|
||||
mediaSource = std::make_shared<RtspMediaSource>(_strVhost,_strApp,_strSrc);
|
||||
}
|
||||
} else if(dynamic_pointer_cast<RtmpPlayer>(_delegate)){
|
||||
//rtmp拉流
|
||||
if(_bEnableRtmp){
|
||||
mediaSource = std::make_shared<RtmpMediaSource>(_strVhost,_strApp,_strSrc);
|
||||
}
|
||||
}
|
||||
if(mediaSource){
|
||||
setMediaSouce(mediaSource);
|
||||
mediaSource->setListener(shared_from_this());
|
||||
}
|
||||
}
|
||||
|
||||
PlayerProxy::~PlayerProxy() {
|
||||
_timer.reset();
|
||||
_timer.reset();
|
||||
}
|
||||
void PlayerProxy::rePlay(const string &strUrl,int iFailedCnt){
|
||||
auto iDelay = MAX(2 * 1000, MIN(iFailedCnt * 3000, 60*1000));
|
||||
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
||||
_timer = std::make_shared<Timer>(iDelay / 1000.0f,[weakSelf,strUrl,iFailedCnt]() {
|
||||
//播放失败次数越多,则延时越长
|
||||
auto strongPlayer = weakSelf.lock();
|
||||
if(!strongPlayer) {
|
||||
return false;
|
||||
}
|
||||
WarnL << "重试播放[" << iFailedCnt << "]:" << strUrl;
|
||||
strongPlayer->MediaPlayer::play(strUrl);
|
||||
return false;
|
||||
}, getPoller());
|
||||
auto iDelay = MAX(2 * 1000, MIN(iFailedCnt * 3000, 60*1000));
|
||||
weak_ptr<PlayerProxy> weakSelf = shared_from_this();
|
||||
_timer = std::make_shared<Timer>(iDelay / 1000.0f,[weakSelf,strUrl,iFailedCnt]() {
|
||||
//播放失败次数越多,则延时越长
|
||||
auto strongPlayer = weakSelf.lock();
|
||||
if(!strongPlayer) {
|
||||
return false;
|
||||
}
|
||||
WarnL << "重试播放[" << iFailedCnt << "]:" << strUrl;
|
||||
strongPlayer->MediaPlayer::play(strUrl);
|
||||
return false;
|
||||
}, getPoller());
|
||||
}
|
||||
|
||||
bool PlayerProxy::close(MediaSource &sender,bool force) {
|
||||
@@ -179,19 +179,19 @@ bool PlayerProxy::close(MediaSource &sender,bool force) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//通知其停止推流
|
||||
weak_ptr<PlayerProxy> weakSlef = dynamic_pointer_cast<PlayerProxy>(shared_from_this());
|
||||
getPoller()->async_first([weakSlef]() {
|
||||
auto stronSelf = weakSlef.lock();
|
||||
if (stronSelf) {
|
||||
stronSelf->_mediaMuxer.reset();
|
||||
stronSelf->setMediaSouce(nullptr);
|
||||
stronSelf->teardown();
|
||||
if(stronSelf->_onClose){
|
||||
//通知其停止推流
|
||||
weak_ptr<PlayerProxy> weakSlef = dynamic_pointer_cast<PlayerProxy>(shared_from_this());
|
||||
getPoller()->async_first([weakSlef]() {
|
||||
auto stronSelf = weakSlef.lock();
|
||||
if (stronSelf) {
|
||||
stronSelf->_mediaMuxer.reset();
|
||||
stronSelf->setMediaSouce(nullptr);
|
||||
stronSelf->teardown();
|
||||
if(stronSelf->_onClose){
|
||||
stronSelf->_onClose();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
WarnL << sender.getSchema() << "/" << sender.getVhost() << "/" << sender.getApp() << "/" << sender.getId() << " " << force;
|
||||
return true;
|
||||
}
|
||||
@@ -208,90 +208,90 @@ int PlayerProxy::totalReaderCount(){
|
||||
}
|
||||
|
||||
int PlayerProxy::totalReaderCount(MediaSource &sender) {
|
||||
return totalReaderCount();
|
||||
return totalReaderCount();
|
||||
}
|
||||
|
||||
class MuteAudioMaker : public FrameDispatcher{
|
||||
public:
|
||||
typedef std::shared_ptr<MuteAudioMaker> Ptr;
|
||||
typedef std::shared_ptr<MuteAudioMaker> Ptr;
|
||||
|
||||
MuteAudioMaker(){};
|
||||
virtual ~MuteAudioMaker(){}
|
||||
void inputFrame(const Frame::Ptr &frame) override {
|
||||
if(frame->getTrackType() == TrackVideo){
|
||||
auto iAudioIndex = frame->dts() / MUTE_ADTS_DATA_MS;
|
||||
if(_iAudioIndex != iAudioIndex){
|
||||
_iAudioIndex = iAudioIndex;
|
||||
auto aacFrame = std::make_shared<AACFrameCacheAble>((char *)MUTE_ADTS_DATA, MUTE_ADTS_DATA_LEN, _iAudioIndex * MUTE_ADTS_DATA_MS);
|
||||
FrameDispatcher::inputFrame(aacFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
MuteAudioMaker(){};
|
||||
virtual ~MuteAudioMaker(){}
|
||||
void inputFrame(const Frame::Ptr &frame) override {
|
||||
if(frame->getTrackType() == TrackVideo){
|
||||
auto iAudioIndex = frame->dts() / MUTE_ADTS_DATA_MS;
|
||||
if(_iAudioIndex != iAudioIndex){
|
||||
_iAudioIndex = iAudioIndex;
|
||||
auto aacFrame = std::make_shared<AACFrameCacheAble>((char *)MUTE_ADTS_DATA, MUTE_ADTS_DATA_LEN, _iAudioIndex * MUTE_ADTS_DATA_MS);
|
||||
FrameDispatcher::inputFrame(aacFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
class AACFrameCacheAble : public AACFrameNoCacheAble{
|
||||
public:
|
||||
template <typename ... ARGS>
|
||||
AACFrameCacheAble(ARGS && ...args) : AACFrameNoCacheAble(std::forward<ARGS>(args)...){};
|
||||
virtual ~AACFrameCacheAble() = default;
|
||||
class AACFrameCacheAble : public AACFrameNoCacheAble{
|
||||
public:
|
||||
template <typename ... ARGS>
|
||||
AACFrameCacheAble(ARGS && ...args) : AACFrameNoCacheAble(std::forward<ARGS>(args)...){};
|
||||
virtual ~AACFrameCacheAble() = default;
|
||||
|
||||
bool cacheAble() const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
bool cacheAble() const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
private:
|
||||
int _iAudioIndex = 0;
|
||||
int _iAudioIndex = 0;
|
||||
};
|
||||
|
||||
void PlayerProxy::onPlaySuccess() {
|
||||
GET_CONFIG(bool,resetWhenRePlay,General::kResetWhenRePlay);
|
||||
if (dynamic_pointer_cast<RtspMediaSource>(_pMediaSrc)) {
|
||||
//rtsp拉流代理
|
||||
if (resetWhenRePlay || !_mediaMuxer) {
|
||||
_mediaMuxer.reset(new MultiMediaSourceMuxer(_strVhost, _strApp, _strSrc, getDuration(), false, _bEnableRtmp, _bEnableHls, _bEnableMp4));
|
||||
}
|
||||
} else if (dynamic_pointer_cast<RtmpMediaSource>(_pMediaSrc)) {
|
||||
//rtmp拉流代理
|
||||
if (resetWhenRePlay || !_mediaMuxer) {
|
||||
_mediaMuxer.reset(new MultiMediaSourceMuxer(_strVhost, _strApp, _strSrc, getDuration(), _bEnableRtsp, false, _bEnableHls, _bEnableMp4));
|
||||
}
|
||||
} else {
|
||||
//其他拉流代理
|
||||
if (resetWhenRePlay || !_mediaMuxer) {
|
||||
_mediaMuxer.reset(new MultiMediaSourceMuxer(_strVhost, _strApp, _strSrc, getDuration(), _bEnableRtsp, _bEnableRtmp, _bEnableHls, _bEnableMp4));
|
||||
}
|
||||
}
|
||||
_mediaMuxer->setListener(shared_from_this());
|
||||
GET_CONFIG(bool,resetWhenRePlay,General::kResetWhenRePlay);
|
||||
if (dynamic_pointer_cast<RtspMediaSource>(_pMediaSrc)) {
|
||||
//rtsp拉流代理
|
||||
if (resetWhenRePlay || !_mediaMuxer) {
|
||||
_mediaMuxer.reset(new MultiMediaSourceMuxer(_strVhost, _strApp, _strSrc, getDuration(), false, _bEnableRtmp, _bEnableHls, _bEnableMp4));
|
||||
}
|
||||
} else if (dynamic_pointer_cast<RtmpMediaSource>(_pMediaSrc)) {
|
||||
//rtmp拉流代理
|
||||
if (resetWhenRePlay || !_mediaMuxer) {
|
||||
_mediaMuxer.reset(new MultiMediaSourceMuxer(_strVhost, _strApp, _strSrc, getDuration(), _bEnableRtsp, false, _bEnableHls, _bEnableMp4));
|
||||
}
|
||||
} else {
|
||||
//其他拉流代理
|
||||
if (resetWhenRePlay || !_mediaMuxer) {
|
||||
_mediaMuxer.reset(new MultiMediaSourceMuxer(_strVhost, _strApp, _strSrc, getDuration(), _bEnableRtsp, _bEnableRtmp, _bEnableHls, _bEnableMp4));
|
||||
}
|
||||
}
|
||||
_mediaMuxer->setListener(shared_from_this());
|
||||
|
||||
auto videoTrack = getTrack(TrackVideo,false);
|
||||
if(videoTrack){
|
||||
//添加视频
|
||||
_mediaMuxer->addTrack(videoTrack);
|
||||
//视频数据写入_mediaMuxer
|
||||
videoTrack->addDelegate(_mediaMuxer);
|
||||
}
|
||||
auto videoTrack = getTrack(TrackVideo,false);
|
||||
if(videoTrack){
|
||||
//添加视频
|
||||
_mediaMuxer->addTrack(videoTrack);
|
||||
//视频数据写入_mediaMuxer
|
||||
videoTrack->addDelegate(_mediaMuxer);
|
||||
}
|
||||
|
||||
//是否添加静音音频
|
||||
GET_CONFIG(bool,addMuteAudio,General::kAddMuteAudio);
|
||||
//是否添加静音音频
|
||||
GET_CONFIG(bool,addMuteAudio,General::kAddMuteAudio);
|
||||
|
||||
auto audioTrack = getTrack(TrackAudio, false);
|
||||
if(audioTrack){
|
||||
//添加音频
|
||||
_mediaMuxer->addTrack(audioTrack);
|
||||
//音频数据写入_mediaMuxer
|
||||
auto audioTrack = getTrack(TrackAudio, false);
|
||||
if(audioTrack){
|
||||
//添加音频
|
||||
_mediaMuxer->addTrack(audioTrack);
|
||||
//音频数据写入_mediaMuxer
|
||||
audioTrack->addDelegate(_mediaMuxer);
|
||||
}else if(addMuteAudio && videoTrack){
|
||||
//没有音频信息,产生一个静音音频
|
||||
MuteAudioMaker::Ptr audioMaker = std::make_shared<MuteAudioMaker>();
|
||||
//videoTrack把数据写入MuteAudioMaker
|
||||
videoTrack->addDelegate(audioMaker);
|
||||
//添加一个静音Track至_mediaMuxer
|
||||
_mediaMuxer->addTrack(std::make_shared<AACTrack>());
|
||||
//MuteAudioMaker生成静音音频然后写入_mediaMuxer;
|
||||
audioMaker->addDelegate(_mediaMuxer);
|
||||
}
|
||||
//没有音频信息,产生一个静音音频
|
||||
MuteAudioMaker::Ptr audioMaker = std::make_shared<MuteAudioMaker>();
|
||||
//videoTrack把数据写入MuteAudioMaker
|
||||
videoTrack->addDelegate(audioMaker);
|
||||
//添加一个静音Track至_mediaMuxer
|
||||
_mediaMuxer->addTrack(std::make_shared<AACTrack>());
|
||||
//MuteAudioMaker生成静音音频然后写入_mediaMuxer;
|
||||
audioMaker->addDelegate(_mediaMuxer);
|
||||
}
|
||||
|
||||
//添加完毕所有track,防止单track情况下最大等待3秒
|
||||
//添加完毕所有track,防止单track情况下最大等待3秒
|
||||
_mediaMuxer->addTrackCompleted();
|
||||
|
||||
if(_pMediaSrc){
|
||||
|
||||
@@ -39,24 +39,24 @@ using namespace toolkit;
|
||||
namespace mediakit {
|
||||
|
||||
class PlayerProxy :public MediaPlayer,
|
||||
public std::enable_shared_from_this<PlayerProxy> ,
|
||||
public MediaSourceEvent{
|
||||
public std::enable_shared_from_this<PlayerProxy> ,
|
||||
public MediaSourceEvent{
|
||||
public:
|
||||
typedef std::shared_ptr<PlayerProxy> Ptr;
|
||||
typedef std::shared_ptr<PlayerProxy> Ptr;
|
||||
|
||||
//如果iRetryCount<0,则一直重试播放;否则重试iRetryCount次数
|
||||
//默认一直重试
|
||||
PlayerProxy(const string &strVhost,
|
||||
PlayerProxy(const string &strVhost,
|
||||
const string &strApp,
|
||||
const string &strSrc,
|
||||
bool bEnableRtsp = true,
|
||||
bool bEnableRtmp = true,
|
||||
bool bEnableRtsp = true,
|
||||
bool bEnableRtmp = true,
|
||||
bool bEnableHls = true,
|
||||
bool bEnableMp4 = false,
|
||||
int iRetryCount = -1,
|
||||
const EventPoller::Ptr &poller = nullptr);
|
||||
const EventPoller::Ptr &poller = nullptr);
|
||||
|
||||
virtual ~PlayerProxy();
|
||||
virtual ~PlayerProxy();
|
||||
|
||||
/**
|
||||
* 设置play结果回调,只触发一次;在play执行之前有效
|
||||
@@ -81,19 +81,19 @@ public:
|
||||
*/
|
||||
int totalReaderCount() ;
|
||||
private:
|
||||
//MediaSourceEvent override
|
||||
bool close(MediaSource &sender,bool force) override;
|
||||
//MediaSourceEvent override
|
||||
bool close(MediaSource &sender,bool force) override;
|
||||
void onNoneReader(MediaSource &sender) override;
|
||||
int totalReaderCount(MediaSource &sender) override;
|
||||
void rePlay(const string &strUrl,int iFailedCnt);
|
||||
void onPlaySuccess();
|
||||
int totalReaderCount(MediaSource &sender) override;
|
||||
void rePlay(const string &strUrl,int iFailedCnt);
|
||||
void onPlaySuccess();
|
||||
private:
|
||||
bool _bEnableRtsp;
|
||||
bool _bEnableRtmp;
|
||||
bool _bEnableHls;
|
||||
bool _bEnableMp4;
|
||||
bool _bEnableHls;
|
||||
bool _bEnableMp4;
|
||||
int _iRetryCount;
|
||||
MultiMediaSourceMuxer::Ptr _mediaMuxer;
|
||||
MultiMediaSourceMuxer::Ptr _mediaMuxer;
|
||||
string _strVhost;
|
||||
string _strApp;
|
||||
string _strSrc;
|
||||
|
||||
Reference in New Issue
Block a user