Search code examples
pythonffmpeg

How to overlay a box on a transparent video in FFmpeg


I'm trying to overlay a box and image on a transparent video in FFmpeg and Python, and have it show up in video editors.

I've written the following code:

import ffmpeg

stream = ffmpeg.input("/dev/zero", f='rawvideo', pix_fmt='rgba', s='{}x{}'.format(1920, 1080),
                              r=30)

stream = ffmpeg.overlay(stream, ffmpeg.input("tmp.png"), x=0, y=0)
stream = ffmpeg.drawbox(stream, x=900, y=100, width=500, height=500, color='blue', thickness="fill")
stream = ffmpeg.trim(stream, duration=1)
stream = ffmpeg.output(stream, "out.webm",
                       pix_fmt="yuva420p")
ffmpeg.run(stream)

While the box displays in most video players:
Clip
When I try to overlay it on another image in any video editor like Kdenlive or Shotcut, or open in FireFox, it doesn't appear:
enter image description here

This seems odd considering the overlayed image displays fine. Is there something wrong with the drawbox call?

EDIT: The same issue occurs when exporting as PNGs, where no frames contain the box when it's not over the image:

stream = ffmpeg.output(stream, "out/out%d.png")

enter image description here


Solution

  • pix_fmt='rgba' gives you a 4 channel video including an alpha channel. Many Video players will matte the alpha channel with black, while others will apply the alpha channel masking the pixels in RGB channels, then show it over a black background or a checked pattern. You may have seen this on GIMP or Photoshop.

    When you use an overlay image, the pixels of the alpha channel of the input video has been replaced by the alpha pixels of the overlay. But this does not happened with draw objects by default. You have to specifically specify it. the default parameter for replace is 0.

    Adding replace=1 will resolve your problem

    stream = ffmpeg.drawbox(stream, x=900, y=100, width=500, height=500, 
                            color='blue', thickness="fill", replace=1)
    

    see the documentation here: https://ffmpeg.org/ffmpeg-filters.html#drawbox