PyAV

17.0.0 · active · verified Sun Apr 05

PyAV is a Pythonic binding for FFmpeg's libraries, providing direct and precise access to media via containers, streams, packets, codecs, and frames. It aims to expose the full power and control of the underlying FFmpeg library while managing lower-level details where possible. The current version is 17.0.0, and releases generally follow significant FFmpeg updates or major feature additions.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to create a simple video file (requires NumPy) and then open, decode, and extract a frame using PyAV. It highlights the basic `av.open()` for container management and `container.decode()` for frame iteration. Ensure that FFmpeg is properly installed and discoverable by PyAV for full functionality. The example creates a 1-second black video and then decodes its first frame.

import av
import os

# Create a dummy video file for demonstration
output_filename = "dummy_video.mp4"

# Encode a simple video (e.g., 1 second of black frames)
# This part requires numpy, but it's a common dependency for video processing
try:
    import numpy as np
    duration = 1  # seconds
    fps = 24      # frames per second
    total_frames = duration * fps
    width, height = 640, 480

    with av.open(output_filename, mode="w") as container:
        stream = container.add_stream("mpeg4", rate=fps)
        stream.width = width
        stream.height = height
        stream.pix_fmt = "yuv420p"

        for frame_i in range(total_frames):
            img = np.zeros((height, width, 3), dtype=np.uint8) # Black frame
            frame = av.VideoFrame.from_ndarray(img, format="rgb24")
            for packet in stream.encode(frame):
                container.mux(packet)

        # Flush stream
        for packet in stream.encode():
            container.mux(packet)

    print(f"Successfully created dummy video: {output_filename}")

    # --- Decoding and processing part of the quickstart ---
    container = av.open(output_filename)

    for frame in container.decode(video=0):
        print(f"Decoded frame {frame.index} with PTS {frame.pts}")
        # Example: Save the first frame
        if frame.index == 0:
            frame.to_image().save(f"frame-{frame.index:04d}.jpg")
            print(f"Saved frame-0000.jpg")
        break # Only process the first frame for this quickstart

    container.close()
    print("Container closed.")

except ImportError:
    print("NumPy not found. Skipping video creation. To run the full quickstart, install numpy (pip install numpy).")
    print(f"Please ensure '{output_filename}' exists for the decoding example, or create it manually.")
    # Attempt to decode if a file exists, otherwise skip
    if os.path.exists(output_filename):
        container = av.open(output_filename)
        for frame in container.decode(video=0):
            print(f"Decoded frame {frame.index} with PTS {frame.pts}")
            break
        container.close()
    else:
        print("No video file to decode without NumPy.")
finally:
    # Clean up the dummy video file
    if os.path.exists(output_filename):
        os.remove(output_filename)
        print(f"Cleaned up {output_filename}")
    if os.path.exists("frame-0000.jpg"):
        os.remove("frame-0000.jpg")
        print(f"Cleaned up frame-0000.jpg")

view raw JSON →