FFmpeg xstack Pixel Offset Configuration Guide
This article explains how to precisely position multiple video inputs
using the xstack filter in FFmpeg. You will learn how to
configure the exact pixel offsets for each input stream using the
layout parameter, enabling you to create custom grid
layouts, picture-in-picture effects, or non-standard video collages with
pixel-perfect accuracy.
Understanding the
xstack Filter Syntax
The xstack filter combines several input videos into a
single output canvas. To define where each video is placed, you must
specify the number of inputs and their exact coordinate offsets using
the layout option.
The basic syntax for the filter is:
-filter_complex "xstack=inputs=N:layout=X0_Y0|X1_Y1|X2_Y2..."
inputs=N: The total number of input video streams.layout: A list of coordinates separated by a pipe (|). Each coordinate pair defines the top-left corner of an input video on the output canvas, formatted asX_Y(horizontal offset and vertical offset, separated by an underscore).
Configuring Offsets with Fixed Pixel Values
If you know the exact dimensions of your output canvas and your source videos, you can use hardcoded pixel offsets.
For example, if you have four 1920x1080 videos and want
to arrange them in a 2x2 grid (resulting in a 3840x2160
output), the top-left pixel coordinates for each video are: *
Video 0 (Top-Left): 0_0 * Video
1 (Top-Right): 1920_0 (Shifted 1920 pixels to the
right) * Video 2 (Bottom-Left): 0_1080
(Shifted 1080 pixels down) * Video 3 (Bottom-Right):
1920_1080 (Shifted 1920 pixels right and 1080 pixels
down)
The corresponding FFmpeg command is:
ffmpeg -i input0.mp4 -i input1.mp4 -i input2.mp4 -i input3.mp4 \
-filter_complex "xstack=inputs=4:layout=0_0|1920_0|0_1080|1920_1080" \
output.mp4Configuring Offsets using Dynamic Variables
Hardcoding pixel values requires you to know the exact dimensions
beforehand. To make your commands reusable, FFmpeg provides variables to
reference the width (w) and height (h) of each
input stream: * w0 and h0 for Input 0 *
w1 and h1 for Input 1 * w2 and
h2 for Input 2, and so on.
Using these variables, the 2x2 grid command can be written dynamically:
ffmpeg -i input0.mp4 -i input1.mp4 -i input2.mp4 -i input3.mp4 \
-filter_complex "xstack=inputs=4:layout=0_0|w0_0|0_h0|w0_h0" \
output.mp4In this setup: * 0_0 places the first video at the
top-left origin. * w0_0 places the second video immediately
to the right of the first video. * 0_h0 places the third
video directly beneath the first video. * w0_h0 places the
fourth video to the right of the third video and beneath the second.
Custom Asymmetric Layouts and Padding
You can use mathematical expressions within the offsets to create custom layouts, such as adding gaps (padding) between videos or leaving space for a background.
For example, if you want to place two 640x360 videos
side-by-side but want a 20-pixel gap between them and a 10-pixel border
at the top and left: * Video 0 Position:
10_10 (Offset by 10 pixels on both X and Y axes) *
Video 1 Position: 10+w0+20_10 (Starts at
10 pixels + width of Video 0 + 20-pixel gap, and 10 pixels down)
The FFmpeg command for this custom offset layout is:
ffmpeg -i input0.mp4 -i input1.mp4 \
-filter_complex "xstack=inputs=2:layout=10_10|10+w0+20_10" \
output.mp4Important Considerations
- Canvas Size: The
xstackfilter automatically calculates the size of the output canvas based on the maximum dimensions reached by your specified layouts. - Unfilled Areas: Any areas of the output canvas not covered by an input video will be filled with black by default.
- Framerate and Pixel Format: For the best results
and to prevent synchronization issues, ensure all input videos have the
same framerate and pixel format before passing them into the
xstackfilter.