优化解复用器/播放器逻辑,在Track准备就绪后回调播放结果
This commit is contained in:
parent
be81aa7fbb
commit
132468e997
|
|
@ -232,8 +232,10 @@ CodecId Factory::getCodecIdByAmf(const AMFValue &val){
|
|||
WarnL << "暂不支持该Amf:" << type_id;
|
||||
return CodecInvalid;
|
||||
}
|
||||
}else{
|
||||
WarnL << "Metedata不存在相应的Track";
|
||||
}
|
||||
WarnL << "暂不支持该Amf:" << val.type();
|
||||
|
||||
return CodecInvalid;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,4 +51,39 @@ PlayerBase::Ptr PlayerBase::createPlayer(const char* strUrl) {
|
|||
return PlayerBase::Ptr(new RtspPlayerImp());
|
||||
}
|
||||
|
||||
///////////////////////////Demuxer//////////////////////////////
|
||||
bool Demuxer::isInited() {
|
||||
if(_ticker.createdTime() < 500){
|
||||
//500毫秒内判断条件
|
||||
//如果音视频都准备好了 ,说明Track全部就绪
|
||||
return (_videoTrack && _videoTrack->ready() && _audioTrack && _audioTrack->ready());
|
||||
}
|
||||
|
||||
//500毫秒之后,去除还未就绪的Track
|
||||
if(_videoTrack && !_videoTrack->ready()){
|
||||
//有视频但是视频未就绪
|
||||
_videoTrack = nullptr;
|
||||
}
|
||||
|
||||
if(_audioTrack && !_audioTrack->ready()){
|
||||
//有音频但是音频未就绪
|
||||
_audioTrack = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
vector<Track::Ptr> Demuxer::getTracks() const {
|
||||
vector<Track::Ptr> ret;
|
||||
if(_videoTrack){
|
||||
ret.emplace_back(_videoTrack);
|
||||
}
|
||||
if(_audioTrack){
|
||||
ret.emplace_back(_audioTrack);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
float Demuxer::getDuration() const {
|
||||
return _fDuration;
|
||||
}
|
||||
} /* namespace mediakit */
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ public:
|
|||
* 是否初始化完毕,完毕后方可调用getTrack方法
|
||||
* @return
|
||||
*/
|
||||
virtual bool isInited() const { return true; }
|
||||
virtual bool isInited() { return true; }
|
||||
|
||||
/**
|
||||
* 获取全部的Track
|
||||
|
|
@ -183,7 +183,7 @@ public:
|
|||
_playResultCB = cb;
|
||||
}
|
||||
|
||||
bool isInited() const override{
|
||||
bool isInited() override{
|
||||
if (_parser) {
|
||||
return _parser->isInited();
|
||||
}
|
||||
|
|
@ -225,12 +225,37 @@ protected:
|
|||
void onShutdown(const SockException &ex) override {
|
||||
if (_shutdownCB) {
|
||||
_shutdownCB(ex);
|
||||
_shutdownCB = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void onPlayResult(const SockException &ex) override {
|
||||
if (_playResultCB) {
|
||||
if(!_playResultCB){
|
||||
return;
|
||||
}
|
||||
if(ex){
|
||||
//播放失败,则立即回调
|
||||
_playResultCB(ex);
|
||||
_playResultCB = nullptr;
|
||||
return;
|
||||
}
|
||||
//播放成功
|
||||
|
||||
if(isInited()){
|
||||
//初始化完毕则立即回调
|
||||
_playResultCB(ex);
|
||||
_playResultCB = nullptr;
|
||||
return;
|
||||
}
|
||||
//播放成功却未初始化完毕
|
||||
}
|
||||
void checkInited(){
|
||||
if(!_playResultCB){
|
||||
return;
|
||||
}
|
||||
if(isInited()){
|
||||
_playResultCB(SockException(Err_success,"play success"));
|
||||
_playResultCB = nullptr;
|
||||
}
|
||||
}
|
||||
protected:
|
||||
|
|
@ -240,6 +265,41 @@ protected:
|
|||
MediaSource::Ptr _pMediaSrc;
|
||||
};
|
||||
|
||||
|
||||
class Demuxer : public PlayerBase{
|
||||
public:
|
||||
Demuxer(){};
|
||||
virtual ~Demuxer(){};
|
||||
|
||||
/**
|
||||
* 返回是否完成初始化完毕
|
||||
* 在构造RtspDemuxer对象时有些rtsp的sdp不包含sps pps信息
|
||||
* 所以要等待接收到到sps的rtp包后才能完成
|
||||
*
|
||||
* 在构造RtmpDemuxer对象时是无法获取sps pps aac_cfg等这些信息,
|
||||
* 所以要调用inputRtmp后才会获取到这些信息,这时才初始化成功
|
||||
* @return
|
||||
*/
|
||||
bool isInited() override;
|
||||
|
||||
/**
|
||||
* 获取所有可用Track,请在isInited()返回true时调用
|
||||
* @return
|
||||
*/
|
||||
vector<Track::Ptr> getTracks() const override;
|
||||
|
||||
/**
|
||||
* 获取节目总时长
|
||||
* @return
|
||||
*/
|
||||
float getDuration() const override;
|
||||
protected:
|
||||
AudioTrack::Ptr _audioTrack;
|
||||
VideoTrack::Ptr _videoTrack;
|
||||
Ticker _ticker;
|
||||
float _fDuration = 0;
|
||||
};
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
||||
#endif /* SRC_PLAYER_PLAYERBASE_H_ */
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ private:
|
|||
_pRtmpMediaSrc->onWrite(chunkData);
|
||||
}
|
||||
_parser->inputRtmp(chunkData);
|
||||
checkInited();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -112,38 +112,5 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) {
|
|||
}
|
||||
}
|
||||
|
||||
vector<Track::Ptr> RtmpDemuxer::getTracks() const {
|
||||
vector<Track::Ptr> ret;
|
||||
if(_videoTrack){
|
||||
ret.emplace_back(_videoTrack);
|
||||
}
|
||||
if(_audioTrack){
|
||||
ret.emplace_back(_audioTrack);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RtmpDemuxer::isInited() const {
|
||||
bool videoReady ,auidoReady;
|
||||
|
||||
if(_videoTrack){
|
||||
videoReady = _videoTrack->ready();
|
||||
}else{
|
||||
videoReady = _tryedGetVideoTrack || _tryedGetAudioTrack;
|
||||
}
|
||||
|
||||
if(_audioTrack){
|
||||
auidoReady = _audioTrack->ready();
|
||||
}else{
|
||||
auidoReady = _tryedGetVideoTrack || _tryedGetAudioTrack;
|
||||
}
|
||||
|
||||
return videoReady && auidoReady;
|
||||
}
|
||||
|
||||
float RtmpDemuxer::getDuration() const {
|
||||
return _fDuration;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ using namespace toolkit;
|
|||
|
||||
namespace mediakit {
|
||||
|
||||
class RtmpDemuxer : public PlayerBase{
|
||||
class RtmpDemuxer : public Demuxer{
|
||||
public:
|
||||
typedef std::shared_ptr<RtmpDemuxer> Ptr;
|
||||
|
||||
|
|
@ -53,6 +53,7 @@ public:
|
|||
* 这样就会在inputRtmp时异步探测媒体编码格式
|
||||
*/
|
||||
RtmpDemuxer(const AMFValue &val);
|
||||
virtual ~RtmpDemuxer(){};
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -62,43 +63,18 @@ public:
|
|||
*/
|
||||
static int getTrackCount(const AMFValue &metedata);
|
||||
|
||||
virtual ~RtmpDemuxer(){};
|
||||
|
||||
/**
|
||||
* 开始解复用
|
||||
* @param pkt rtmp包
|
||||
* @return true 代表是i帧
|
||||
*/
|
||||
bool inputRtmp(const RtmpPacket::Ptr &pkt);
|
||||
|
||||
/**
|
||||
* 获取节目总时长
|
||||
* @return
|
||||
*/
|
||||
float getDuration() const override;
|
||||
|
||||
/**
|
||||
* 返回是否完成初始化完毕
|
||||
* 由于在构造该对象时是无法获取sps pps aac_cfg等这些信息,
|
||||
* 所以要调用inputRtmp后才会获取到这些信息,这时才初始化成功
|
||||
* @return
|
||||
*/
|
||||
bool isInited() const override;
|
||||
|
||||
/**
|
||||
* 获取所有可用Track,请在isInited()返回true时调用
|
||||
* @return
|
||||
*/
|
||||
vector<Track::Ptr> getTracks() const override;
|
||||
private:
|
||||
void makeVideoTrack(const AMFValue &val);
|
||||
void makeAudioTrack(const AMFValue &val);
|
||||
private:
|
||||
float _fDuration = 0;
|
||||
bool _tryedGetVideoTrack = false;
|
||||
bool _tryedGetAudioTrack = false;
|
||||
AudioTrack::Ptr _audioTrack;
|
||||
VideoTrack::Ptr _videoTrack;
|
||||
RtmpCodec::Ptr _audioRtmpDecoder;
|
||||
RtmpCodec::Ptr _videoRtmpDecoder;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ private:
|
|||
_pRtspMediaSrc->onWrite(rtppt,true);
|
||||
}
|
||||
_parser->inputRtp(rtppt);
|
||||
checkInited();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -117,33 +117,4 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) {
|
|||
}
|
||||
}
|
||||
|
||||
vector<Track::Ptr> RtspDemuxer::getTracks() const {
|
||||
vector<Track::Ptr> ret;
|
||||
if(_videoTrack){
|
||||
ret.emplace_back(_videoTrack);
|
||||
}
|
||||
if(_audioTrack){
|
||||
ret.emplace_back(_audioTrack);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RtspDemuxer::isInited() const {
|
||||
bool videoReady = true ,auidoReady = true;
|
||||
|
||||
if(_videoTrack){
|
||||
videoReady = _videoTrack->ready();
|
||||
}
|
||||
|
||||
if(_audioTrack){
|
||||
auidoReady = _audioTrack->ready();
|
||||
}
|
||||
|
||||
return videoReady && auidoReady;
|
||||
}
|
||||
|
||||
float RtspDemuxer::getDuration() const {
|
||||
return _fDuration;
|
||||
}
|
||||
|
||||
} /* namespace mediakit */
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ using namespace toolkit;
|
|||
|
||||
namespace mediakit {
|
||||
|
||||
class RtspDemuxer : public PlayerBase{
|
||||
class RtspDemuxer : public Demuxer{
|
||||
public:
|
||||
typedef std::shared_ptr<RtspDemuxer> Ptr;
|
||||
RtspDemuxer(const string &sdp);
|
||||
|
|
@ -51,34 +51,11 @@ public:
|
|||
* @return true 代表是i帧第一个rtp包
|
||||
*/
|
||||
bool inputRtp(const RtpPacket::Ptr &rtp);
|
||||
|
||||
/**
|
||||
* 获取节目总时长
|
||||
* @return
|
||||
*/
|
||||
float getDuration() const override;
|
||||
|
||||
/**
|
||||
* 返回是否完成初始化完毕
|
||||
* 由于有些rtsp的sdp不包含sps pps信息
|
||||
* 所以要等待接收到到sps的rtp包后才能完成
|
||||
* @return
|
||||
*/
|
||||
bool isInited() const override;
|
||||
|
||||
/**
|
||||
* 获取所有可用Track,请在isInited()返回true时调用
|
||||
* @return
|
||||
*/
|
||||
vector<Track::Ptr> getTracks() const override;
|
||||
private:
|
||||
void makeAudioTrack(const SdpTrack::Ptr &audio);
|
||||
void makeVideoTrack(const SdpTrack::Ptr &video);
|
||||
void loadSdp(const SdpAttr &attr);
|
||||
private:
|
||||
float _fDuration = 0;
|
||||
AudioTrack::Ptr _audioTrack;
|
||||
VideoTrack::Ptr _videoTrack;
|
||||
RtpCodec::Ptr _audioRtpDecoder;
|
||||
RtpCodec::Ptr _videoRtpDecoder;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue