Overlay Image On Video

How to overlay PNG image on top of MP4 video.

Source Video

For a source video we use the MP4 file from the TED talk video What’s the next window into our universe? by Andrew Connolly. The original video format is Wide 480p or 16:9, 854 x 480.

Overlay Image

For overlay image we use iFunnyIcon, but you can use any other image instead. Just make sure the image width and height are of even size, i.e. a multiple of 2. That is a requirement of the AVBlocks overlay filter.

Complete Program

This code overlays a PNG image on top of a MP4 video.

import sys

from avblocks import (
    Library, MediaBuffer, MediaInfo, MediaSocket, Transcoder,
    AlphaCompositingMode, HardwareEncoder, Param, Use
)


def main():
    Library.initialize()

    # Read the overlay image stream info
    with MediaInfo() as image_info:
        image_info.inputs[0].file = "Icon.png"

        if not image_info.open():
            print("image_info.open() failed")
            return 1

        image_format = image_info.outputs[0].pins[0].stream_info.clone()

    # Read the overlay image data
    with open("Icon.png", "rb") as f:
        image_buffer = MediaBuffer(f.read())

    with MediaInfo() as input_info:
        input_info.inputs[0].file = "AndrewConnolly_2014.mp4"

        if input_info.open():
            # create input socket
            input_socket = MediaSocket.from_media_info(input_info)

            # start with an output socket identical to the input socket
            output_socket = input_socket.clone()
            output_socket.file = "AndrewConnolly_2014_With_Overlay.mp4"

            # set overlay parameters
            out_video_pin = output_socket.pins[0]

            # Compositing mode and alpha
            # see https://en.wikipedia.org/wiki/Alpha_compositing
            out_video_pin.params[Param.Video.Overlay.Mode] = int(AlphaCompositingMode.Over)
            out_video_pin.params[Param.Video.Overlay.BackgroundAlpha] = 1.0
            out_video_pin.params[Param.Video.Overlay.ForegroundAlpha] = 0.2

            # position at the top left corner
            out_video_pin.params[Param.Video.Overlay.LocationX] = 0
            out_video_pin.params[Param.Video.Overlay.LocationY] = 0

            # provide the actual image data
            out_video_pin.params[Param.Video.Overlay.ForegroundBuffer] = image_buffer
            out_video_pin.params[Param.Video.Overlay.ForegroundBufferFormat] = image_format

            # force video decoding and encoding. Otherwise
            # video is transferred as is, and the overlay
            # filter is not applied.
            out_video_pin.params[Param.ReEncode] = Use.On

            # enable hardware accelerated encoding (optional)
            out_video_pin.params[Param.HardwareEncoder] = HardwareEncoder.Auto

            # create a transcoder and run it
            with Transcoder() as transcoder:
                transcoder.allow_demo_mode = True

                transcoder.inputs.add(input_socket)
                transcoder.outputs.add(output_socket)

                if transcoder.open():
                    transcoder.run()
                    transcoder.close()

    Library.shutdown()
    return 0


if __name__ == '__main__':
    sys.exit(main())

How to run

Follow the steps in Developing with Visual Studio Code to create a Python project and add AVBlocks, but in simple_converter.py use the code from this article.

Download the AndrewConnolly_2014.mp4 MPEG4 file from the Internet Archive and save it in the project directory.

Download the Icon.png image file from the Internet Archive and save it in the project directory.

Run the application with uv run python simple_converter.py. Wait a few seconds for the Transcoder to finish. The converted file AndrewConnolly_2014_With_Overlay.mp4 will be in the project directory.