mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-02-22 16:20:54 +08:00
优化mp4与flv录制相关代码 (#4206)
This commit is contained in:
@@ -138,7 +138,7 @@ Frame::Ptr MP4Demuxer::readFrame(bool &keyFrame, bool &eof) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame::Ptr MP4Demuxer::makeFrame(uint32_t track_id, const Buffer::Ptr &buf, int64_t pts, int64_t dts) {
|
Frame::Ptr MP4Demuxer::makeFrame(uint32_t track_id, Buffer::Ptr buf, int64_t pts, int64_t dts) {
|
||||||
auto it = _tracks.find(track_id);
|
auto it = _tracks.find(track_id);
|
||||||
if (it == _tracks.end()) {
|
if (it == _tracks.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -198,11 +198,11 @@ void MultiMP4Demuxer::openMP4(const string &files_string) {
|
|||||||
std::vector<std::string> files;
|
std::vector<std::string> files;
|
||||||
if (File::is_dir(files_string)) {
|
if (File::is_dir(files_string)) {
|
||||||
File::scanDir(files_string, [&](const string &path, bool is_dir) {
|
File::scanDir(files_string, [&](const string &path, bool is_dir) {
|
||||||
if (!is_dir) {
|
if (!is_dir && end_with(path, ".mp4")) {
|
||||||
files.emplace_back(path);
|
files.emplace_back(path);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
}, true);
|
||||||
std::sort(files.begin(), files.end());
|
std::sort(files.begin(), files.end());
|
||||||
} else {
|
} else {
|
||||||
files = split(files_string, ";");
|
files = split(files_string, ";");
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ 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 toolkit::Buffer::Ptr &buf, int64_t pts, int64_t dts);
|
Frame::Ptr makeFrame(uint32_t track_id, toolkit::Buffer::Ptr buf, int64_t pts, int64_t dts);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MP4FileDisk::Ptr _mp4_file;
|
MP4FileDisk::Ptr _mp4_file;
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ using namespace toolkit;
|
|||||||
namespace mediakit {
|
namespace mediakit {
|
||||||
|
|
||||||
MP4Recorder::MP4Recorder(const MediaTuple &tuple, const string &path, size_t max_second) {
|
MP4Recorder::MP4Recorder(const MediaTuple &tuple, const string &path, size_t max_second) {
|
||||||
_folder_path = path;
|
|
||||||
// ///record 业务逻辑////// [AUTO-TRANSLATED:2e78931a]
|
// ///record 业务逻辑////// [AUTO-TRANSLATED:2e78931a]
|
||||||
// ///record Business Logic//////
|
// ///record Business Logic//////
|
||||||
static_cast<MediaTuple &>(_info) = tuple;
|
static_cast<MediaTuple &>(_info) = tuple;
|
||||||
@@ -44,9 +43,9 @@ MP4Recorder::~MP4Recorder() {
|
|||||||
void MP4Recorder::createFile() {
|
void MP4Recorder::createFile() {
|
||||||
closeFile();
|
closeFile();
|
||||||
auto date = getTimeStr("%Y-%m-%d");
|
auto date = getTimeStr("%Y-%m-%d");
|
||||||
auto file_name = getTimeStr("%H-%M-%S") + "-" + std::to_string(_file_index++) + ".mp4";
|
auto file_name = date + "-" + getTimeStr("%H-%M-%S") + "-" + std::to_string(_file_index++) + ".mp4";
|
||||||
auto full_path = _folder_path + date + "/" + file_name;
|
auto full_path = _info.folder + date + "/" + file_name;
|
||||||
auto full_path_tmp = _folder_path + date + "/." + file_name;
|
auto full_path_tmp = _info.folder + date + "/." + file_name;
|
||||||
|
|
||||||
// ///record 业务逻辑////// [AUTO-TRANSLATED:2e78931a]
|
// ///record 业务逻辑////// [AUTO-TRANSLATED:2e78931a]
|
||||||
// ///record Business Logic//////
|
// ///record Business Logic//////
|
||||||
@@ -66,7 +65,6 @@ void MP4Recorder::createFile() {
|
|||||||
_muxer->addTrack(track);
|
_muxer->addTrack(track);
|
||||||
}
|
}
|
||||||
_full_path_tmp = full_path_tmp;
|
_full_path_tmp = full_path_tmp;
|
||||||
_full_path = full_path;
|
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
WarnL << ex.what();
|
WarnL << ex.what();
|
||||||
}
|
}
|
||||||
@@ -75,10 +73,9 @@ void MP4Recorder::createFile() {
|
|||||||
void MP4Recorder::asyncClose() {
|
void MP4Recorder::asyncClose() {
|
||||||
auto muxer = _muxer;
|
auto muxer = _muxer;
|
||||||
auto full_path_tmp = _full_path_tmp;
|
auto full_path_tmp = _full_path_tmp;
|
||||||
auto full_path = _full_path;
|
|
||||||
auto info = _info;
|
auto info = _info;
|
||||||
TraceL << "Start close tmp mp4 file: " << full_path_tmp;
|
TraceL << "Start close tmp mp4 file: " << full_path_tmp;
|
||||||
WorkThreadPool::Instance().getExecutor()->async([muxer, full_path_tmp, full_path, info]() mutable {
|
WorkThreadPool::Instance().getExecutor()->async([muxer, full_path_tmp, info]() mutable {
|
||||||
info.time_len = muxer->getDuration() / 1000.0f;
|
info.time_len = muxer->getDuration() / 1000.0f;
|
||||||
// 关闭mp4可能非常耗时,所以要放在后台线程执行 [AUTO-TRANSLATED:a7378a11]
|
// 关闭mp4可能非常耗时,所以要放在后台线程执行 [AUTO-TRANSLATED:a7378a11]
|
||||||
// Closing mp4 can be very time-consuming, so it should be executed in the background thread
|
// Closing mp4 can be very time-consuming, so it should be executed in the background thread
|
||||||
@@ -97,9 +94,9 @@ void MP4Recorder::asyncClose() {
|
|||||||
}
|
}
|
||||||
// 临时文件名改成正式文件名,防止mp4未完成时被访问 [AUTO-TRANSLATED:541a6f00]
|
// 临时文件名改成正式文件名,防止mp4未完成时被访问 [AUTO-TRANSLATED:541a6f00]
|
||||||
// Change the temporary file name to the official file name to prevent access to the mp4 before it is completed
|
// Change the temporary file name to the official file name to prevent access to the mp4 before it is completed
|
||||||
rename(full_path_tmp.data(), full_path.data());
|
rename(full_path_tmp.data(), info.file_path.data());
|
||||||
}
|
}
|
||||||
TraceL << "Emit mp4 record event: " << full_path;
|
TraceL << "Emit mp4 record event: " << info.file_path;
|
||||||
// 触发mp4录制切片生成事件 [AUTO-TRANSLATED:9959dcd4]
|
// 触发mp4录制切片生成事件 [AUTO-TRANSLATED:9959dcd4]
|
||||||
// Trigger mp4 recording slice generation event
|
// Trigger mp4 recording slice generation event
|
||||||
NOTICE_EMIT(BroadcastRecordMP4Args, Broadcast::kBroadcastRecordMP4, info);
|
NOTICE_EMIT(BroadcastRecordMP4Args, Broadcast::kBroadcastRecordMP4, info);
|
||||||
|
|||||||
@@ -71,9 +71,7 @@ private:
|
|||||||
bool _have_video = false;
|
bool _have_video = false;
|
||||||
size_t _max_second;
|
size_t _max_second;
|
||||||
uint64_t _last_dts = 0;
|
uint64_t _last_dts = 0;
|
||||||
uint64_t _file_index = 0;
|
std::atomic<uint64_t> _file_index { 0 };
|
||||||
std::string _folder_path;
|
|
||||||
std::string _full_path;
|
|
||||||
std::string _full_path_tmp;
|
std::string _full_path_tmp;
|
||||||
RecordInfo _info;
|
RecordInfo _info;
|
||||||
MP4Muxer::Ptr _muxer;
|
MP4Muxer::Ptr _muxer;
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "Rtmp/utils.h"
|
#include "Rtmp/utils.h"
|
||||||
#include "Http/HttpSession.h"
|
#include "Http/HttpSession.h"
|
||||||
|
|
||||||
#define FILE_BUF_SIZE (64 * 1024)
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
@@ -168,11 +167,12 @@ void FlvRecorder::startRecord(const EventPoller::Ptr &poller, const string &vhos
|
|||||||
|
|
||||||
void FlvRecorder::startRecord(const EventPoller::Ptr &poller, const RtmpMediaSource::Ptr &media,
|
void FlvRecorder::startRecord(const EventPoller::Ptr &poller, const RtmpMediaSource::Ptr &media,
|
||||||
const string &file_path) {
|
const string &file_path) {
|
||||||
|
GET_CONFIG(uint32_t, flvBufSize, Record::kFileBufSize);
|
||||||
stop();
|
stop();
|
||||||
lock_guard<recursive_mutex> lck(_file_mtx);
|
lock_guard<recursive_mutex> lck(_file_mtx);
|
||||||
// 开辟文件写缓存 [AUTO-TRANSLATED:22d1c17f]
|
// 开辟文件写缓存 [AUTO-TRANSLATED:22d1c17f]
|
||||||
// Allocate file write cache.
|
// Allocate file write cache.
|
||||||
std::shared_ptr<char> fileBuf(new char[FILE_BUF_SIZE], [](char *ptr) {
|
std::shared_ptr<char> fileBuf(new char[flvBufSize], [](char *ptr) {
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
delete[] ptr;
|
delete[] ptr;
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ void FlvRecorder::startRecord(const EventPoller::Ptr &poller, const RtmpMediaSou
|
|||||||
|
|
||||||
// 设置文件写缓存 [AUTO-TRANSLATED:a767e55c]
|
// 设置文件写缓存 [AUTO-TRANSLATED:a767e55c]
|
||||||
// Set the file write cache.
|
// Set the file write cache.
|
||||||
setvbuf(_file.get(), fileBuf.get(), _IOFBF, FILE_BUF_SIZE);
|
setvbuf(_file.get(), fileBuf.get(), _IOFBF, flvBufSize);
|
||||||
start(poller, media);
|
start(poller, media);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user