优化解复用器/播放器逻辑,在Track准备就绪后回调播放结果
This commit is contained in:
parent
be81aa7fbb
commit
132468e997
|
|
@ -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) {
|
||||||
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:
|
||||||
* 是否初始化完毕,完毕后方可调用getTrack方法
|
* 是否初始化完毕,完毕后方可调用getTrack方法
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual bool isInited() const { return true; }
|
virtual bool isInited() { return true; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取全部的Track
|
* 获取全部的Track
|
||||||
|
|
@ -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:
|
||||||
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:
|
||||||
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:
|
||||||
_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) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
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:
|
||||||
* 这样就会在inputRtmp时异步探测媒体编码格式
|
* 这样就会在inputRtmp时异步探测媒体编码格式
|
||||||
*/
|
*/
|
||||||
RtmpDemuxer(const AMFValue &val);
|
RtmpDemuxer(const AMFValue &val);
|
||||||
|
virtual ~RtmpDemuxer(){};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
@ -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:
|
||||||
_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) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
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:
|
||||||
* @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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue