#mp4 #merge #join #multiple #camera #sdcard #settings

bin+lib mp4-merge

A tool and library to losslessly join multiple .mp4 files shot with same camera and settings

10 releases

0.1.10 Aug 27, 2024
0.1.9 Aug 4, 2024
0.1.8 Apr 30, 2024
0.1.7 Jan 24, 2024
0.1.2 Aug 31, 2022

#70 in Video

Download history 119/week @ 2024-07-26 266/week @ 2024-08-02 165/week @ 2024-08-09 118/week @ 2024-08-16 260/week @ 2024-08-23 150/week @ 2024-08-30 110/week @ 2024-09-06 166/week @ 2024-09-13 167/week @ 2024-09-20 142/week @ 2024-09-27 146/week @ 2024-10-04 157/week @ 2024-10-11 77/week @ 2024-10-18 64/week @ 2024-10-25 96/week @ 2024-11-01 22/week @ 2024-11-08

286 downloads per month
Used in gopro-chaptered-video-ass…

MIT/Apache

35KB
562 lines

mp4-merge

A tool and library to losslessly join multiple .mp4 files shot with same camera and settings.

This is useful to merge multiple files that are created by the camera because of the 4GB limit on the SD Card.

This tool can merge all these separate files to a new one without transcoding or losing any data.

All original tracks are preserved, all metadata is kept as in the original.

It was created to help stabilizing such files in Gyroflow.

Download:

See the Releases page.

Usage:

The easiest way is to just drag & drop multiple .mp4 files onto the mp4_merge executable.

Usage from command line:

  • Merge specified files and output to IN_FILE1.mp4_joined.mp4
mp4_merge IN_FILE1.mp4 IN_FILE2.mp4 IN_FILE3.mp4 ...
  • Merge specified files and output to result.mp4
mp4_merge IN_FILE1.mp4 IN_FILE2.mp4 IN_FILE3.mp4 ... --out result.mp4

Use as a Rust library:

[dependencies]
mp4-merge = "0.1.10"
let files = ["IN_FILE1.mp4", "IN_FILE2.mp4"];
mp4_merge::join_files(&files, "out.mp4", |progress| {
    println!("Merging... {:.2}%", progress * 100.0);
}).unwrap();

How does this work?

The idea is to merge the raw track data together, and then rewrite the stbl box (which is the descriptor of the raw data) to account for the additional data. In order to do this this library does the following:

  1. Scan every provided file and collect:
    • mdat offset and size
    • Duration stored in mvhd, tkhd, mdhd boxes
    • stbl descriptions: stts, stsz, stss, stsc, stco/co64
  2. Merge all these descriptions: sum durations, append stbl lists to each other and add chunk offsets based on previous file mdat size.
  3. Take the first file, go through every box and write it to the output file, while:
    • If mdat: write raw data from all mdat boxes from all files, and store it as a large box (64-bit)
    • If mvhd, tkhd or mdhd: patch the duration value to the sum of all durations
    • If stbl: write these boxes from scratch, using merged lists from the description
    • If stco: rewrite to co64 to be able to fit more than 4 GB of data.
  4. Done

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Dependencies

~0.2–7MB
~43K SLoC