修改Rtmp播放结果回调事件触发机制,防止秒开失败以及获取Track失败

This commit is contained in:
xiongziliang 2019-08-01 13:12:24 +08:00
parent fcdcf12af9
commit 2e95c3b2fa
6 changed files with 29 additions and 63 deletions

View File

@ -51,6 +51,8 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
//缓存sps pps后续插入到I帧之前 //缓存sps pps后续插入到I帧之前
_sps = pkt->getH264SPS(); _sps = pkt->getH264SPS();
_pps = pkt->getH264PPS(); _pps = pkt->getH264PPS();
onGetH264(_sps.data(), _sps.size(), pkt->timeStamp , pkt->timeStamp);
onGetH264(_pps.data(), _pps.size(), pkt->timeStamp , pkt->timeStamp);
return false; return false;
} }
@ -69,44 +71,13 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) {
if(iFrameLen + iOffset > iTotalLen){ if(iFrameLen + iOffset > iTotalLen){
break; break;
} }
onGetH264_l(pkt->strBuf.data() + iOffset, iFrameLen, pkt->timeStamp , pts); onGetH264(pkt->strBuf.data() + iOffset, iFrameLen, pkt->timeStamp , pts);
iOffset += iFrameLen; iOffset += iFrameLen;
} }
} }
return pkt->isVideoKeyFrame(); return pkt->isVideoKeyFrame();
} }
inline void H264RtmpDecoder::onGetH264_l(const char* pcData, int iLen, uint32_t dts,uint32_t pts) {
switch (H264_TYPE(pcData[0])) {
case H264Frame::NAL_IDR: {
//I frame
if(_sps.length()){
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: {
//I or P or B frame
onGetH264(pcData, iLen, dts , pts);
}
break;
case H264Frame::NAL_SPS: {
_sps.assign(pcData, iLen);
}
break;
case H264Frame::NAL_PPS:{
_pps.assign(pcData, iLen);
}
break;
default:
break;
}
}
inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dts,uint32_t pts) { inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dts,uint32_t pts) {
#if 1 #if 1
_h264frame->type = H264_TYPE(pcData[0]); _h264frame->type = H264_TYPE(pcData[0]);

View File

@ -60,7 +60,6 @@ public:
} }
protected: protected:
bool decodeRtmp(const RtmpPacket::Ptr &Rtmp); bool decodeRtmp(const RtmpPacket::Ptr &Rtmp);
void onGetH264_l(const char *pcData, int iLen, uint32_t dts,uint32_t pts);
void onGetH264(const char *pcData, int iLen, uint32_t dts,uint32_t pts); void onGetH264(const char *pcData, int iLen, uint32_t dts,uint32_t pts);
H264Frame::Ptr obtainFrame(); H264Frame::Ptr obtainFrame();
protected: protected:

View File

@ -245,14 +245,9 @@ protected:
_playResultCB = nullptr; _playResultCB = nullptr;
return; return;
} }
//播放成功后我们还必须等待各个Track初始化完毕才能回调告知已经初始化完毕 //播放成功
if(isInited(0xFFFF)){ _playResultCB(ex);
//初始化完毕则立即回调 _playResultCB = nullptr;
_playResultCB(ex);
_playResultCB = nullptr;
return;
}
//播放成功却未初始化完毕,这个时候不回调汇报播放成功
} }
void onResume() override{ void onResume() override{
@ -260,16 +255,6 @@ protected:
_resumeCB(); _resumeCB();
} }
} }
void checkInited(int analysisMs){
if(!_playResultCB){
return;
}
if(isInited(analysisMs)){
_playResultCB(SockException(Err_success,"play success"));
_playResultCB = nullptr;
}
}
protected: protected:
function<void(const SockException &ex)> _shutdownCB; function<void(const SockException &ex)> _shutdownCB;
function<void(const SockException &ex)> _playResultCB; function<void(const SockException &ex)> _playResultCB;

View File

@ -321,7 +321,6 @@ 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_l(SockException(Err_success,"play rtmp success"));
} }
void RtmpPlayer::onStreamDry(uint32_t ui32StreamId) { void RtmpPlayer::onStreamDry(uint32_t ui32StreamId) {
@ -329,6 +328,25 @@ void RtmpPlayer::onStreamDry(uint32_t ui32StreamId) {
onPlayResult_l(SockException(Err_other,"rtmp stream dry")); onPlayResult_l(SockException(Err_other,"rtmp stream dry"));
} }
void RtmpPlayer::onMediaData_l(const RtmpPacket::Ptr &packet) {
_mediaTicker.resetTime();
if(!_pPlayTimer){
//已经触发了onPlayResult事件直接触发onMediaData事件
onMediaData(packet);
return;
}
if(packet->isCfgFrame()){
//输入配置帧以便初始化完成各个track
onMediaData(packet);
}else{
//先触发onPlayResult事件这个时候解码器才能初始化完毕
onPlayResult_l(SockException(Err_success,"play rtmp success"));
//触发onPlayResult事件后再把帧数据输入到解码器
onMediaData(packet);
}
}
void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) { void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
switch (chunkData.typeId) { switch (chunkData.typeId) {
@ -351,6 +369,7 @@ void RtmpPlayer::onRtmpChunk(RtmpPacket &chunkData) {
case MSG_VIDEO: { case MSG_VIDEO: {
auto idx = chunkData.typeId%2; auto idx = chunkData.typeId%2;
if (_aNowStampTicker[idx].elapsedTime() > 500) { if (_aNowStampTicker[idx].elapsedTime() > 500) {
//计算播放进度时间轴用
_aiNowStamp[idx] = chunkData.timeStamp; _aiNowStamp[idx] = chunkData.timeStamp;
} }
onMediaData_l(std::make_shared<RtmpPacket>(std::move(chunkData))); onMediaData_l(std::make_shared<RtmpPacket>(std::move(chunkData)));

View File

@ -60,11 +60,7 @@ protected:
uint32_t getProgressMilliSecond() const; uint32_t getProgressMilliSecond() const;
void seekToMilliSecond(uint32_t ms); void seekToMilliSecond(uint32_t ms);
protected: protected:
void onMediaData_l(const RtmpPacket::Ptr &chunkData) { void onMediaData_l(const RtmpPacket::Ptr &chunkData);
_mediaTicker.resetTime();
onMediaData(chunkData);
}
void onPlayResult_l(const SockException &ex); void onPlayResult_l(const SockException &ex);
//for Tcpclient //for Tcpclient
@ -97,7 +93,7 @@ protected:
inline void send_createStream(); inline void send_createStream();
inline void send_play(); inline void send_play();
inline void send_pause(bool bPause); inline void send_pause(bool bPause);
private:
string _strApp; string _strApp;
string _strStream; string _strStream;
string _strTcUrl; string _strTcUrl;

View File

@ -58,7 +58,6 @@ public:
seekToMilliSecond(fProgress * getDuration() * 1000); seekToMilliSecond(fProgress * getDuration() * 1000);
}; };
void play(const string &strUrl) override { void play(const string &strUrl) override {
_analysisMs = (*this)[kMaxAnalysisMS].as<int>();
PlayerImp<RtmpPlayer,RtmpDemuxer>::play(strUrl); PlayerImp<RtmpPlayer,RtmpDemuxer>::play(strUrl);
} }
private: private:
@ -76,16 +75,13 @@ private:
_pRtmpMediaSrc->onWrite(chunkData); _pRtmpMediaSrc->onWrite(chunkData);
} }
if(!_parser){ if(!_parser){
//这个流没有metedata,那么尝试在音视频包里面还原出相关信息 //这个流没有metedata
_parser.reset(new RtmpDemuxer()); _parser.reset(new RtmpDemuxer());
onPlayResult_l(SockException(Err_success,"play rtmp success"));
} }
_parser->inputRtmp(chunkData); _parser->inputRtmp(chunkData);
checkInited(_analysisMs);
} }
private: private:
RtmpMediaSource::Ptr _pRtmpMediaSrc; RtmpMediaSource::Ptr _pRtmpMediaSrc;
int _analysisMs;
}; };