Concat two mp4 files with ffmpeg without losing quality

16

16

I want to concatenate 2 videos using ffmpeg. I am using:

ffmpeg -i output1.mp4 -scodec copy -vbsf h264_mp4toannexb i0.ts

But the mp4 file I get looks much worse then the source file.

Here is the information about both the files

   Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'output1.mp4':
   Metadata:
   major_brand     : isom
   minor_version   : 1
   compatible_brands: isom
   creation_time   : 2013-06-13 15:40:36
   Duration: 00:00:15.72, start: 0.000000, bitrate: 2053 kb/s
   Stream #0.0(und): Video: h264 (High), yuv420p, 1280x720, 1931 kb/s, 25 fps, 25 tbr,   12800 tbn, 50 tbc
   Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 128 kb/s

  Input #0, mpegts, from 'i0.ts':
  Duration: 00:00:15.64, start: 1.400000, bitrate: 1382 kb/s
  Program 1 
  Metadata:
  service_name    : Service01
  service_provider: Libav
  Stream #0.0[0x100]: Video: mpeg2video (Main), yuv420p, 1280x720 [PAR 1:1 DAR 16:9], 104857 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
  Stream #0.1[0x101](und): Audio: mp2, 44100 Hz, stereo, s16, 128 kb/s

How can I solve this problem?

jenia

Posted 2013-06-13T16:08:03.863

Reputation:

What are you trying to do, exactly? The term "concat" means to join several files, but you are only referring to one input, output1.mp4, and one output, i0.ts. Encoding to ts output container will use the mpeg2video encoder by default (at least with your build), and last time I checked the default bitrate or quality setting for this encoder is -b:v 200k which is too low for most cases. – llogan – 2013-06-13T17:15:42.723

sorry. Then i concat them with ffmpeg -i "concat:i0.ts|i1.ts" output1111.mp4. But the problem is that the quality is bad already when i make ts-files – None – 2013-06-13T17:34:33.497

You may not need to re-encode to MPEG-2 video. Do all of your original inputs (output1.mp4, etc) have the same formats, frame rate, and frame size? – llogan – 2013-06-13T18:10:47.497

yes, exactly. All are equall – None – 2013-06-13T18:22:17.507

Answers

36

Consider using the concat demuxer. This way you can avoid creating temporary, lossy intermediate files and skip an extra step of re-encoding.

Note: All inputs must have the same stream types (same formats, same time base, etc.).

  1. Create a text file and include the paths and names of each file to concatenate (or "join"). Example file, input.txt:

    file '/home/jenia/input1.mp4'
    file '/home/jenia/input2.mp4'
    file '/home/jenia/input3.mp4'
    
  2. Now you can use the concat demuxer:

    ffmpeg -f concat -i input.txt -codec copy output.mp4
    

If you do not have this feature, then either your ffmpeg is too old, or you're using a "fake" ffmpeg from the libav fork.

Easy to use static builds are available for Linux, OS X, and Windows via the FFmpeg download page, or you can follow a step-by-step guide to compile ffmpeg.

Also see:

llogan

Posted 2013-06-13T16:08:03.863

Reputation: 31 929

This is exactly what I wanted and helped me merge 2 .mov files from my iPhone 6. Thanks. – Ryan – 2016-02-22T18:51:50.183

7

The quickest 1-liner would be:

ls Movie\ Part\ * | while read line; do echo file \'$line\'; done | ffmpeg -f concat -i - -c copy output.mp4

Hackeron

Posted 2013-06-13T16:08:03.863

Reputation: 529

Any chance to get such a 1-onliner for windows command line? – PeterCo – 2016-09-14T13:20:25.730

2On Linux I used this oneliner: ffmpeg -safe 0 -f concat -i <(find . -type f -name '*' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv (mkv accepts more codecs than mp4, but you could also try it with mp4). The -safe 0 is for recent ffmpeg versions complaining about Unsafe file name, and the -type f is for only listing files. I added | sort to sort the files alphabetically; because find reads them in order as saved on filesystem. Works also for files with whitespaces. – erik – 2016-12-02T14:18:39.683