Stack Videos With FFmpeg

Something I had to figure how to do recently to make a Fiverr gig promo video was stack videos together.

This is when you see two or more videos playing side by side at the same time. It is often used to compare before and after results, such as what I did.

Horizontal Stacking

So what does it look like to stack two videos together horizontally? It looks something like this:

Let's see how we achieve this result:

ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex \
"[0:v][1:v]hstack=inputs=2:shortest=1[outv]" \
-map "[outv]" hstacked.mp4

You'll see we are passing in two videos as inputs with the -i option, video1.mp4, and video2.mp4.

For the filter graph we have:

"[0:v][1:v]hstack=inputs=2:shortest=1[outv]"

We are taking the video streams from the two inputs and passing them into the hstack filter. The inputs option indicates how many video streams are being used as inputs (defaults to 2) and the shortest option indicates how long the output video stream will be. By default, it will be the length of the longest video stream. Setting shortest=1 will make it the length of the shortest video stream instead.

After that, we just map the video stream created from hstack to the output file and you're good to go.

One thing about using hstack taken from the FFmpeg filter documentation:

All streams must be of same pixel format and of same height

If I recall, this means the videos have to be the same height and have the same encoding. Otherwise, the output just doesn't work.

Vertical Stacking

Let's see what vertically stacked videos looks like:

Let's see how we achieve this result:

ffmpeg -i video1.mp4 -i video2.mp4 -filter_complex \
"[0:v][1:v]vstack=inputs=2:shortest=1[outv]" \
-map "[outv]" hstacked.mp4

This is almost the same as horizontal stacking but we use vstack instead of hstack, even the arguments are the same.

The vstack filter has the same conditions as hstack but they have to be the same width, instead of height.

Combining Stacks

A weird idea I had after playing around with these was to combine them. After doing so I got this result:

That's pretty interesting, looks like a 2x2 grid of videos playing.

Now, how did we achieve this effect?

ffmpeg -i video1.mp4 -i video2.mp4 -i video3.mp4 -filter_complex \
"[0:v][1:v]hstack=inputs=2:shortest=1[row1];
[0:v][2:v]hstack=inputs=2:shortest=1[row2];
[row1][row2]vstack=inputs=2:shortest=1[outv]" \
-map "[outv]" ow-creation-double-stack.mp4

Let's go over the filter graph:

[0:v][1:v]hstack=inputs=2:shortest=1[row1]

Here we are horizontally stacking the first video stream and the second video stream and calling the new stream [row1].

[0:v][2:v]hstack=inputs=2:shortest=1[row2]

Next, we horizontally stack the first video stream with the third video stream and call that new stream [row2].

[row1][row2]vstack=inputs=2:shortest=1[outv]

Finally, we take the two horizontally stacked video streams, and vertically stack them on top of each other! That is pretty neat.

With that, you should be able to horizontally and vertically stack videos with FFmpeg!

Thank you for reading!


Did you find this information useful? If so, consider heading over to my donation page and drop me some support.

Want to ask a question or just chat? Contact me here