[Python] How to dynamically overlay images with ffmpeg

Discussão em 'Python' iniciado por Stack, Maio 20, 2025.

  1. Stack

    Stack Membro Participativo

    As a part of a bigger project, I'm trying to stream a live feed using ffmpeg through RTSP while also dynamically changing subtitles depending on the situation.

    As of now, I'm able to live stream with no issue. I also came across a solution for the subtitles by using a text file.

    However, I'd like to avoid having this text file in my project. I thought about creating a picture with the subtitles and overlaying it with the screen stream. However, with my current solution, the data is streamed only when I kill the running code (data streamed for a few seconds).

    Here is the current code for this problem :

    import subprocess
    import threading
    import string
    import random
    import time
    import io
    from PIL import Image, ImageDraw, ImageFont

    RTSP_URL = "..."
    ffmpeg = None

    def generate_subtitle():
    width = 640
    height = 100
    font_size = 32
    while True:
    if ffmpeg:
    try:
    text = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(10))

    image = Image.new("RGBA", (width, height), (0, 0, 0, 128))
    draw = ImageDraw.Draw(image)

    try:
    font = ImageFont.truetype("arial.ttf", font_size)
    except IOError:
    font = ImageFont.load_default()

    bbox = draw.textbbox((0, 0), text, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]

    x = (width - text_width) // 2
    y = (height - text_height) // 2

    draw.text((x, y), text, font=font, fill=(255, 255, 255, 255))
    buffer = io.BytesIO()
    image.save(buffer, format="PNG")
    ffmpeg.stdin.write(buffer.getvalue())
    ffmpeg.stdin.flush()
    time.sleep(5)
    except Exception as e:
    print("Erreur d'envoi d'image :", e)
    break
    else:
    time.sleep(1)

    def run_ffmpeg():
    global ffmpeg
    ffmpeg = subprocess.Popen([
    'ffmpeg',

    # Input 0: capture desktop
    "-f", "gdigrab",
    "-offset_x", "0",
    "-offset_y", "0",
    "-video_size", "1920x1080",
    "-i", "desktop",

    # Input 1: PNG overlay from stdin
    "-f", "image2pipe",
    "-vcodec", "png",
    "-i", "-",

    # Filter to overlay Input 1 on Input 0
    "-filter_complex", "[0:v][1:v]overlay=(main_w-overlay_w)/2:(main_h-overlay_h)-10",

    # Output settings
    "-vcodec", "libx264",
    "-preset", "ultrafast",
    "-tune", "zerolatency",
    "-g", "30",
    "-sc_threshold", "0",
    "-f", "rtsp",
    RTSP_URL
    ], stdin=subprocess.PIPE)

    threading.Thread(target=run_ffmpeg, daemon=True).start()

    threading.Thread(target=generate_subtitle, daemon=True).start()

    while True:
    time.sleep(1)



    My question is how can I stream the data correctly ? If there is another solution to change dynamically the subtitles without using a text file or a temporary file I'd be glad to hear it.

    Continue reading...

Compartilhe esta Página