Skip to content

Tips: To concatenate videos

suntong edited this page May 18, 2023 · 15 revisions

(Shortened url: https://fars.ee/Jhvf)

pure ffmpeg solution

  • To concatenate videos into one, without re-encoding and in a single step:

    ffmpeg -safe 0 -f concat -i <(find . -type f -name '*.mp4' -printf "file '$PWD/%p'\n" | sort) -c copy output.mkv

    (as per the FFmpeg wiki. The process substitution <( ) creates a file descriptor on the fly, which ffmpeg can read. This file will contain the path to every .mp4 file in the current directory. And, we have to prefix it with $(pwd) to get the correct path relative to the current directory, instead of relative to the file descriptor.)

    One special case, to repeat the same video 3 times:

    ffmpeg -safe 0 -f concat -i <(jot -b "file $(pwd)/video.mp4" 3) -c copy output.mp4
    
  • To break it into less automatic but more controllable way,

    1. Make a file containing all the files to join, ex parts.txt containing:

      file video1.mkv
      file 'video2 with space in name.mkv'
      # file videox.mkv, make it a comment to exclude
      
    2. Join the files using the concat demuxer (The -safe 0 above is not required as the paths are relative)

      ffmpeg -f concat -i parts.txt -c copy video.mkv 
      

    Note that there has been a suggestion of this form:

    ffmpeg -i "concat:File1.mp4|File2.mp4" -codec copy .output.mp4

    but I tried it and it is not working for me.

  • To concatenate 2-part videos into one, with encoding:

    ffmpeg -i 01.mp4 -i 02.mp4 -filter_complex "[0:v] [0:a] [1:v] [1:a] concat=n=2:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" -c:v libvpx-vp9 -b:v 0 -crf 43.8 -c:a libopus -b:a 64k -c:s copy out.mkv

Check the following for more explanations and discussions.

Special case: To concatenate WAV files

The above creating file descriptor on the fly approach would still work, but the best option for wav is to use sox:

$ sox short1.wav short2.wav short3.wav long.wav

Solution comes from here, How to append a bunch of .wav files

ffcvt solution

  • To concatenate 2-part videos into one, with encoding, using ffcvt (version v1.6+):
export FFCVT_O=' -i 02.mp4 -filter_complex [0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a] -map [v] -map [a] -speed 2'
nice ffcvt -nc -debug 1 -f 01.mp4
  • For the same feed that has been cut into two parts (same a/v encoding), it can even be as simple as:

    export FFCVT_O=' -i 02.mp4 -filter_complex concat=n=2:v=1:a=1 -speed 2'

  • To concatenate 3-part videos into one, with encoding, using ffcvt (version v1.6+):

    export FFCVT_O=' -i 02.mp4 -i 03.mp4 -filter_complex [0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[v][a] -map [v] -map [a] -speed 2'

    or,

    export FFCVT_O=' -i 02.mp4 -i 03.mp4 -filter_complex concat=n=3:v=1:a=1 -speed 2'

Overlapping case

What if the videos have overlapping sections?

The best option is to cut it first before doing above concatenation. To cut the first 30 seconds off the second video:

ffmpeg -ss 30 -i 02.mp4 -c copy Part2-trimmed.avi

Don't try to do it in single step. If you are determined to do so, then take a look at https://markheath.net/post/cut-and-concatenate-with-ffmpeg. I haven't figure it out myself yet.