diff --git a/src/Extension/Factory.cpp b/src/Extension/Factory.cpp index 053dd5a1..4aad5e9f 100644 --- a/src/Extension/Factory.cpp +++ b/src/Extension/Factory.cpp @@ -68,6 +68,7 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { auto sps = decodeBase64(base64_SPS); auto pps = decodeBase64(base64_PPS); if(sps.empty() || pps.empty()){ + //如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps return std::make_shared(); } @@ -80,6 +81,10 @@ Track::Ptr Factory::getTrackBySdp(const SdpTrack::Ptr &track) { auto vps = decodeBase64(map["sprop-vps"]); auto sps = decodeBase64(map["sprop-sps"]); auto pps = decodeBase64(map["sprop-pps"]); + if(sps.empty() || pps.empty()){ + //如果sdp里面没有sps/pps,那么可能在后续的rtp里面恢复出sps/pps + return std::make_shared(); + } return std::make_shared(vps,sps,pps,0,0,0); } diff --git a/src/Player/PlayerBase.cpp b/src/Player/PlayerBase.cpp index 4de82c30..a48879a1 100644 --- a/src/Player/PlayerBase.cpp +++ b/src/Player/PlayerBase.cpp @@ -69,12 +69,18 @@ PlayerBase::PlayerBase() { ///////////////////////////Demuxer////////////////////////////// bool Demuxer::isInited(int analysisMs) { - if(_ticker.createdTime() < analysisMs){ - //analysisMs毫秒内判断条件 - //如果音视频都准备好了 ,说明Track全部就绪 - return (_videoTrack && _videoTrack->ready() && _audioTrack && _audioTrack->ready()); + if(analysisMs && _ticker.createdTime() > analysisMs){ + //analysisMs毫秒后强制初始化完毕 + return true; + } + if (_videoTrack && !_videoTrack->ready()) { + //视频未准备好 + return false; + } + if (_audioTrack && !_audioTrack->ready()) { + //音频未准备好 + return false; } - //analysisMs毫秒后强制初始化完毕 return true; } diff --git a/src/Player/PlayerBase.h b/src/Player/PlayerBase.h index 50330b06..84fd6795 100644 --- a/src/Player/PlayerBase.h +++ b/src/Player/PlayerBase.h @@ -236,18 +236,10 @@ protected: } void onPlayResult(const SockException &ex) override { - if(!_playResultCB){ - return; - } - if(ex){ - //播放失败,则立即回调 + if(_playResultCB) { _playResultCB(ex); _playResultCB = nullptr; - return; } - //播放成功 - _playResultCB(ex); - _playResultCB = nullptr; } void onResume() override{ diff --git a/src/Rtmp/RtmpPlayer.h b/src/Rtmp/RtmpPlayer.h index e06e8191..10bc8ff1 100644 --- a/src/Rtmp/RtmpPlayer.h +++ b/src/Rtmp/RtmpPlayer.h @@ -61,6 +61,7 @@ protected: void seekToMilliSecond(uint32_t ms); protected: void onMediaData_l(const RtmpPacket::Ptr &chunkData); + //在获取config帧后才触发onPlayResult_l(而不是收到play命令回复),所以此时所有track都初始化完毕了 void onPlayResult_l(const SockException &ex, bool handshakeCompleted); //form Tcpclient diff --git a/src/Rtsp/RtspPlayerImp.h b/src/Rtsp/RtspPlayerImp.h index effa7328..c9702b43 100644 --- a/src/Rtsp/RtspPlayerImp.h +++ b/src/Rtsp/RtspPlayerImp.h @@ -75,19 +75,29 @@ private: } _parser->inputRtp(rtp); - //由于我们重载isInited方法强制认为一旦获取sdp那么就初始化Track成功, - //所以我们不需要在后续检验是否初始化成功 - //checkInited(0); + if(_maxAnalysisMS && _parser->isInited(_maxAnalysisMS)){ + PlayerImp::onPlayResult(SockException(Err_success,"play rtsp success")); + _maxAnalysisMS = 0; + } } - bool isInited(int analysisMs) override{ - //rtsp是通过sdp来完成track的初始化的,所以我们强制返回true, - //认为已经初始化完毕,这样可以提高rtsp打开速度 - return true; + //在RtspPlayer中触发onPlayResult事件只是代表收到play回复了, + //并不代表所有track初始化成功了(这跟rtmp播放器不一样) + //如果sdp里面信息不完整,只能尝试延后从rtp中恢复关键信息并初始化track + //如果超过这个时间还未获取成功,那么会强制触发onPlayResult事件(虽然此时有些track还未初始化成功) + void onPlayResult(const SockException &ex) override { + //isInited判断条件:无超时 + if(_parser->isInited(0)){ + //已经初始化成功,说明sdp里面有完善的信息 + PlayerImp::onPlayResult(ex); + }else{ + //还没初始化成功,说明sdp里面信息不完善,还有一些track未初始化成功 + _maxAnalysisMS = (*this)[Client::kMaxAnalysisMS]; + } } private: RtspMediaSource::Ptr _pRtspMediaSrc; - + int _maxAnalysisMS = 0; }; } /* namespace mediakit */