Commit 132468e9 by xiongziliang

优化解复用器/播放器逻辑,在Track准备就绪后回调播放结果

parent be81aa7f
...@@ -232,8 +232,10 @@ CodecId Factory::getCodecIdByAmf(const AMFValue &val){ ...@@ -232,8 +232,10 @@ CodecId Factory::getCodecIdByAmf(const AMFValue &val){
WarnL << "暂不支持该Amf:" << type_id; WarnL << "暂不支持该Amf:" << type_id;
return CodecInvalid; return CodecInvalid;
} }
}else{
WarnL << "Metedata不存在相应的Track";
} }
WarnL << "暂不支持该Amf:" << val.type();
return CodecInvalid; return CodecInvalid;
} }
......
...@@ -51,4 +51,39 @@ PlayerBase::Ptr PlayerBase::createPlayer(const char* strUrl) { ...@@ -51,4 +51,39 @@ PlayerBase::Ptr PlayerBase::createPlayer(const char* strUrl) {
return PlayerBase::Ptr(new RtspPlayerImp()); 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 */ } /* namespace mediakit */
...@@ -55,7 +55,7 @@ public: ...@@ -55,7 +55,7 @@ public:
* 是否初始化完毕,完毕后方可调用getTrack方法 * 是否初始化完毕,完毕后方可调用getTrack方法
* @return * @return
*/ */
virtual bool isInited() const { return true; } virtual bool isInited() { return true; }
/** /**
* 获取全部的Track * 获取全部的Track
...@@ -183,7 +183,7 @@ public: ...@@ -183,7 +183,7 @@ public:
_playResultCB = cb; _playResultCB = cb;
} }
bool isInited() const override{ bool isInited() override{
if (_parser) { if (_parser) {
return _parser->isInited(); return _parser->isInited();
} }
...@@ -225,12 +225,37 @@ protected: ...@@ -225,12 +225,37 @@ protected:
void onShutdown(const SockException &ex) override { void onShutdown(const SockException &ex) override {
if (_shutdownCB) { if (_shutdownCB) {
_shutdownCB(ex); _shutdownCB(ex);
_shutdownCB = nullptr;
} }
} }
void onPlayResult(const SockException &ex) override { void onPlayResult(const SockException &ex) override {
if (_playResultCB) { if(!_playResultCB){
return;
}
if(ex){
//播放失败,则立即回调
_playResultCB(ex); _playResultCB(ex);
_playResultCB = nullptr; _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: protected:
...@@ -240,6 +265,41 @@ protected: ...@@ -240,6 +265,41 @@ protected:
MediaSource::Ptr _pMediaSrc; 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 */ } /* namespace mediakit */
#endif /* SRC_PLAYER_PLAYERBASE_H_ */ #endif /* SRC_PLAYER_PLAYERBASE_H_ */
...@@ -72,6 +72,7 @@ private: ...@@ -72,6 +72,7 @@ private:
_pRtmpMediaSrc->onWrite(chunkData); _pRtmpMediaSrc->onWrite(chunkData);
} }
_parser->inputRtmp(chunkData); _parser->inputRtmp(chunkData);
checkInited();
} }
private: private:
......
...@@ -112,38 +112,5 @@ void RtmpDemuxer::makeAudioTrack(const AMFValue &audioCodec) { ...@@ -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 */ } /* namespace mediakit */
...@@ -39,7 +39,7 @@ using namespace toolkit; ...@@ -39,7 +39,7 @@ using namespace toolkit;
namespace mediakit { namespace mediakit {
class RtmpDemuxer : public PlayerBase{ class RtmpDemuxer : public Demuxer{
public: public:
typedef std::shared_ptr<RtmpDemuxer> Ptr; typedef std::shared_ptr<RtmpDemuxer> Ptr;
...@@ -53,6 +53,7 @@ public: ...@@ -53,6 +53,7 @@ public:
* 这样就会在inputRtmp时异步探测媒体编码格式 * 这样就会在inputRtmp时异步探测媒体编码格式
*/ */
RtmpDemuxer(const AMFValue &val); RtmpDemuxer(const AMFValue &val);
virtual ~RtmpDemuxer(){};
/** /**
* *
...@@ -62,43 +63,18 @@ public: ...@@ -62,43 +63,18 @@ public:
*/ */
static int getTrackCount(const AMFValue &metedata); static int getTrackCount(const AMFValue &metedata);
virtual ~RtmpDemuxer(){};
/** /**
* 开始解复用 * 开始解复用
* @param pkt rtmp包 * @param pkt rtmp包
* @return true 代表是i帧 * @return true 代表是i帧
*/ */
bool inputRtmp(const RtmpPacket::Ptr &pkt); 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: private:
void makeVideoTrack(const AMFValue &val); void makeVideoTrack(const AMFValue &val);
void makeAudioTrack(const AMFValue &val); void makeAudioTrack(const AMFValue &val);
private: private:
float _fDuration = 0;
bool _tryedGetVideoTrack = false; bool _tryedGetVideoTrack = false;
bool _tryedGetAudioTrack = false; bool _tryedGetAudioTrack = false;
AudioTrack::Ptr _audioTrack;
VideoTrack::Ptr _videoTrack;
RtmpCodec::Ptr _audioRtmpDecoder; RtmpCodec::Ptr _audioRtmpDecoder;
RtmpCodec::Ptr _videoRtmpDecoder; RtmpCodec::Ptr _videoRtmpDecoder;
}; };
......
...@@ -75,6 +75,7 @@ private: ...@@ -75,6 +75,7 @@ private:
_pRtspMediaSrc->onWrite(rtppt,true); _pRtspMediaSrc->onWrite(rtppt,true);
} }
_parser->inputRtp(rtppt); _parser->inputRtp(rtppt);
checkInited();
} }
private: private:
......
...@@ -117,33 +117,4 @@ void RtspDemuxer::makeVideoTrack(const SdpTrack::Ptr &video) { ...@@ -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 */ } /* namespace mediakit */
...@@ -38,7 +38,7 @@ using namespace toolkit; ...@@ -38,7 +38,7 @@ using namespace toolkit;
namespace mediakit { namespace mediakit {
class RtspDemuxer : public PlayerBase{ class RtspDemuxer : public Demuxer{
public: public:
typedef std::shared_ptr<RtspDemuxer> Ptr; typedef std::shared_ptr<RtspDemuxer> Ptr;
RtspDemuxer(const string &sdp); RtspDemuxer(const string &sdp);
...@@ -51,34 +51,11 @@ public: ...@@ -51,34 +51,11 @@ public:
* @return true 代表是i帧第一个rtp包 * @return true 代表是i帧第一个rtp包
*/ */
bool inputRtp(const RtpPacket::Ptr &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: private:
void makeAudioTrack(const SdpTrack::Ptr &audio); void makeAudioTrack(const SdpTrack::Ptr &audio);
void makeVideoTrack(const SdpTrack::Ptr &video); void makeVideoTrack(const SdpTrack::Ptr &video);
void loadSdp(const SdpAttr &attr); void loadSdp(const SdpAttr &attr);
private: private:
float _fDuration = 0;
AudioTrack::Ptr _audioTrack;
VideoTrack::Ptr _videoTrack;
RtpCodec::Ptr _audioRtpDecoder; RtpCodec::Ptr _audioRtpDecoder;
RtpCodec::Ptr _videoRtpDecoder; RtpCodec::Ptr _videoRtpDecoder;
}; };
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论