FFmpeg is a free and open-source video editing tool capable of trimming, cropping, concatenating, muxing, and transcoding almost any type of media file you throw at it.
It's also a very robust solution for implementing video automation, as we use it extensively in our own video editing API. For this tutorial we'll use FFmpeg 5.1.2, but any recent version will do.
You can merge a video and overlay image using the following command:
$ ffmpeg -i video.mp4 -i overlay.png -filter_complex [0][1]overlay=x=0:y=0 output.mp4
Tip: You can convert any image into a transparent PNG with a service like Remove.bg. If you just want to overlay an opaque image, you don't need to do this.
These variables can be used to instruct FFmpeg where to place the overlay:
To place the overlay in the bottom-left corner:
$ ffmpeg -i video.mp4 -i overlay.png -filter_complex [0][1]overlay=x=0:y=(main_h-overlay_h) output.mp4
To place the overlay in the bottom-right corner:
$ ffmpeg -i video.mp4 -i overlay.png -filter_complex [0][1]overlay=x=(main_w-overlay_w):y=(main_h-overlay_h) output.mp4
To place the overlay in the top-left corner:
$ ffmpeg -i video.mp4 -i overlay.png -filter_complex [0][1]overlay=x=0:y=0 output.mp4
To place the overlay in the top-right corner:
$ ffmpeg -i video.mp4 -i overlay.png -filter_complex [0][1]overlay=x=(main_w-overlay_w):y=0 output.mp4
To place the overlay in the center:
$ ffmpeg -i video.mp4 -i overlay.png -filter_complex [0][1]overlay=x=(main_w-overlay_w)/2:y=(main_h-overlay_h)/2 output.mp4
An overlay can be padded by adding or subtracting pixels from its position, as illustrated in the following example. Here, the overlay is placed in the top-right corner, but with a padding of 100 pixels:
$ ffmpeg -i video.mp4 -i overlay.png -filter_complex [0][1]overlay=x=(main_w-overlay_w-100):y=100 output.mp4
FFmpeg also allows us to make an overlay image that changes over time. We can do this by using multiple overlay filters for every image we want to display, and enabling those filters at the right timestamps. Here is how three images can be displayed sequentially over a video:
$ ffmpeg -i video.mp4 -i overlay1.png -i overlay2.png -i overlay3.png -filter_complex [0][1]overlay=enable='between(t,0,4)':x=0:y=0[out];[out][2]overlay=enable='between(t,4,8)':x=0:y=0[out];[out][3]overlay=enable='between(t,8,12)':x=0:y=0 output.mp4
If you want to overlay an animated image on top of a video, simply replace the PNG input from the previous examples. For example, if we want to add a GIF in the top-left corner, we can use the following command:
$ ffmpeg -i video.mp4 -stream_loop -1 -i overlay.gif -filter_complex [0][1]overlay=x=0:y=0:shortest=1 output.mp4