Skip to content

Ffmpeg-python

ffmpeg-python: Python bindings for FFmpeg.

pygame으로 실시간 랜더링하기

import ffmpeg
import cv2
import numpy as np
import pygame
import sys
import os
from OpenGL import GL


os.environ["SDL_VIDEO_X11_FORCE_EGL"] = "1"

# Define a function to read frames from ffmpeg stdout
def read_frame_from_stdout(pipe, width, height):
    raw_image = pipe.stdout.read(width * height * 3)
    if len(raw_image) == width * height * 3:
        image = np.frombuffer(raw_image, np.uint8)
        image = image.reshape((height, width, 3))
        return image
    return None

# Define a function to initialize ffmpeg process
def init_ffmpeg_process(video_path, width, height):
    return (
        ffmpeg
        .input(video_path)
        .filter('scale', width, height)
        .output('pipe:', format='rawvideo', pix_fmt='rgb24')
        .run_async(pipe_stdout=True)
    )

# Main function to set up pygame and pyimgui
def main():
    width, height = 400, 300  # Size for each video window
    cols = 4
    rows = 4
    size = cols * rows
    total_width, total_height = width * cols, height * rows  # Overall window size

    video_files = ['/home/username/Downloads/ddrm/original/main/20240424_112118-959629.mp4'] * size
    processes = [init_ffmpeg_process(file, width, height) for file in video_files]

    # Initialize pygame and create the window
    pygame.init()
    screen = pygame.display.set_mode((total_width, total_height))
    pygame.display.set_caption(f'pyimgui with pygame - {size} Videos')

    clock = pygame.time.Clock()
    running = True

    while running:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
                break

        screen.fill((0, 0, 0))  # Clear the screen

        for idx, process in enumerate(processes):
            frame = read_frame_from_stdout(process, width, height)
            if frame is not None:
                frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                image_surface = pygame.image.frombuffer(frame_rgb.tobytes(), (width, height), 'RGB')

                # Calculate the position in the 2x2 grid
                pos_x = (idx % rows) * width
                pos_y = (idx // rows) * height
                screen.blit(image_surface, (pos_x, pos_y))

        pygame.display.flip()
        clock.tick(30)  # Limit to 30 FPS

    for process in processes:
        process.stdout.close()
        process.wait()

    pygame.quit()

if __name__ == "__main__":
    main()

Python binding

See also

Favorite site