mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
修改Rtmp播放结果回调事件触发机制,防止秒开失败以及获取Track失败
This commit is contained in:
parent
fcdcf12af9
commit
2e95c3b2fa
@ -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]);
|
||||||
|
@ -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:
|
||||||
|
@ -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;
|
||||||
|
@ -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)));
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user