How to stack videos together with ffmpeg
Tags: linux, productivity, video, ffmpeg
Published: 2020-05-06 21:13:24

{% youtube 659dOQPwfdQ %}

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:

![Horizontal Stack Example](https://dev-to-uploads.s3.amazonaws.com/i/hcezgtwcwwb57pp73i6x.jpg)

Lets see how we achieve this result:

```sh
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

Lets see what vertically stacked videos looks like:

![Vertically Stacked Videos](https://dev-to-uploads.s3.amazonaws.com/i/el2h2ibt5u1m24de61kd.jpg)

Lets see how we achieve this result:

```sh
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 exactly 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:

![Double Stacked Videos](https://dev-to-uploads.s3.amazonaws.com/i/ko3im7c4seyfbra8b155.jpg)

Thats pretty interesting, looks like a 2x2 grid of videos playing.

Now, how did we achieve this effect?

```sh
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
```

Lets 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!

If you enjoy my content, you can find me on these platforms as well:

* Subscribe on [Youtube](https://www.youtube.com/channel/UCTHij3Ac5GizLsn5yB4IX_Q)
* Follow on [Twitter](https://twitter.com/FeuryDonald)