mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 22:55:52 +08:00
播放器支持超时时间的配置项
优化函数命名
This commit is contained in:
parent
e240044f2f
commit
40a7913bf9
@ -39,8 +39,13 @@ const char PlayerBase::kRtspUser[] = "rtsp_user" ;
|
|||||||
const char PlayerBase::kRtspPwd[] = "rtsp_pwd";
|
const char PlayerBase::kRtspPwd[] = "rtsp_pwd";
|
||||||
const char PlayerBase::kRtspPwdIsMD5[] = "rtsp_pwd_md5";
|
const char PlayerBase::kRtspPwdIsMD5[] = "rtsp_pwd_md5";
|
||||||
|
|
||||||
|
const char PlayerBase::kPlayTimeoutMS[] = "play_timeout_ms";
|
||||||
|
const char PlayerBase::kMediaTimeoutMS[] = "media_timeout_ms";
|
||||||
|
const char PlayerBase::kBeatIntervalMS[] = "beat_interval_ms";
|
||||||
|
const char PlayerBase::kMaxAnalysisMS[] = "max_analysis_ms";
|
||||||
|
|
||||||
PlayerBase::Ptr PlayerBase::createPlayer(const char* strUrl) {
|
|
||||||
|
PlayerBase::Ptr PlayerBase::createPlayer(const char* strUrl) {
|
||||||
static auto releasePlayer = [](PlayerBase *ptr){
|
static auto releasePlayer = [](PlayerBase *ptr){
|
||||||
onceToken token(nullptr,[&](){
|
onceToken token(nullptr,[&](){
|
||||||
delete ptr;
|
delete ptr;
|
||||||
@ -57,6 +62,13 @@ PlayerBase::Ptr PlayerBase::createPlayer(const char* strUrl) {
|
|||||||
return PlayerBase::Ptr(new RtspPlayerImp(),releasePlayer);
|
return PlayerBase::Ptr(new RtspPlayerImp(),releasePlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlayerBase::PlayerBase() {
|
||||||
|
this->mINI::operator[](kPlayTimeoutMS) = 10000;
|
||||||
|
this->mINI::operator[](kMediaTimeoutMS) = 5000;
|
||||||
|
this->mINI::operator[](kBeatIntervalMS) = 5000;
|
||||||
|
this->mINI::operator[](kMaxAnalysisMS) = 2000;
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////Demuxer//////////////////////////////
|
///////////////////////////Demuxer//////////////////////////////
|
||||||
bool Demuxer::isInited(int analysisMs) {
|
bool Demuxer::isInited(int analysisMs) {
|
||||||
if(_ticker.createdTime() < analysisMs){
|
if(_ticker.createdTime() < analysisMs){
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
* @param analysisMs 数据流最大分析时间 单位毫秒
|
* @param analysisMs 数据流最大分析时间 单位毫秒
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual bool isInited(int analysisMs = 2000) { return true; }
|
virtual bool isInited(int analysisMs) { return true; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取全部的Track
|
* 获取全部的Track
|
||||||
@ -103,10 +103,19 @@ public:
|
|||||||
static const char kRtspUser[];
|
static const char kRtspUser[];
|
||||||
//rtsp认证用用户密码,可以是明文也可以是md5,md5密码生成方式 md5(username:realm:password)
|
//rtsp认证用用户密码,可以是明文也可以是md5,md5密码生成方式 md5(username:realm:password)
|
||||||
static const char kRtspPwd[];
|
static const char kRtspPwd[];
|
||||||
//rtsp认证用用户密码是否为md5
|
//rtsp认证用用户密码是否为md5类型
|
||||||
static const char kRtspPwdIsMD5[];
|
static const char kRtspPwdIsMD5[];
|
||||||
|
//播放超时时间,默认10,000 毫秒
|
||||||
|
static const char kPlayTimeoutMS[];
|
||||||
|
//rtp/rtmp包接收超时时间,默认5000秒
|
||||||
|
static const char kMediaTimeoutMS[];
|
||||||
|
//rtsp/rtmp心跳时间,默认5000毫秒
|
||||||
|
static const char kBeatIntervalMS[];
|
||||||
|
//Track编码格式探测最大时间,单位毫秒,默认2000
|
||||||
|
static const char kMaxAnalysisMS[];
|
||||||
|
|
||||||
PlayerBase(){}
|
|
||||||
|
PlayerBase();
|
||||||
virtual ~PlayerBase(){}
|
virtual ~PlayerBase(){}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,7 +196,7 @@ public:
|
|||||||
_playResultCB = cb;
|
_playResultCB = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInited(int analysisMs = 2000) override{
|
bool isInited(int analysisMs) override{
|
||||||
if (_parser) {
|
if (_parser) {
|
||||||
return _parser->isInited(analysisMs);
|
return _parser->isInited(analysisMs);
|
||||||
}
|
}
|
||||||
@ -243,21 +252,20 @@ protected:
|
|||||||
_playResultCB = nullptr;
|
_playResultCB = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//播放成功
|
//播放成功后,我们还必须等待各个Track初始化完毕才能回调告知已经初始化完毕
|
||||||
|
if(isInited(INT_MAX)){
|
||||||
if(isInited()){
|
|
||||||
//初始化完毕则立即回调
|
//初始化完毕则立即回调
|
||||||
_playResultCB(ex);
|
_playResultCB(ex);
|
||||||
_playResultCB = nullptr;
|
_playResultCB = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//播放成功却未初始化完毕
|
//播放成功却未初始化完毕,这个时候不回调汇报播放成功
|
||||||
}
|
}
|
||||||
void checkInited(){
|
void checkInited(int analysisMs){
|
||||||
if(!_playResultCB){
|
if(!_playResultCB){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(isInited()){
|
if(isInited(analysisMs)){
|
||||||
_playResultCB(SockException(Err_success,"play success"));
|
_playResultCB(SockException(Err_success,"play success"));
|
||||||
_playResultCB = nullptr;
|
_playResultCB = nullptr;
|
||||||
}
|
}
|
||||||
@ -285,7 +293,7 @@ public:
|
|||||||
* @param analysisMs 数据流最大分析时间 单位毫秒
|
* @param analysisMs 数据流最大分析时间 单位毫秒
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool isInited(int analysisMs = 2000) override;
|
bool isInited(int analysisMs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有可用Track,请在isInited()返回true时调用
|
* 获取所有可用Track,请在isInited()返回true时调用
|
||||||
|
@ -80,7 +80,7 @@ void RtmpPlayer::play(const char* strUrl) {
|
|||||||
_strTcUrl = string("rtmp://") + strHost + "/" + _strApp;
|
_strTcUrl = string("rtmp://") + strHost + "/" + _strApp;
|
||||||
|
|
||||||
if (!_strApp.size() || !_strStream.size()) {
|
if (!_strApp.size() || !_strStream.size()) {
|
||||||
_onPlayResult(SockException(Err_other,"rtmp url非法"));
|
onPlayResult_l(SockException(Err_other,"rtmp url非法"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DebugL << strHost << " " << _strApp << " " << _strStream;
|
DebugL << strHost << " " << _strApp << " " << _strStream;
|
||||||
@ -96,27 +96,30 @@ void RtmpPlayer::play(const char* strUrl) {
|
|||||||
if(!(*this)[PlayerBase::kNetAdapter].empty()){
|
if(!(*this)[PlayerBase::kNetAdapter].empty()){
|
||||||
setNetAdapter((*this)[PlayerBase::kNetAdapter]);
|
setNetAdapter((*this)[PlayerBase::kNetAdapter]);
|
||||||
}
|
}
|
||||||
startConnect(strHost, iPort);
|
|
||||||
}
|
|
||||||
void RtmpPlayer::onErr(const SockException &ex){
|
|
||||||
_onShutdown(ex);
|
|
||||||
}
|
|
||||||
void RtmpPlayer::onConnect(const SockException &err){
|
|
||||||
if(err.getErrCode()!=Err_success) {
|
|
||||||
_onPlayResult(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
weak_ptr<RtmpPlayer> weakSelf= dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
|
weak_ptr<RtmpPlayer> weakSelf= dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
|
||||||
_pPlayTimer.reset( new Timer(10, [weakSelf]() {
|
float playTimeOutSec = (*this)[kPlayTimeoutMS].as<int>() / 1000.0;
|
||||||
|
_pPlayTimer.reset( new Timer(playTimeOutSec, [weakSelf]() {
|
||||||
auto strongSelf=weakSelf.lock();
|
auto strongSelf=weakSelf.lock();
|
||||||
if(!strongSelf) {
|
if(!strongSelf) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
strongSelf->_onPlayResult(SockException(Err_timeout,"play rtmp timeout"));
|
strongSelf->onPlayResult_l(SockException(Err_timeout,"play rtmp timeout"));
|
||||||
strongSelf->teardown();
|
strongSelf->teardown();
|
||||||
return false;
|
return false;
|
||||||
},getPoller()));
|
},getPoller()));
|
||||||
|
|
||||||
|
startConnect(strHost, iPort , playTimeOutSec);
|
||||||
|
}
|
||||||
|
void RtmpPlayer::onErr(const SockException &ex){
|
||||||
|
onShutdown_l(ex);
|
||||||
|
}
|
||||||
|
void RtmpPlayer::onConnect(const SockException &err){
|
||||||
|
if(err.getErrCode()!=Err_success) {
|
||||||
|
onPlayResult_l(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
weak_ptr<RtmpPlayer> weakSelf= dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
|
||||||
startClientSession([weakSelf](){
|
startClientSession([weakSelf](){
|
||||||
auto strongSelf=weakSelf.lock();
|
auto strongSelf=weakSelf.lock();
|
||||||
if(!strongSelf) {
|
if(!strongSelf) {
|
||||||
@ -130,8 +133,8 @@ void RtmpPlayer::onRecv(const Buffer::Ptr &pBuf){
|
|||||||
onParseRtmp(pBuf->data(), pBuf->size());
|
onParseRtmp(pBuf->data(), pBuf->size());
|
||||||
} catch (exception &e) {
|
} catch (exception &e) {
|
||||||
SockException ex(Err_other, e.what());
|
SockException ex(Err_other, e.what());
|
||||||
_onPlayResult(ex);
|
onPlayResult_l(ex);
|
||||||
_onShutdown(ex);
|
onShutdown_l(ex);
|
||||||
teardown();
|
teardown();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,7 +213,7 @@ inline void RtmpPlayer::send_pause(bool bPause) {
|
|||||||
}else{
|
}else{
|
||||||
_bPaused = bPause;
|
_bPaused = bPause;
|
||||||
if(!bPause){
|
if(!bPause){
|
||||||
_onPlayResult(SockException(Err_success, "rtmp resum success"));
|
onPlayResult_l(SockException(Err_success, "rtmp resum success"));
|
||||||
}else{
|
}else{
|
||||||
//暂停播放
|
//暂停播放
|
||||||
_pMediaTimer.reset();
|
_pMediaTimer.reset();
|
||||||
@ -222,7 +225,7 @@ inline void RtmpPlayer::send_pause(bool bPause) {
|
|||||||
_pBeatTimer.reset();
|
_pBeatTimer.reset();
|
||||||
if(bPause){
|
if(bPause){
|
||||||
weak_ptr<RtmpPlayer> weakSelf = dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
|
weak_ptr<RtmpPlayer> weakSelf = dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
|
||||||
_pBeatTimer.reset(new Timer(3,[weakSelf](){
|
_pBeatTimer.reset(new Timer((*this)[kBeatIntervalMS].as<int>() / 1000.0,[weakSelf](){
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if (!strongSelf){
|
if (!strongSelf){
|
||||||
return false;
|
return false;
|
||||||
@ -279,12 +282,12 @@ void RtmpPlayer::onCmd_onMetaData(AMFDecoder &dec) {
|
|||||||
if(!onCheckMeta(val)){
|
if(!onCheckMeta(val)){
|
||||||
throw std::runtime_error("onCheckMeta faied");
|
throw std::runtime_error("onCheckMeta faied");
|
||||||
}
|
}
|
||||||
_onPlayResult(SockException(Err_success,"play rtmp success"));
|
onPlayResult_l(SockException(Err_success,"play rtmp success"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtmpPlayer::onStreamDry(uint32_t ui32StreamId) {
|
void RtmpPlayer::onStreamDry(uint32_t ui32StreamId) {
|
||||||
//TraceL << ui32StreamId;
|
//TraceL << ui32StreamId;
|
||||||
_onShutdown(SockException(Err_other,"rtmp stream dry"));
|
onShutdown_l(SockException(Err_other,"rtmp stream dry"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -311,7 +314,7 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
|
|||||||
if (_aNowStampTicker[idx].elapsedTime() > 500) {
|
if (_aNowStampTicker[idx].elapsedTime() > 500) {
|
||||||
_aiNowStamp[idx] = chunkData.timeStamp;
|
_aiNowStamp[idx] = chunkData.timeStamp;
|
||||||
}
|
}
|
||||||
_onMediaData(std::make_shared<RtmpPacket>(std::move(chunkData)));
|
onMediaData_l(std::make_shared<RtmpPacket>(std::move(chunkData)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -58,32 +58,33 @@ protected:
|
|||||||
uint32_t getProgressMilliSecond() const;
|
uint32_t getProgressMilliSecond() const;
|
||||||
void seekToMilliSecond(uint32_t ms);
|
void seekToMilliSecond(uint32_t ms);
|
||||||
protected:
|
protected:
|
||||||
void _onShutdown(const SockException &ex) {
|
void onShutdown_l(const SockException &ex) {
|
||||||
WarnL << ex.getErrCode() << " " << ex.what();
|
WarnL << ex.getErrCode() << " " << ex.what();
|
||||||
_pPlayTimer.reset();
|
_pPlayTimer.reset();
|
||||||
_pMediaTimer.reset();
|
_pMediaTimer.reset();
|
||||||
_pBeatTimer.reset();
|
_pBeatTimer.reset();
|
||||||
onShutdown(ex);
|
onShutdown(ex);
|
||||||
}
|
}
|
||||||
void _onMediaData(const RtmpPacket::Ptr &chunkData) {
|
void onMediaData_l(const RtmpPacket::Ptr &chunkData) {
|
||||||
_mediaTicker.resetTime();
|
_mediaTicker.resetTime();
|
||||||
onMediaData(chunkData);
|
onMediaData(chunkData);
|
||||||
}
|
}
|
||||||
void _onPlayResult(const SockException &ex) {
|
void onPlayResult_l(const SockException &ex) {
|
||||||
WarnL << ex.getErrCode() << " " << ex.what();
|
WarnL << ex.getErrCode() << " " << ex.what();
|
||||||
_pPlayTimer.reset();
|
_pPlayTimer.reset();
|
||||||
_pMediaTimer.reset();
|
_pMediaTimer.reset();
|
||||||
if (!ex) {
|
if (!ex) {
|
||||||
_mediaTicker.resetTime();
|
_mediaTicker.resetTime();
|
||||||
weak_ptr<RtmpPlayer> weakSelf = dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
|
weak_ptr<RtmpPlayer> weakSelf = dynamic_pointer_cast<RtmpPlayer>(shared_from_this());
|
||||||
_pMediaTimer.reset( new Timer(5, [weakSelf]() {
|
int timeoutMS = (*this)[kMediaTimeoutMS].as<int>();
|
||||||
|
_pMediaTimer.reset( new Timer(timeoutMS / 2000.0, [weakSelf,timeoutMS]() {
|
||||||
auto strongSelf=weakSelf.lock();
|
auto strongSelf=weakSelf.lock();
|
||||||
if(!strongSelf) {
|
if(!strongSelf) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(strongSelf->_mediaTicker.elapsedTime()>10000) {
|
if(strongSelf->_mediaTicker.elapsedTime()> timeoutMS) {
|
||||||
//recv media timeout!
|
//recv media timeout!
|
||||||
strongSelf->_onShutdown(SockException(Err_timeout,"recv rtmp timeout"));
|
strongSelf->onShutdown_l(SockException(Err_timeout,"recv rtmp timeout"));
|
||||||
strongSelf->teardown();
|
strongSelf->teardown();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,10 @@ public:
|
|||||||
fProgress = MAX(float(0),MIN(fProgress,float(1.0)));
|
fProgress = MAX(float(0),MIN(fProgress,float(1.0)));
|
||||||
seekToMilliSecond(fProgress * getDuration() * 1000);
|
seekToMilliSecond(fProgress * getDuration() * 1000);
|
||||||
};
|
};
|
||||||
|
void play(const char* strUrl) override {
|
||||||
|
_analysisMs = (*this)[PlayerBase::kMaxAnalysisMS].as<int>();
|
||||||
|
PlayerImp<RtmpPlayer,RtmpDemuxer>::play(strUrl);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
//派生类回调函数
|
//派生类回调函数
|
||||||
bool onCheckMeta(AMFValue &val) override {
|
bool onCheckMeta(AMFValue &val) override {
|
||||||
@ -71,15 +75,16 @@ private:
|
|||||||
_pRtmpMediaSrc->onWrite(chunkData);
|
_pRtmpMediaSrc->onWrite(chunkData);
|
||||||
}
|
}
|
||||||
if(!_parser){
|
if(!_parser){
|
||||||
|
//这个流没有metedata,那么尝试在音视频包里面还原出相关信息
|
||||||
_parser.reset(new RtmpDemuxer());
|
_parser.reset(new RtmpDemuxer());
|
||||||
_onPlayResult(SockException(Err_success,"play rtmp success"));
|
onPlayResult_l(SockException(Err_success,"play rtmp success"));
|
||||||
}
|
}
|
||||||
_parser->inputRtmp(chunkData);
|
_parser->inputRtmp(chunkData);
|
||||||
checkInited();
|
checkInited(_analysisMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RtmpMediaSource::Ptr _pRtmpMediaSrc;
|
RtmpMediaSource::Ptr _pRtmpMediaSrc;
|
||||||
|
int _analysisMs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,15 +59,15 @@ public:
|
|||||||
}
|
}
|
||||||
virtual ~RtmpToRtspMediaSource(){}
|
virtual ~RtmpToRtspMediaSource(){}
|
||||||
|
|
||||||
void onGetMetaData(const AMFValue &_metadata) override {
|
void onGetMetaData(const AMFValue &metadata) override {
|
||||||
_rtmpDemuxer = std::make_shared<RtmpDemuxer>(_metadata);
|
_rtmpDemuxer = std::make_shared<RtmpDemuxer>(metadata);
|
||||||
RtmpMediaSource::onGetMetaData(_metadata);
|
RtmpMediaSource::onGetMetaData(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onWrite(const RtmpPacket::Ptr &pkt,bool key_pos) override {
|
void onWrite(const RtmpPacket::Ptr &pkt,bool key_pos) override {
|
||||||
if(_rtmpDemuxer){
|
if(_rtmpDemuxer){
|
||||||
_rtmpDemuxer->inputRtmp(pkt);
|
_rtmpDemuxer->inputRtmp(pkt);
|
||||||
if(!_rtspMuxer && _rtmpDemuxer->isInited()){
|
if(!_rtspMuxer && _rtmpDemuxer->isInited(2000)){
|
||||||
_rtspMuxer = std::make_shared<RtspMediaSourceMuxer>(getVhost(),
|
_rtspMuxer = std::make_shared<RtspMediaSourceMuxer>(getVhost(),
|
||||||
getApp(),
|
getApp(),
|
||||||
getId(),
|
getId(),
|
||||||
|
@ -54,7 +54,7 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sps.size() && pkt->strBuf.size() > 9) {
|
if (pkt->strBuf.size() > 9) {
|
||||||
uint32_t iTotalLen = pkt->strBuf.size();
|
uint32_t iTotalLen = pkt->strBuf.size();
|
||||||
uint32_t iOffset = 5;
|
uint32_t iOffset = 5;
|
||||||
uint8_t *cts_ptr = (uint8_t *) (pkt->strBuf.data() + 2);
|
uint8_t *cts_ptr = (uint8_t *) (pkt->strBuf.data() + 2);
|
||||||
@ -81,9 +81,15 @@ inline void H264RtmpDecoder::onGetH264_l(const char* pcData, int iLen, uint32_t
|
|||||||
switch (H264_TYPE(pcData[0])) {
|
switch (H264_TYPE(pcData[0])) {
|
||||||
case H264Frame::NAL_IDR: {
|
case H264Frame::NAL_IDR: {
|
||||||
//I frame
|
//I frame
|
||||||
onGetH264(_sps.data(), _sps.length(), dts , pts);
|
if(_sps.length()){
|
||||||
onGetH264(_pps.data(), _pps.length(), dts , pts);
|
onGetH264(_sps.data(), _sps.length(), dts , pts);
|
||||||
|
}
|
||||||
|
if(_pps.length()){
|
||||||
|
onGetH264(_pps.data(), _pps.length(), dts , pts);
|
||||||
|
}
|
||||||
|
onGetH264(pcData, iLen, dts , pts);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case H264Frame::NAL_B_P: {
|
case H264Frame::NAL_B_P: {
|
||||||
//I or P or B frame
|
//I or P or B frame
|
||||||
onGetH264(pcData, iLen, dts , pts);
|
onGetH264(pcData, iLen, dts , pts);
|
||||||
|
@ -133,7 +133,20 @@ void RtspPlayer::play(const char* strUrl, const char *strUser, const char *strPw
|
|||||||
if(!(*this)[PlayerBase::kNetAdapter].empty()){
|
if(!(*this)[PlayerBase::kNetAdapter].empty()){
|
||||||
setNetAdapter((*this)[PlayerBase::kNetAdapter]);
|
setNetAdapter((*this)[PlayerBase::kNetAdapter]);
|
||||||
}
|
}
|
||||||
startConnect(ip.data(), port);
|
|
||||||
|
weak_ptr<RtspPlayer> weakSelf = dynamic_pointer_cast<RtspPlayer>(shared_from_this());
|
||||||
|
float playTimeOutSec = (*this)[kPlayTimeoutMS].as<int>() / 1000.0;
|
||||||
|
_pPlayTimer.reset( new Timer(playTimeOutSec, [weakSelf]() {
|
||||||
|
auto strongSelf=weakSelf.lock();
|
||||||
|
if(!strongSelf) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
strongSelf->onPlayResult_l(SockException(Err_timeout,"play rtsp timeout"));
|
||||||
|
strongSelf->teardown();
|
||||||
|
return false;
|
||||||
|
},getPoller()));
|
||||||
|
|
||||||
|
startConnect(ip.data(), port , playTimeOutSec);
|
||||||
}
|
}
|
||||||
void RtspPlayer::onConnect(const SockException &err){
|
void RtspPlayer::onConnect(const SockException &err){
|
||||||
if(err.getErrCode()!=Err_success) {
|
if(err.getErrCode()!=Err_success) {
|
||||||
@ -143,17 +156,6 @@ void RtspPlayer::onConnect(const SockException &err){
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendDescribe();
|
sendDescribe();
|
||||||
|
|
||||||
weak_ptr<RtspPlayer> weakSelf = dynamic_pointer_cast<RtspPlayer>(shared_from_this());
|
|
||||||
_pPlayTimer.reset( new Timer(10, [weakSelf]() {
|
|
||||||
auto strongSelf=weakSelf.lock();
|
|
||||||
if(!strongSelf) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
strongSelf->onPlayResult_l(SockException(Err_timeout,"play rtsp timeout"));
|
|
||||||
strongSelf->teardown();
|
|
||||||
return false;
|
|
||||||
},getPoller()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtspPlayer::onRecv(const Buffer::Ptr& pBuf) {
|
void RtspPlayer::onRecv(const Buffer::Ptr& pBuf) {
|
||||||
@ -346,7 +348,7 @@ void RtspPlayer::handleResSETUP(const Parser &parser, unsigned int uiTrackIndex)
|
|||||||
}
|
}
|
||||||
/////////////////////////心跳/////////////////////////////////
|
/////////////////////////心跳/////////////////////////////////
|
||||||
weak_ptr<RtspPlayer> weakSelf = dynamic_pointer_cast<RtspPlayer>(shared_from_this());
|
weak_ptr<RtspPlayer> weakSelf = dynamic_pointer_cast<RtspPlayer>(shared_from_this());
|
||||||
_pBeatTimer.reset(new Timer(5, [weakSelf](){
|
_pBeatTimer.reset(new Timer((*this)[kBeatIntervalMS].as<int>() / 1000.0, [weakSelf](){
|
||||||
auto strongSelf = weakSelf.lock();
|
auto strongSelf = weakSelf.lock();
|
||||||
if (!strongSelf){
|
if (!strongSelf){
|
||||||
return false;
|
return false;
|
||||||
@ -591,12 +593,13 @@ void RtspPlayer::onPlayResult_l(const SockException &ex) {
|
|||||||
if (!ex) {
|
if (!ex) {
|
||||||
_rtpTicker.resetTime();
|
_rtpTicker.resetTime();
|
||||||
weak_ptr<RtspPlayer> weakSelf = dynamic_pointer_cast<RtspPlayer>(shared_from_this());
|
weak_ptr<RtspPlayer> weakSelf = dynamic_pointer_cast<RtspPlayer>(shared_from_this());
|
||||||
_pRtpTimer.reset( new Timer(5, [weakSelf]() {
|
int timeoutMS = (*this)[kMediaTimeoutMS].as<int>();
|
||||||
|
_pRtpTimer.reset( new Timer(timeoutMS / 2000.0, [weakSelf,timeoutMS]() {
|
||||||
auto strongSelf=weakSelf.lock();
|
auto strongSelf=weakSelf.lock();
|
||||||
if(!strongSelf) {
|
if(!strongSelf) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(strongSelf->_rtpTicker.elapsedTime()>10000) {
|
if(strongSelf->_rtpTicker.elapsedTime()> timeoutMS) {
|
||||||
//recv rtp timeout!
|
//recv rtp timeout!
|
||||||
strongSelf->onShutdown_l(SockException(Err_timeout,"recv rtp timeout"));
|
strongSelf->onShutdown_l(SockException(Err_timeout,"recv rtp timeout"));
|
||||||
strongSelf->teardown();
|
strongSelf->teardown();
|
||||||
|
@ -74,10 +74,15 @@ private:
|
|||||||
_pRtspMediaSrc->onWrite(rtppt,true);
|
_pRtspMediaSrc->onWrite(rtppt,true);
|
||||||
}
|
}
|
||||||
_parser->inputRtp(rtppt);
|
_parser->inputRtp(rtppt);
|
||||||
checkInited();
|
|
||||||
|
//由于我们重载isInited方法强制认为一旦获取sdp那么就初始化Track成功,
|
||||||
|
//所以我们不需要在后续检验是否初始化成功
|
||||||
|
//checkInited(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInited(int analysisMs = 2000) override{
|
bool isInited(int analysisMs) override{
|
||||||
|
//rtsp是通过sdp来完成track的初始化的,所以我们强制返回true,
|
||||||
|
//认为已经初始化完毕,这样可以提高rtsp打开速度
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
@ -61,7 +61,7 @@ public:
|
|||||||
virtual void onWrite(const RtpPacket::Ptr &rtp, bool bKeyPos) override {
|
virtual void onWrite(const RtpPacket::Ptr &rtp, bool bKeyPos) override {
|
||||||
if (_rtspDemuxer) {
|
if (_rtspDemuxer) {
|
||||||
bKeyPos = _rtspDemuxer->inputRtp(rtp);
|
bKeyPos = _rtspDemuxer->inputRtp(rtp);
|
||||||
if (!_rtmpMuxer && _rtspDemuxer->isInited()) {
|
if (!_rtmpMuxer && _rtspDemuxer->isInited(2000)) {
|
||||||
_rtmpMuxer = std::make_shared<RtmpMediaSourceMuxer>(getVhost(),
|
_rtmpMuxer = std::make_shared<RtmpMediaSourceMuxer>(getVhost(),
|
||||||
getApp(),
|
getApp(),
|
||||||
getId(),
|
getId(),
|
||||||
|
Loading…
Reference in New Issue
Block a user