Skip to content

Commit 16bb22c

Browse files
authored
Merge pull request #247 from SuslikV/patch-5
Add 2 new multiplexing presets for mp4, mov files
2 parents e85e605 + be7db11 commit 16bb22c

File tree

1 file changed

+28
-2
lines changed

1 file changed

+28
-2
lines changed

src/FFmpegWriter.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ using namespace openshot;
4141
#pragma message "You are compiling only with software encode"
4242
#endif
4343

44+
// Multiplexer parameters temporary storage
45+
AVDictionary *mux_dict = NULL;
46+
4447
#if IS_FFMPEG_3_2
4548
int hw_en_on = 1; // Is set in UI
4649
int hw_en_supported = 0; // Is set by FFmpegWriter
@@ -467,6 +470,17 @@ void FFmpegWriter::SetOption(StreamType stream, string name, string value) {
467470

468471
ZmqLogger::Instance()->AppendDebugMethod("FFmpegWriter::SetOption (" + (string)name + ")", "stream == VIDEO_STREAM", stream == VIDEO_STREAM, "", -1, "", -1, "", -1, "", -1, "", -1);
469472

473+
// Muxing dictionary is not part of the codec context.
474+
// Just reusing SetOption function to set popular multiplexing presets.
475+
} else if (name == "muxing_preset") {
476+
if (value == "mp4_faststart") {
477+
// 'moov' box to the beginning; only for MOV, MP4
478+
av_dict_set(&mux_dict, "movflags", "faststart", 0);
479+
} else if (value == "mp4_fragmented") {
480+
// write selfcontained fragmented file, minimum length of the fragment 8 sec; only for MOV, MP4
481+
av_dict_set(&mux_dict, "movflags", "frag_keyframe", 0);
482+
av_dict_set(&mux_dict, "min_frag_duration", "8000000", 0);
483+
}
470484
} else {
471485
throw InvalidOptions("The option is not valid for this codec.", path);
472486
}
@@ -514,17 +528,29 @@ void FFmpegWriter::WriteHeader() {
514528
snprintf(oc->AV_FILENAME, sizeof(oc->AV_FILENAME), "%s", path.c_str());
515529

516530
// Write the stream header, if any
517-
// TODO: add avoptions / parameters instead of NULL
518531

519532
// Add general metadata (if any)
520533
for (std::map<string, string>::iterator iter = info.metadata.begin(); iter != info.metadata.end(); ++iter) {
521534
av_dict_set(&oc->metadata, iter->first.c_str(), iter->second.c_str(), 0);
522535
}
523536

524-
if (avformat_write_header(oc, NULL) != 0) {
537+
// Set multiplexing parameters
538+
AVDictionary *dict = NULL;
539+
540+
bool is_mp4 = strcmp(oc->oformat->name, "mp4");
541+
bool is_mov = strcmp(oc->oformat->name, "mov");
542+
// Set dictionary preset only for MP4 and MOV files
543+
if (is_mp4 || is_mov)
544+
av_dict_copy(&dict, mux_dict, 0);
545+
546+
if (avformat_write_header(oc, &dict) != 0) {
525547
throw InvalidFile("Could not write header to file.", path);
526548
};
527549

550+
// Free multiplexing dictionaries sets
551+
if (dict) av_dict_free(&dict);
552+
if (mux_dict) av_dict_free(&mux_dict);
553+
528554
// Mark as 'written'
529555
write_header = true;
530556

0 commit comments

Comments
 (0)