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.
- Concat Demuxer: Fast (no re-encoding), but requires all input files to have the exact same codecs, resolution, frame rate, and aspect ratio.
- Concat Filter: Slower (requires re-encoding), but highly flexible. It allows you to resize, pad, and transcode varying inputs on the fly so they can be merged seamlessly.
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.mp4How the Filtergraph Works
The -filter_complex flag handles the processing of both
video streams simultaneously using the following steps:
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.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).setsar=1: Sets the Sample Aspect Ratio to 1 to ensure standard square pixels, preventing playback distortion.[v0]and[v1]: These are temporary labels assigned to the newly processed video streams.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=2tells FFmpeg there are two input segments.v=1specifies that each segment has one video stream.a=1specifies 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.mp4In this command, n=3 is used in the concat
filter to accommodate the three input sets, outputting a single unified
video.