FFmpeg Concat Videos with Different Resolutions and Codecs

This article explains how to merge videos with mismatching resolutions, aspect ratios, frame rates, or codecs using FFmpeg’s concat filter. When source videos do not share identical parameters, the standard file-level concat demuxer will fail or produce corrupted files. To resolve this, you must pass the inputs through a filtergraph to normalize their properties—specifically scaling, padding, and re-encoding them to a uniform format—before joining them into a single output file.

The Challenge with Different Formats

FFmpeg has two primary ways to join videos: the concat demuxer and the concat filter.

To use the concat filter with differing files, you must preprocess each video stream within the command to match a target resolution and aspect ratio.

The FFmpeg Command

The following command takes two different input videos (input1.mp4 and input2.mp4), scales and pads them to a uniform 1920x1080 resolution, and concatenates them with their audio.

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v0]; \
 [1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v1]; \
 [v0][0:a][v1][1:a]concat=n=2:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -c:v libx264 -c:a aac -vsync 2 output.mp4

How the Filtergraph Works

The -filter_complex flag handles the processing of both video streams simultaneously using the following steps:

  1. scale=1920:1080:force_original_aspect_ratio=decrease: Resizes the video to fit within a 1920x1080 box without stretching or distorting the original aspect ratio.
  2. pad=1920:1080:(ow-iw)/2:(oh-ih)/2: Centers the scaled video inside a 1920x1080 canvas and fills the remaining empty space with black bars (pillarboxing or letterboxing).
  3. setsar=1: Sets the Sample Aspect Ratio to 1 to ensure standard square pixels, preventing playback distortion.
  4. [v0] and [v1]: These are temporary labels assigned to the newly processed video streams.
  5. concat=n=2:v=1:a=1: This filter takes the processed video streams ([v0], [v1]) and their respective original audio streams ([0:a], [1:a]) to merge them.
    • n=2 tells FFmpeg there are two input segments.
    • v=1 specifies that each segment has one video stream.
    • a=1 specifies that each segment has one audio stream.

Handling More Than Two Videos

If you need to concatenate three or more videos, extend the pattern by adding more inputs, defining additional scale/pad filters, and updating the concat filter parameters.

Here is an example for three videos:

ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -filter_complex \
"[0:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v0]; \
 [1:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v1]; \
 [2:v]scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2,setsar=1[v2]; \
 [v0][0:a][v1][1:a][v2][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -c:v libx264 -c:a aac -vsync 2 output.mp4

In this command, n=3 is used in the concat filter to accommodate the three input sets, outputting a single unified video.