How can I merge two mp4 files without losing quality?
I usually use VirtualDub to merge my files, but it doesn't seem to support mp4. So what alternatives are there?
Avidemux. It's just like VirtualDub, only with more formats supported and built-in codecs and filters. I always use it in preference; it joins AVC+AAC.MP4 files (without recoding) fine for me.
To join them in AviDemux:
- File -> Open -> Select File
- File -> Append -> Select File
- Set all to Copy
- File -> Save -> FileName
- Wait..
According to AViDemux forums, this join process is lossless (http://www.avidemux.org/smf/index.php?topic=9467.0)
You can do this with ffmpeg:
mkfifo temp0 temp1
ffmpeg -i input0.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts -y temp0 2> /dev/null & \
ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts -y temp1 2> /dev/null & \
ffmpeg -f mpegts -i "concat:temp0|temp1" -c copy -absf aac_adtstoasc output.mp4
This doesn't re-encode anything, it places them in a new transport stream container, which makes them more easy to concatenate, and then concatenates them back into an MP4. If output.mp4 already exists, the command will fail. The version above uses named pipes, if you're on a system that doesn't support those you'd have to use intermediate files (like windows):
ffmpeg -i input0.mp4 -c copy -bsf:v h264_mp4toannexb temp0.ts
ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb temp1.ts
ffmpeg -i "concat:temp0.ts|temp1.ts" -c copy -bsf:a aac_adtstoasc output.mp4
Concat demuxer
The concat demuxer was added to ffmpeg 1.1. If your version of ffmpeg is to old, get the newest static binary from here: http://www.ffmpeg.org/download.html
Instructions
Create a file mylist.txt
with all the files you want to have concatenated in the following form (Lines starting with a dash are ignored):
# this is a comment
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
Note that these can be either relative or absolute paths. Then you can encode your files with:
ffmpeg -f concat -i mylist.txt -c copy output
It is possible to generate this list file with a bash for loop, or using printf. Either one of the following would generate a list file containing every *.wav in the working directory:
for f in ./*.wav; do echo "file '$f'" >> mylist.txt; done
printf "file '%s'\n" ./*.wav > mylist.txt
Source: ffmpeg wiki
YAMB along with MP4BOX is a good option.
Download both and unzip them (no installation needed and together they're about 5MB), in YAMB choose Settings and set the folder path of MP4box.
To join mp4 files choose Editing > Click to Join supported...
Try using the Matroska video container.
Firstly, you need mkvtoolnix. Download and install it, then you need to fire up mkvmerge GUI (unless you like command-line tools, which is fine by me - although you might want to look at the file linking section of the mkvmerge documentation).
Add your first file by clicking "add". Then, click on "append", and open your second file. Set the output file, hit "Start muxing" at the bottom, and away you go!
If the container is unsuitable for your needs, you can reencode it, or try to convert it to some other format... Although MKV is a very lovely container!