How to Use FFmpeg xstack with Different Video Dimensions
This guide explains how to use FFmpeg’s xstack filter to
combine and stack multiple videos that have different resolutions and
dimensions. You will learn the core concepts of the xstack
layout grid, how to position videos of varying sizes using precise
coordinate positioning, and how to use scaling or padding to ensure a
clean visual output without rendering artifacts.
Understanding the xstack Layout System
The xstack filter positions multiple input videos on a
single output canvas using a 2D coordinate system (X_Y). It
uses variables to represent the dimensions of the inputs: *
w0, h0 represent the width and height of the
first input. * w1, h1 represent the width and
height of the second input, and so on.
When stacking videos of different sizes, you must explicitly define
these coordinates in the layout parameter and handle any
empty spaces created by the size mismatches.
Method 1: Direct Stacking with Custom Coordinates
If you want to keep the original resolutions of your videos, you can position them side-by-side or stacked vertically using their exact dimensions.
Example: Side-by-Side (Horizontal Stack)
Suppose you have two videos: * Video 0: 1280x720 * Video 1: 640x360
To stack them horizontally, Video 0 starts at 0_0
(top-left). Video 1 must start at the end of Video 0’s width, which is
w0_0. Because Video 1 is shorter, you should use the
fill option to paint the empty space black.
ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex "[0:v][1:v]xstack=inputs=2:layout=0_0|w0_0:fill=black[v]" -map "[v]" output.mp4Example: 2x2 Grid with Mixed Dimensions
Suppose you have four videos with different sizes: * Input 0: 1920x1080 (Top-left) * Input 1: 1280x720 (Top-right, positioned at X = 1920, Y = 0) * Input 2: 1280x720 (Bottom-left, positioned at X = 0, Y = 1080) * Input 3: 640x480 (Bottom-right, positioned at X = 1920, Y = 1080)
The layout string for this configuration is
0_0|w0_0|0_h0|w0_h0:
ffmpeg -i in1.mp4 -i in2.mp4 -i in3.mp4 -i in4.mp4 -filter_complex "[0:v][1:v][2:v][3:v]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0:fill=black[v]" -map "[v]" output.mp4Method 2: Scaling Inputs First (Recommended)
Directly stacking mismatched resolutions can leave uneven black bars
or empty gaps in your output grid. The cleanest way to stack videos of
different dimensions is to scale them to uniform dimensions before
passing them to the xstack filter.
The following command scales four different input videos to a uniform
640x360 resolution and stacks them in a perfect 2x2
grid:
ffmpeg -i in1.mp4 -i in2.mp4 -i in3.mp4 -i in4.mp4 -filter_complex \
"[0:v]scale=640:360[v0]; \
[1:v]scale=640:360[v1]; \
[2:v]scale=640:360[v2]; \
[3:v]scale=640:360[v3]; \
[v0][v1][v2][v3]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v]" \
-map "[v]" output.mp4Method 3: Padding Inputs to Avoid Aspect Ratio Distortion
If scaling your videos stretches or distorts the image, you can use
the pad filter. This adds black bars (pillarboxes or
letterboxes) to each video to bring them to a uniform size before
stacking.
This example pads two different videos to a uniform
1280x720 container, centering the original video, and
stacks them side-by-side:
ffmpeg -i in1.mp4 -i in2.mp4 -filter_complex \
"[0:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2[v0]; \
[1:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2[v1]; \
[v0][v1]xstack=inputs=2:layout=0_0|w0_0[v]" \
-map "[v]" output.mp4