Commit 283188be by ziyue

MP4Demuxer: 提高MP4解复用器接口灵活度

parent 5bffc985
...@@ -15,23 +15,27 @@ ...@@ -15,23 +15,27 @@
using namespace toolkit; using namespace toolkit;
namespace mediakit { namespace mediakit {
MP4Reader::MP4Reader(const string &strVhost,const string &strApp, const string &strId,const string &filePath ) { MP4Reader::MP4Reader(const string &vhost, const string &app, const string &stream_id, const string &file_path) {
_poller = WorkThreadPool::Instance().getPoller(); _poller = WorkThreadPool::Instance().getPoller();
_file_path = filePath; _file_path = file_path;
if(_file_path.empty()){ if (_file_path.empty()) {
GET_CONFIG(string,recordPath,Record::kFilePath); GET_CONFIG(string, recordPath, Record::kFilePath);
GET_CONFIG(bool,enableVhost,General::kEnableVhost); GET_CONFIG(bool, enableVhost, General::kEnableVhost);
if(enableVhost){ if (enableVhost) {
_file_path = strVhost + "/" + strApp + "/" + strId; _file_path = vhost + "/" + app + "/" + stream_id;
}else{ } else {
_file_path = strApp + "/" + strId; _file_path = app + "/" + stream_id;
} }
_file_path = File::absolutePath(_file_path,recordPath); _file_path = File::absolutePath(_file_path, recordPath);
} }
_demuxer = std::make_shared<MP4Demuxer>(); _demuxer = std::make_shared<MP4Demuxer>();
_demuxer->openMP4(_file_path); _demuxer->openMP4(_file_path);
_muxer = std::make_shared<MultiMediaSourceMuxer>(strVhost, strApp, strId, _demuxer->getDurationMS() / 1000.0f, true, true, false, false);
if (stream_id.empty()) {
return;
}
_muxer = std::make_shared<MultiMediaSourceMuxer>(vhost, app, stream_id, _demuxer->getDurationMS() / 1000.0f, true, true, false, false);
auto tracks = _demuxer->getTracks(false); auto tracks = _demuxer->getTracks(false);
if(tracks.empty()){ if(tracks.empty()){
throw std::runtime_error(StrPrinter << "该mp4文件没有有效的track:" << _file_path); throw std::runtime_error(StrPrinter << "该mp4文件没有有效的track:" << _file_path);
...@@ -60,14 +64,16 @@ bool MP4Reader::readSample() { ...@@ -60,14 +64,16 @@ bool MP4Reader::readSample() {
if (!frame) { if (!frame) {
continue; continue;
} }
_muxer->inputFrame(frame); if (_muxer) {
_muxer->inputFrame(frame);
}
if (frame->dts() > getCurrentStamp()) { if (frame->dts() > getCurrentStamp()) {
break; break;
} }
} }
GET_CONFIG(bool, fileRepeat, Record::kFileRepeat); GET_CONFIG(bool, fileRepeat, Record::kFileRepeat);
if (eof && fileRepeat) { if (eof && (fileRepeat || _file_repeat)) {
//需要从头开始看 //需要从头开始看
seekTo(0); seekTo(0);
return true; return true;
...@@ -76,10 +82,14 @@ bool MP4Reader::readSample() { ...@@ -76,10 +82,14 @@ bool MP4Reader::readSample() {
return !eof; return !eof;
} }
void MP4Reader::startReadMP4() { void MP4Reader::stopReadMP4() {
_timer = nullptr;
}
void MP4Reader::startReadMP4(const EventPoller::Ptr &poller, uint64_t sample_ms, bool ref_self, bool file_repeat) {
GET_CONFIG(uint32_t, sampleMS, Record::kSampleMS); GET_CONFIG(uint32_t, sampleMS, Record::kSampleMS);
auto strongSelf = shared_from_this(); auto strongSelf = shared_from_this();
_muxer->setMediaListener(strongSelf); if (_muxer) { _muxer->setMediaListener(strongSelf); }
//先获取关键帧 //先获取关键帧
seekTo(0); seekTo(0);
...@@ -88,10 +98,28 @@ void MP4Reader::startReadMP4() { ...@@ -88,10 +98,28 @@ void MP4Reader::startReadMP4() {
readSample(); readSample();
//启动定时器 //启动定时器
_timer = std::make_shared<Timer>(sampleMS / 1000.0f, [strongSelf]() { if (ref_self) {
lock_guard<recursive_mutex> lck(strongSelf->_mtx); _timer = std::make_shared<Timer>((sample_ms ? sample_ms : sampleMS) / 1000.0f, [strongSelf]() {
return strongSelf->readSample(); lock_guard<recursive_mutex> lck(strongSelf->_mtx);
}, _poller); return strongSelf->readSample();
}, poller ? poller : _poller);
} else {
weak_ptr<MP4Reader> weak_self = strongSelf;
_timer = std::make_shared<Timer>((sample_ms ? sample_ms : sampleMS) / 1000.0f, [weak_self]() {
auto strongSelf = weak_self.lock();
if (!strongSelf) {
return false;
}
lock_guard<recursive_mutex> lck(strongSelf->_mtx);
return strongSelf->readSample();
}, poller ? poller : _poller);
}
_file_repeat = file_repeat;
}
const MP4Demuxer::Ptr &MP4Reader::getDemuxer() const {
return _demuxer;
} }
uint32_t MP4Reader::getCurrentStamp() { uint32_t MP4Reader::getCurrentStamp() {
...@@ -102,7 +130,7 @@ void MP4Reader::setCurrentStamp(uint32_t new_stamp){ ...@@ -102,7 +130,7 @@ void MP4Reader::setCurrentStamp(uint32_t new_stamp){
auto old_stamp = getCurrentStamp(); auto old_stamp = getCurrentStamp();
_seek_to = new_stamp; _seek_to = new_stamp;
_seek_ticker.resetTime(); _seek_ticker.resetTime();
if (old_stamp != new_stamp) { if (old_stamp != new_stamp && _muxer) {
//时间轴未拖动时不操作 //时间轴未拖动时不操作
_muxer->setTimeStamp(new_stamp); _muxer->setTimeStamp(new_stamp);
} }
...@@ -170,7 +198,9 @@ bool MP4Reader::seekTo(uint32_t ui32Stamp) { ...@@ -170,7 +198,9 @@ bool MP4Reader::seekTo(uint32_t ui32Stamp) {
} }
if(keyFrame || frame->keyFrame() || frame->configFrame()){ if(keyFrame || frame->keyFrame() || frame->configFrame()){
//定位到key帧 //定位到key帧
_muxer->inputFrame(frame); if (_muxer) {
_muxer->inputFrame(frame);
}
//设置当前时间戳 //设置当前时间戳
setCurrentStamp(frame->dts()); setCurrentStamp(frame->dts());
return true; return true;
......
...@@ -23,18 +23,21 @@ public: ...@@ -23,18 +23,21 @@ public:
/** /**
* 流化一个mp4文件,使之转换成RtspMediaSource和RtmpMediaSource * 流化一个mp4文件,使之转换成RtspMediaSource和RtmpMediaSource
* @param strVhost 虚拟主机 * @param vhost 虚拟主机
* @param strApp 应用名 * @param app 应用名
* @param strId 流id * @param stream_id 流id
* @param filePath 文件路径,如果为空则根据配置文件和上面参数自动生成,否则使用指定的文件 * @param file_path 文件路径,如果为空则根据配置文件和上面参数自动生成,否则使用指定的文件
*/ */
MP4Reader(const string &strVhost,const string &strApp, const string &strId,const string &filePath = ""); MP4Reader(const string &vhost, const string &app, const string &stream_id, const string &file_path = "");
/** /**
* 开始流化MP4文件,需要指出的是,MP4Reader对象一经过调用startReadMP4方法,它的强引用会自持有, * 开始流化MP4文件,需要指出的是,MP4Reader对象一经过调用startReadMP4方法,它的强引用会自持有,
* 意思是在文件流化结束之前或中断之前,MP4Reader对象是不会被销毁的(不管有没有被外部对象持有) * 意思是在文件流化结束之前或中断之前,MP4Reader对象是不会被销毁的(不管有没有被外部对象持有)
*/ */
void startReadMP4(); void startReadMP4(const EventPoller::Ptr &poller = nullptr, uint64_t sample_ms = 0, bool ref_self = true, bool file_repeat = false);
void stopReadMP4();
const MP4Demuxer::Ptr& getDemuxer() const;
private: private:
//MediaSourceEvent override //MediaSourceEvent override
...@@ -53,6 +56,7 @@ private: ...@@ -53,6 +56,7 @@ private:
bool seekTo(uint32_t ui32Stamp); bool seekTo(uint32_t ui32Stamp);
private: private:
bool _file_repeat = false;
bool _have_video = false; bool _have_video = false;
bool _paused = false; bool _paused = false;
float _speed = 1.0; float _speed = 1.0;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论