How to Configure FFmpeg xstack for Multi-Video Grids
This article explains how to use the FFmpeg xstack
filter to combine multiple video inputs into custom grid layouts. You
will learn the syntax of the layout parameter, how to
define coordinate positions for each video stream, and see practical
examples for building complex multi-video displays.
Understanding the xstack Filter
The xstack filter allows you to slice and position
multiple input videos into a single output canvas using a coordinate
system. Unlike the older hstack and vstack
filters, which only allow simple horizontal or vertical chaining,
xstack can position videos anywhere on a 2D grid, even
allowing custom offsets and overlapping positions.
The filter requires two primary parameters: 1. inputs:
The number of input video streams. 2. layout: A list of 2D
coordinates (X_Y) separated by a pipe character
(|), defining where the top-left corner of each input video
should be positioned on the output canvas.
Coordinate Math and Variables
To position videos accurately, xstack provides variables
representing the dimensions of each input video: * w0,
h0: Width and height of the 1st input ([0:v])
* w1, h1: Width and height of the 2nd input
([1:v]) * w2, h2: Width and
height of the 3rd input ([2:v]), and so on.
The coordinates for each video are defined relative to the top-left
corner of the output canvas, which is designated as 0_0
(X=0, Y=0).
Example 1: 2x2 Grid (4 Videos)
To create a standard 2x2 grid using four videos of identical dimensions, use the following layout configuration:
- Top-Left (Video 0):
0_0 - Top-Right (Video 1): Starts at the end of Video 0’s
width:
w0_0 - Bottom-Left (Video 2): Starts below Video 0’s
height:
0_h0 - Bottom-Right (Video 3): Starts at the end of Video
0’s width and below Video 0’s height:
w0_h0
FFmpeg Command:
ffmpeg -i input0.mp4 -i input1.mp4 -i input2.mp4 -i input3.mp4 \
-filter_complex "[0:v][1:v][2:v][3:v]xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0[v]" \
-map "[v]" output.mp4Example 2: 3x3 Grid (9 Videos)
For a larger 3x3 grid using nine identical videos, you expand the coordinate logic horizontally and vertically.
- Row 1:
0_0|w0_0|w0+w1_0 - Row 2:
0_h0|w0_h0|w0+w1_h0 - Row 3:
0_h0+h3|w0_h0+h3|w0+w1_h0+h3
FFmpeg Command:
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -i 4.mp4 -i 5.mp4 -i 6.mp4 -i 7.mp4 -i 8.mp4 -i 9.mp4 \
-filter_complex "[0:v][1:v][2:v][3:v][4:v][5:v][6:v][7:v][8:v]xstack=inputs=9:layout=0_0|w0_0|w0+w1_0|0_h0|w0_h0|w0+w1_h0|0_h0+h3|w0_h0+h3|w0+w1_h0+h3[v]" \
-map "[v]" output.mp4Example 3: Asymmetric Layout (1 Large, 2 Small Videos)
You can also configure asymmetric grids where one video is larger than the others. For example, placing one large video (e.g., 1280x720) on the left, and stack two smaller videos (e.g., 640x360 each) vertically on the right.
- Large Left Video (Video 0):
0_0 - Top-Right Video (Video 1): Starts at the end of
Video 0’s width:
w0_0 - Bottom-Right Video (Video 2): Starts at the end of
Video 0’s width, and below Video 1’s height:
w0_h1
FFmpeg Command:
ffmpeg -i large.mp4 -i small1.mp4 -i small2.mp4 \
-filter_complex "[0:v][1:v][2:v]xstack=inputs=3:layout=0_0|w0_0|w0_h1[v]" \
-map "[v]" output.mp4Important Considerations
- Video Length: By default, the output video duration
will match the longest input. To stop encoding when the shortest input
ends, add the
shortest=1option to your main FFmpeg output parameters. - Canvas Background: If your inputs do not perfectly
align, empty spaces on the output canvas will appear black by default.
You can change this using the
fillparameter (e.g.,fill=redorfill=0x112233). - Frame Rates and Pixel Formats:
xstackrequires all input videos to have the same pixel format and frame rate. If your inputs differ, use theformatorfpsfilters on the inputs before passing them toxstack.