完善mp4点播

This commit is contained in:
xiongziliang 2020-04-03 22:04:13 +08:00
parent 278591d5ee
commit 47d8e37e3d
4 changed files with 28 additions and 40 deletions

View File

@ -158,7 +158,7 @@ struct Context{
BufferRaw::Ptr buffer; BufferRaw::Ptr buffer;
}; };
Frame::Ptr MP4Demuxer::readFrame(bool &keyFrame, bool &eof) { Frame::Ptr MP4Demuxer::readFrame(bool &keyFrame) {
static mov_reader_onread mov_reader_onread = [](void *param, uint32_t track_id, const void *buffer, size_t bytes, int64_t pts, int64_t dts, int flags) { static mov_reader_onread mov_reader_onread = [](void *param, uint32_t track_id, const void *buffer, size_t bytes, int64_t pts, int64_t dts, int flags) {
Context *ctx = (Context *) param; Context *ctx = (Context *) param;
ctx->pts = pts; ctx->pts = pts;
@ -178,25 +178,19 @@ Frame::Ptr MP4Demuxer::readFrame(bool &keyFrame, bool &eof) {
Context ctx = {this, 0}; Context ctx = {this, 0};
auto ret = mov_reader_read2(_mov_reader.get(), mov_onalloc, mov_reader_onread, &ctx); auto ret = mov_reader_read2(_mov_reader.get(), mov_onalloc, mov_reader_onread, &ctx);
switch (ret) { switch (ret) {
case 0 : { case 0 :
eof = true; return nullptr;
WarnL << "读取mp4文件完毕";
}
break;
case 1 : { case 1 : {
keyFrame = ctx.flags & MOV_AV_FLAG_KEYFREAME; keyFrame = ctx.flags & MOV_AV_FLAG_KEYFREAME;
return makeFrame(ctx.track_id, ctx.buffer, ctx.pts, ctx.dts); return makeFrame(ctx.track_id, ctx.buffer, ctx.pts, ctx.dts);
} }
break;
default: default:
eof = true;
WarnL << "读取mp4文件数据失败:" << ret; WarnL << "读取mp4文件数据失败:" << ret;
break;
}
return nullptr; return nullptr;
} }
}
template <typename Parent> template <typename Parent>
class FrameWrapper : public Parent{ class FrameWrapper : public Parent{

View File

@ -38,7 +38,7 @@ public:
MP4Demuxer(const char *file); MP4Demuxer(const char *file);
~MP4Demuxer() override; ~MP4Demuxer() override;
int64_t seekTo(int64_t stamp_ms); int64_t seekTo(int64_t stamp_ms);
Frame::Ptr readFrame(bool &keyFrame, bool &eof); Frame::Ptr readFrame(bool &keyFrame);
vector<Track::Ptr> getTracks(bool trackReady) const override ; vector<Track::Ptr> getTracks(bool trackReady) const override ;
uint64_t getDurationMS() const; uint64_t getDurationMS() const;
private: private:

View File

@ -62,32 +62,27 @@ MP4Reader::MP4Reader(const string &strVhost,const string &strApp, const string &
} }
bool MP4Reader::readSample() { bool MP4Reader::readSample() {
bool eof = false;
bool keyFrame = false; bool keyFrame = false;
while (!eof) { bool eof = false;
auto frame = _demuxer->readFrame(keyFrame, eof); while (true) {
auto frame = _demuxer->readFrame(keyFrame);
if (!frame) { if (!frame) {
eof = true;
break; break;
} }
_mediaMuxer->inputFrame(frame); _mediaMuxer->inputFrame(frame);
if (frame->dts() > nextStampForStop()) { if (frame->dts() > getCurrentStamp()) {
break; break;
} }
} }
if(!eof && _mediaMuxer->totalReaderCount() > 0){
//文件未看完且观看者大于0个
_alive.resetTime();
}
//重头开始循环读取
GET_CONFIG(bool, fileRepeat, Record::kFileRepeat); GET_CONFIG(bool, fileRepeat, Record::kFileRepeat);
if (eof && fileRepeat) { if (eof && fileRepeat) {
//文件看完了,且需要从头开始看 //需要从头开始看
seekTo(0); seekTo(0);
} }
//读取mp4完毕后10秒才销毁对象
return _alive.elapsedTime() < 10 * 1000; return !eof;
} }
void MP4Reader::startReadMP4() { void MP4Reader::startReadMP4() {
@ -97,9 +92,8 @@ void MP4Reader::startReadMP4() {
//先获取关键帧 //先获取关键帧
seekTo(0); seekTo(0);
//设置下次读取停止事件
setNextStampForStop(_seek_to + sampleMS);
//读sampleMS毫秒的数据用于产生MediaSource //读sampleMS毫秒的数据用于产生MediaSource
setCurrentStamp(getCurrentStamp() + sampleMS);
readSample(); readSample();
//启动定时器 //启动定时器
@ -109,14 +103,14 @@ void MP4Reader::startReadMP4() {
}, _poller); }, _poller);
} }
uint32_t MP4Reader::nextStampForStop() { uint32_t MP4Reader::getCurrentStamp() {
return _seek_to + _seek_ticker.elapsedTime(); return _seek_to + _seek_ticker.elapsedTime();
} }
void MP4Reader::setNextStampForStop(uint32_t ui32Stamp){ void MP4Reader::setCurrentStamp(uint32_t ui32Stamp){
_seek_to = ui32Stamp; _seek_to = ui32Stamp;
_seek_ticker.resetTime(); _seek_ticker.resetTime();
_alive.resetTime(); _mediaMuxer->setTimeStamp(ui32Stamp);
} }
bool MP4Reader::seekTo(MediaSource &sender,uint32_t ui32Stamp){ bool MP4Reader::seekTo(MediaSource &sender,uint32_t ui32Stamp){
@ -134,26 +128,27 @@ bool MP4Reader::seekTo(uint32_t ui32Stamp){
//seek失败 //seek失败
return false; return false;
} }
InfoL << stamp;
//设置当前时间戳
setNextStampForStop(stamp);
if(!_have_video){ if(!_have_video){
//没有视频,不需要搜索关键帧 //没有视频,不需要搜索关键帧
//设置当前时间戳
setCurrentStamp(stamp);
return true; return true;
} }
//搜索到下一帧关键帧 //搜索到下一帧关键帧
bool eof = false; bool eof = false;
bool keyFrame = false; bool keyFrame = false;
while (!eof) { while (!eof) {
auto frame = _demuxer->readFrame(keyFrame, eof); auto frame = _demuxer->readFrame(keyFrame);
if(!frame){ if(!frame){
eof = true;
break; break;
} }
if(keyFrame || frame->keyFrame() || frame->configFrame()){ if(keyFrame || frame->keyFrame() || frame->configFrame()){
//定位到key帧 //定位到key帧
_mediaMuxer->inputFrame(frame); _mediaMuxer->inputFrame(frame);
setNextStampForStop(frame->dts()); //设置当前时间戳
setCurrentStamp(frame->dts());
return true; return true;
} }
} }

View File

@ -58,15 +58,14 @@ private:
int totalReaderCount(MediaSource &sender) override; int totalReaderCount(MediaSource &sender) override;
bool readSample(); bool readSample();
uint32_t nextStampForStop(); uint32_t getCurrentStamp();
void setNextStampForStop(uint32_t ui32Stamp); void setCurrentStamp(uint32_t ui32Stamp);
bool seekTo(uint32_t ui32Stamp); bool seekTo(uint32_t ui32Stamp);
private: private:
recursive_mutex _mtx; recursive_mutex _mtx;
MultiMediaSourceMuxer::Ptr _mediaMuxer; MultiMediaSourceMuxer::Ptr _mediaMuxer;
uint32_t _seek_to; uint32_t _seek_to;
Ticker _seek_ticker; Ticker _seek_ticker;
Ticker _alive;
Timer::Ptr _timer; Timer::Ptr _timer;
EventPoller::Ptr _poller; EventPoller::Ptr _poller;
MP4Demuxer::Ptr _demuxer; MP4Demuxer::Ptr _demuxer;