[Python] How to get webam frames one by one but also compressed?

Discussão em 'Python' iniciado por Stack, Março 29, 2025.

  1. Stack

    Stack Membro Participativo

    I need to grab frames from the webcam of a laptop, transmit them one by one and the receiving side stitch them into a video. I picked ffmpeg-python as wrapper of choice and the example from the docs works right away:

    #!/usr/bin/env python

    # In this file: reading frames one by one from the webcam.


    import ffmpeg

    width = 640
    height = 480


    reader = (
    ffmpeg
    .input('/dev/video0', s='{}x{}'.format(width, height))
    .output('pipe:', format='rawvideo', pix_fmt='yuv420p')
    .run_async(pipe_stdout=True)
    )

    # This is here only to test the reader.
    writer = (
    ffmpeg
    .input('pipe:', format='rawvideo', pix_fmt='yuv420p', s='{}x{}'.format(width, height))
    .output('/tmp/test.mp4', format='h264', pix_fmt='yuv420p')
    .overwrite_output()
    .run_async(pipe_stdin=True)
    )


    while True:
    chunk = reader.stdout.read(width * height * 1.5) # yuv
    print(len(chunk))
    writer.stdin.write(chunk)


    Now for the compression part.

    My reading of the docs is that the input to the reader perhaps needs be rawvideo but nothing else does. I tried replacing rawvideo with h264 in my code but that resulted in empty frames. I'm considering a third invocation looking like this but is that really the correct approach?

    encoder = (
    ffmpeg
    .input('pipe:', format='rawvideo', pix_fmt='yuv420p', s='{}x{}'.format(width, height))
    .output('pipe:', format='h264', pix_fmt='yuv420p')
    .run_async(pipe_stdin=True, pipe_stdout=True)

    Continue reading...

Compartilhe esta Página