mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-31 08:39:34 +08:00
提炼MP4相关接口和代码
This commit is contained in:
parent
2dd1046131
commit
071d0a9fd1
@ -18,6 +18,8 @@
|
|||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////mp4_writer_t/////////////////////////////////////////////////
|
||||||
|
|
||||||
struct mp4_writer_t {
|
struct mp4_writer_t {
|
||||||
int is_fmp4;
|
int is_fmp4;
|
||||||
union {
|
union {
|
||||||
@ -102,28 +104,32 @@ int mp4_writer_init_segment(mp4_writer_t* mp4){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////MP4FileIO/////////////////////////////////////////////////
|
||||||
|
|
||||||
static struct mov_buffer_t s_io = {
|
static struct mov_buffer_t s_io = {
|
||||||
[](void *ctx, void *data, uint64_t bytes) {
|
[](void *ctx, void *data, uint64_t bytes) {
|
||||||
MP4File *thiz = (MP4File *) ctx;
|
MP4FileIO *thiz = (MP4FileIO *) ctx;
|
||||||
return thiz->onRead(data, bytes);
|
return thiz->onRead(data, bytes);
|
||||||
},
|
},
|
||||||
[](void *ctx, const void *data, uint64_t bytes) {
|
[](void *ctx, const void *data, uint64_t bytes) {
|
||||||
MP4File *thiz = (MP4File *) ctx;
|
MP4FileIO *thiz = (MP4FileIO *) ctx;
|
||||||
return thiz->onWrite(data, bytes);
|
return thiz->onWrite(data, bytes);
|
||||||
},
|
},
|
||||||
[](void *ctx, uint64_t offset) {
|
[](void *ctx, uint64_t offset) {
|
||||||
MP4File *thiz = (MP4File *) ctx;
|
MP4FileIO *thiz = (MP4FileIO *) ctx;
|
||||||
return thiz->onSeek(offset);
|
return thiz->onSeek(offset);
|
||||||
},
|
},
|
||||||
[](void *ctx) {
|
[](void *ctx) {
|
||||||
MP4File *thiz = (MP4File *) ctx;
|
MP4FileIO *thiz = (MP4FileIO *) ctx;
|
||||||
return thiz->onTell();
|
return thiz->onTell();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MP4File::Writer MP4File::createWriter(int flags, bool is_fmp4){
|
MP4FileIO::Writer MP4FileIO::createWriter(int flags, bool is_fmp4){
|
||||||
Writer writer;
|
Writer writer;
|
||||||
writer.reset(mp4_writer_create(is_fmp4, &s_io,this, flags),[](mp4_writer_t *ptr){
|
Ptr self = shared_from_this();
|
||||||
|
//保存自己的强引用,防止提前释放
|
||||||
|
writer.reset(mp4_writer_create(is_fmp4, &s_io,this, flags),[self](mp4_writer_t *ptr){
|
||||||
if(ptr){
|
if(ptr){
|
||||||
mp4_writer_destroy(ptr);
|
mp4_writer_destroy(ptr);
|
||||||
}
|
}
|
||||||
@ -134,9 +140,11 @@ MP4File::Writer MP4File::createWriter(int flags, bool is_fmp4){
|
|||||||
return writer;
|
return writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
MP4File::Reader MP4File::createReader(){
|
MP4FileIO::Reader MP4FileIO::createReader(){
|
||||||
Reader reader;
|
Reader reader;
|
||||||
reader.reset(mov_reader_create(&s_io,this),[](mov_reader_t *ptr){
|
Ptr self = shared_from_this();
|
||||||
|
//保存自己的强引用,防止提前释放
|
||||||
|
reader.reset(mov_reader_create(&s_io,this),[self](mov_reader_t *ptr){
|
||||||
if(ptr){
|
if(ptr){
|
||||||
mov_reader_destroy(ptr);
|
mov_reader_destroy(ptr);
|
||||||
}
|
}
|
||||||
@ -147,15 +155,17 @@ MP4File::Reader MP4File::createReader(){
|
|||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////MP4FileDisk/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
#define fseek64 _fseeki64
|
#define fseek64 _fseeki64
|
||||||
#define ftell64 _ftelli64
|
#define ftell64 _ftelli64
|
||||||
#else
|
#else
|
||||||
#define fseek64 fseek
|
#define fseek64 fseek
|
||||||
#define ftell64 ftell
|
#define ftell64 ftell
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void MP4File::openFile(const char *file,const char *mode) {
|
void MP4FileDisk::openFile(const char *file, const char *mode) {
|
||||||
//创建文件
|
//创建文件
|
||||||
auto fp = File::create_file(file, mode);
|
auto fp = File::create_file(file, mode);
|
||||||
if(!fp){
|
if(!fp){
|
||||||
@ -183,26 +193,26 @@ void MP4File::openFile(const char *file,const char *mode) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP4File::closeFile() {
|
void MP4FileDisk::closeFile() {
|
||||||
_file = nullptr;
|
_file = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MP4File::onRead(void *data, uint64_t bytes) {
|
int MP4FileDisk::onRead(void *data, uint64_t bytes) {
|
||||||
if (bytes == fread(data, 1, bytes, _file.get())){
|
if (bytes == fread(data, 1, bytes, _file.get())){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 0 != ferror(_file.get()) ? ferror(_file.get()) : -1 /*EOF*/;
|
return 0 != ferror(_file.get()) ? ferror(_file.get()) : -1 /*EOF*/;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MP4File::onWrite(const void *data, uint64_t bytes) {
|
int MP4FileDisk::onWrite(const void *data, uint64_t bytes) {
|
||||||
return bytes == fwrite(data, 1, bytes, _file.get()) ? 0 : ferror(_file.get());
|
return bytes == fwrite(data, 1, bytes, _file.get()) ? 0 : ferror(_file.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
int MP4File::onSeek(uint64_t offset) {
|
int MP4FileDisk::onSeek(uint64_t offset) {
|
||||||
return fseek64(_file.get(), offset, SEEK_SET);
|
return fseek64(_file.get(), offset, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t MP4File::onTell() {
|
uint64_t MP4FileDisk::onTell() {
|
||||||
return ftell64(_file.get());
|
return ftell64(_file.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
|
//以下是fmp4/mov的通用接口,简单包装了ireader/media-server的接口
|
||||||
typedef struct mp4_writer_t mp4_writer_t;
|
typedef struct mp4_writer_t mp4_writer_t;
|
||||||
mp4_writer_t* mp4_writer_create(int is_fmp4, const struct mov_buffer_t *buffer, void* param, int flags);
|
mp4_writer_t* mp4_writer_create(int is_fmp4, const struct mov_buffer_t *buffer, void* param, int flags);
|
||||||
void mp4_writer_destroy(mp4_writer_t* mp4);
|
void mp4_writer_destroy(mp4_writer_t* mp4);
|
||||||
@ -34,23 +35,84 @@ int mp4_writer_write_l(mp4_writer_t* mp4, int track, const void* data, size_t by
|
|||||||
int mp4_writer_save_segment(mp4_writer_t* mp4);
|
int mp4_writer_save_segment(mp4_writer_t* mp4);
|
||||||
int mp4_writer_init_segment(mp4_writer_t* mp4);
|
int mp4_writer_init_segment(mp4_writer_t* mp4);
|
||||||
|
|
||||||
class MP4File {
|
//mp4文件IO的抽象接口类
|
||||||
|
class MP4FileIO : public std::enable_shared_from_this<MP4FileIO> {
|
||||||
public:
|
public:
|
||||||
friend struct mov_buffer_t;
|
using Ptr = std::shared_ptr<MP4FileIO>;
|
||||||
typedef std::shared_ptr<mp4_writer_t> Writer;
|
using Writer = std::shared_ptr<mp4_writer_t>;
|
||||||
typedef std::shared_ptr<mov_reader_t> Reader;
|
using Reader = std::shared_ptr<mov_reader_t>;
|
||||||
MP4File() = default;
|
|
||||||
virtual ~MP4File() = default;
|
|
||||||
|
|
||||||
Writer createWriter(int flags, bool is_fmp4 = false);
|
MP4FileIO() = default;
|
||||||
Reader createReader();
|
virtual ~MP4FileIO() = default;
|
||||||
void openFile(const char *file,const char *mode);
|
|
||||||
|
/**
|
||||||
|
* 创建mp4复用器
|
||||||
|
* @param flags 支持0、MOV_FLAG_FASTSTART、MOV_FLAG_SEGMENT
|
||||||
|
* @param is_fmp4 是否为fmp4还是普通mp4
|
||||||
|
* @return mp4复用器
|
||||||
|
*/
|
||||||
|
virtual Writer createWriter(int flags, bool is_fmp4 = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建mp4解复用器
|
||||||
|
* @return mp4解复用器
|
||||||
|
*/
|
||||||
|
virtual Reader createReader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件读写位置
|
||||||
|
*/
|
||||||
|
virtual uint64_t onTell() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* seek至文件某处
|
||||||
|
* @param offset 文件偏移量
|
||||||
|
* @return 是否成功(0成功)
|
||||||
|
*/
|
||||||
|
virtual int onSeek(uint64_t offset) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从文件读取一定数据
|
||||||
|
* @param data 数据存放指针
|
||||||
|
* @param bytes 指针长度
|
||||||
|
* @return 是否成功(0成功)
|
||||||
|
*/
|
||||||
|
virtual int onRead(void *data, uint64_t bytes) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写入文件一定数据
|
||||||
|
* @param data 数据指针
|
||||||
|
* @param bytes 数据长度
|
||||||
|
* @return 是否成功(0成功)
|
||||||
|
*/
|
||||||
|
virtual int onWrite(const void *data, uint64_t bytes) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
//磁盘MP4文件类
|
||||||
|
class MP4FileDisk : public MP4FileIO {
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<MP4FileDisk>;
|
||||||
|
MP4FileDisk() = default;
|
||||||
|
~MP4FileDisk() override = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开磁盘文件
|
||||||
|
* @param file 文件路径
|
||||||
|
* @param mode fopen的方式
|
||||||
|
*/
|
||||||
|
void openFile(const char *file, const char *mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭磁盘文件
|
||||||
|
*/
|
||||||
void closeFile();
|
void closeFile();
|
||||||
|
|
||||||
int onRead(void* data, uint64_t bytes);
|
protected:
|
||||||
int onWrite(const void* data, uint64_t bytes);
|
uint64_t onTell() override;
|
||||||
int onSeek( uint64_t offset);
|
int onSeek(uint64_t offset) override;
|
||||||
uint64_t onTell();
|
int onRead(void *data, uint64_t bytes) override;
|
||||||
|
int onWrite(const void *data, uint64_t bytes) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<FILE> _file;
|
std::shared_ptr<FILE> _file;
|
||||||
};
|
};
|
||||||
|
@ -19,18 +19,20 @@
|
|||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
MP4Demuxer::MP4Demuxer(const char *file) {
|
MP4Demuxer::MP4Demuxer() {}
|
||||||
openFile(file,"rb+");
|
|
||||||
_mov_reader = createReader();
|
|
||||||
getAllTracks();
|
|
||||||
_duration_ms = mov_reader_getduration(_mov_reader.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
MP4Demuxer::~MP4Demuxer() {
|
MP4Demuxer::~MP4Demuxer() {
|
||||||
_mov_reader = nullptr;
|
_mov_reader = nullptr;
|
||||||
closeFile();
|
closeFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MP4Demuxer::openMP4(const string &file){
|
||||||
|
openFile(file.data(),"rb+");
|
||||||
|
_mov_reader = createReader();
|
||||||
|
getAllTracks();
|
||||||
|
_duration_ms = mov_reader_getduration(_mov_reader.get());
|
||||||
|
}
|
||||||
|
|
||||||
int MP4Demuxer::getAllTracks() {
|
int MP4Demuxer::getAllTracks() {
|
||||||
static mov_reader_trackinfo_t s_on_track = {
|
static mov_reader_trackinfo_t s_on_track = {
|
||||||
[](void *param, uint32_t track, uint8_t object, int width, int height, const void *extra, size_t bytes) {
|
[](void *param, uint32_t track, uint8_t object, int width, int height, const void *extra, size_t bytes) {
|
||||||
|
@ -16,24 +16,60 @@
|
|||||||
#include "Util/ResourcePool.h"
|
#include "Util/ResourcePool.h"
|
||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
class MP4Demuxer : public MP4File, public TrackSource{
|
class MP4Demuxer : public MP4FileDisk, public TrackSource{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<MP4Demuxer> Ptr;
|
typedef std::shared_ptr<MP4Demuxer> Ptr;
|
||||||
MP4Demuxer(const char *file);
|
|
||||||
|
/**
|
||||||
|
* 创建mp4解复用器
|
||||||
|
*/
|
||||||
|
MP4Demuxer();
|
||||||
~MP4Demuxer() override;
|
~MP4Demuxer() override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开文件
|
||||||
|
* @param file mp4文件路径
|
||||||
|
*/
|
||||||
|
void openMP4(const string &file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动时间轴至某处
|
||||||
|
* @param stamp_ms 预期的时间轴位置,单位毫秒
|
||||||
|
* @return 时间轴位置
|
||||||
|
*/
|
||||||
int64_t seekTo(int64_t stamp_ms);
|
int64_t seekTo(int64_t stamp_ms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取一帧数据
|
||||||
|
* @param keyFrame 是否为关键帧
|
||||||
|
* @param eof 是否文件读取完毕
|
||||||
|
* @return 帧数据,可能为空
|
||||||
|
*/
|
||||||
Frame::Ptr readFrame(bool &keyFrame, bool &eof);
|
Frame::Ptr readFrame(bool &keyFrame, bool &eof);
|
||||||
vector<Track::Ptr> getTracks(bool trackReady) const override ;
|
|
||||||
|
/**
|
||||||
|
* 获取所有Track信息
|
||||||
|
* @param trackReady 是否要求track为就绪状态
|
||||||
|
* @return 所有Track
|
||||||
|
*/
|
||||||
|
vector<Track::Ptr> getTracks(bool trackReady) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件长度
|
||||||
|
* @return 文件长度,单位毫秒
|
||||||
|
*/
|
||||||
uint64_t getDurationMS() const;
|
uint64_t getDurationMS() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int getAllTracks();
|
int getAllTracks();
|
||||||
void onVideoTrack(uint32_t track_id, uint8_t object, int width, int height, const void* extra, size_t bytes);
|
void onVideoTrack(uint32_t track_id, uint8_t object, int width, int height, const void *extra, size_t bytes);
|
||||||
void onAudioTrack(uint32_t track_id, uint8_t object, int channel_count, int bit_per_sample, int sample_rate, const void* extra, size_t bytes);
|
void onAudioTrack(uint32_t track_id, uint8_t object, int channel_count, int bit_per_sample, int sample_rate, const void *extra, size_t bytes);
|
||||||
Frame::Ptr makeFrame(uint32_t track_id, const Buffer::Ptr &buf,int64_t pts, int64_t dts);
|
Frame::Ptr makeFrame(uint32_t track_id, const Buffer::Ptr &buf, int64_t pts, int64_t dts);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MP4File::Reader _mov_reader;
|
Reader _mov_reader;
|
||||||
uint64_t _duration_ms = 0;
|
uint64_t _duration_ms = 0;
|
||||||
map<int, Track::Ptr > _track_to_codec;
|
map<int, Track::Ptr> _track_to_codec;
|
||||||
ResourcePool<BufferRaw> _buffer_pool;
|
ResourcePool<BufferRaw> _buffer_pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,21 +14,20 @@
|
|||||||
#include "Extension/H264.h"
|
#include "Extension/H264.h"
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
MP4Muxer::MP4Muxer(const char *file) {
|
MP4Muxer::MP4Muxer() {}
|
||||||
_file_name = file;
|
|
||||||
openMP4();
|
|
||||||
}
|
|
||||||
|
|
||||||
MP4Muxer::~MP4Muxer() {
|
MP4Muxer::~MP4Muxer() {
|
||||||
closeMP4();
|
closeMP4();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP4Muxer::openMP4(){
|
void MP4Muxer::openMP4(const string &file){
|
||||||
|
_file_name = file;
|
||||||
closeMP4();
|
closeMP4();
|
||||||
openFile(_file_name.data(), "wb+");
|
openFile(_file_name.data(), "wb+");
|
||||||
GET_CONFIG(bool, mp4FastStart, Record::kFastStart);
|
GET_CONFIG(bool, mp4FastStart, Record::kFastStart);
|
||||||
_mov_writter = createWriter(mp4FastStart ? MOV_FLAG_FASTSTART : 0, false);
|
_mov_writter = createWriter(mp4FastStart ? MOV_FLAG_FASTSTART : 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP4Muxer::closeMP4(){
|
void MP4Muxer::closeMP4(){
|
||||||
_mov_writter = nullptr;
|
_mov_writter = nullptr;
|
||||||
closeFile();
|
closeFile();
|
||||||
@ -38,7 +37,7 @@ void MP4Muxer::resetTracks() {
|
|||||||
_codec_to_trackid.clear();
|
_codec_to_trackid.clear();
|
||||||
_started = false;
|
_started = false;
|
||||||
_have_video = false;
|
_have_video = false;
|
||||||
openMP4();
|
openMP4(_file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MP4Muxer::inputFrame(const Frame::Ptr &frame) {
|
void MP4Muxer::inputFrame(const Frame::Ptr &frame) {
|
||||||
|
@ -23,11 +23,11 @@
|
|||||||
|
|
||||||
namespace mediakit{
|
namespace mediakit{
|
||||||
|
|
||||||
class MP4Muxer : public MediaSinkInterface, public MP4File{
|
class MP4Muxer : public MediaSinkInterface, public MP4FileDisk{
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<MP4Muxer> Ptr;
|
typedef std::shared_ptr<MP4Muxer> Ptr;
|
||||||
|
|
||||||
MP4Muxer(const char *file);
|
MP4Muxer();
|
||||||
~MP4Muxer() override;
|
~MP4Muxer() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,13 +44,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
void resetTracks() override ;
|
void resetTracks() override ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开mp4
|
||||||
|
* @param file 文件完整路径
|
||||||
|
*/
|
||||||
|
void openMP4(const string &file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手动关闭文件(对象析构时会自动关闭)
|
* 手动关闭文件(对象析构时会自动关闭)
|
||||||
*/
|
*/
|
||||||
void closeMP4();
|
void closeMP4();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void openMP4();
|
|
||||||
void stampSync();
|
void stampSync();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -62,8 +67,8 @@ private:
|
|||||||
List<Frame::Ptr> _frameCached;
|
List<Frame::Ptr> _frameCached;
|
||||||
bool _started = false;
|
bool _started = false;
|
||||||
bool _have_video = false;
|
bool _have_video = false;
|
||||||
MP4File::Writer _mov_writter;
|
|
||||||
string _file_name;
|
string _file_name;
|
||||||
|
Writer _mov_writter;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
||||||
|
@ -29,7 +29,8 @@ MP4Reader::MP4Reader(const string &strVhost,const string &strApp, const string &
|
|||||||
strFileName = File::absolutePath(strFileName,recordPath);
|
strFileName = File::absolutePath(strFileName,recordPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
_demuxer = std::make_shared<MP4Demuxer>(strFileName.data());
|
_demuxer = std::make_shared<MP4Demuxer>();
|
||||||
|
_demuxer->openMP4(strFileName);
|
||||||
_mediaMuxer.reset(new MultiMediaSourceMuxer(strVhost, strApp, strId, _demuxer->getDurationMS() / 1000.0, true, true, false, false));
|
_mediaMuxer.reset(new MultiMediaSourceMuxer(strVhost, strApp, strId, _demuxer->getDurationMS() / 1000.0, true, true, false, false));
|
||||||
auto tracks = _demuxer->getTracks(false);
|
auto tracks = _demuxer->getTracks(false);
|
||||||
if(tracks.empty()){
|
if(tracks.empty()){
|
||||||
|
@ -35,6 +35,7 @@ public:
|
|||||||
* 意思是在文件流化结束之前或中断之前,MP4Reader对象是不会被销毁的(不管有没有被外部对象持有)
|
* 意思是在文件流化结束之前或中断之前,MP4Reader对象是不会被销毁的(不管有没有被外部对象持有)
|
||||||
*/
|
*/
|
||||||
void startReadMP4();
|
void startReadMP4();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//MediaSourceEvent override
|
//MediaSourceEvent override
|
||||||
bool seekTo(MediaSource &sender,uint32_t ui32Stamp) override;
|
bool seekTo(MediaSource &sender,uint32_t ui32Stamp) override;
|
||||||
@ -45,15 +46,16 @@ private:
|
|||||||
uint32_t getCurrentStamp();
|
uint32_t getCurrentStamp();
|
||||||
void setCurrentStamp(uint32_t ui32Stamp);
|
void setCurrentStamp(uint32_t ui32Stamp);
|
||||||
bool seekTo(uint32_t ui32Stamp);
|
bool seekTo(uint32_t ui32Stamp);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
recursive_mutex _mtx;
|
bool _have_video = false;
|
||||||
MultiMediaSourceMuxer::Ptr _mediaMuxer;
|
|
||||||
uint32_t _seek_to;
|
uint32_t _seek_to;
|
||||||
|
recursive_mutex _mtx;
|
||||||
Ticker _seek_ticker;
|
Ticker _seek_ticker;
|
||||||
Timer::Ptr _timer;
|
Timer::Ptr _timer;
|
||||||
EventPoller::Ptr _poller;
|
EventPoller::Ptr _poller;
|
||||||
MP4Demuxer::Ptr _demuxer;
|
MP4Demuxer::Ptr _demuxer;
|
||||||
bool _have_video = false;
|
MultiMediaSourceMuxer::Ptr _mediaMuxer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace mediakit */
|
} /* namespace mediakit */
|
||||||
|
@ -53,15 +53,16 @@ void MP4Recorder::createFile() {
|
|||||||
+ strTime + ".mp4";
|
+ strTime + ".mp4";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
_muxer = std::make_shared<MP4Muxer>(strFileTmp.data());
|
_muxer = std::make_shared<MP4Muxer>();
|
||||||
for(auto &track :_tracks){
|
_muxer->openMP4(strFileTmp);
|
||||||
|
for (auto &track :_tracks) {
|
||||||
//添加track
|
//添加track
|
||||||
_muxer->addTrack(track);
|
_muxer->addTrack(track);
|
||||||
}
|
}
|
||||||
_strFileTmp = strFileTmp;
|
_strFileTmp = strFileTmp;
|
||||||
_strFile = strFile;
|
_strFile = strFile;
|
||||||
_createFileTicker.resetTime();
|
_createFileTicker.resetTime();
|
||||||
}catch(std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
WarnL << ex.what();
|
WarnL << ex.what();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user