{"id":1078,"library":"av","title":"PyAV","description":"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.","status":"active","version":"17.0.0","language":"en","source_language":"en","source_url":"https://github.com/PyAV-Org/PyAV","tags":["video processing","audio processing","ffmpeg","multimedia","bindings"],"install":[{"cmd":"pip install av","lang":"bash","label":"Stable release"},{"cmd":"conda install -c conda-forge pyav","lang":"bash","label":"Conda-forge"}],"dependencies":[],"imports":[{"symbol":"av","correct":"import av"}],"quickstart":{"code":"import av\nimport os\n\n# Create a dummy video file for demonstration\noutput_filename = \"dummy_video.mp4\"\n\n# Encode a simple video (e.g., 1 second of black frames)\n# This part requires numpy, but it's a common dependency for video processing\ntry:\n    import numpy as np\n    duration = 1  # seconds\n    fps = 24      # frames per second\n    total_frames = duration * fps\n    width, height = 640, 480\n\n    with av.open(output_filename, mode=\"w\") as container:\n        stream = container.add_stream(\"mpeg4\", rate=fps)\n        stream.width = width\n        stream.height = height\n        stream.pix_fmt = \"yuv420p\"\n\n        for frame_i in range(total_frames):\n            img = np.zeros((height, width, 3), dtype=np.uint8) # Black frame\n            frame = av.VideoFrame.from_ndarray(img, format=\"rgb24\")\n            for packet in stream.encode(frame):\n                container.mux(packet)\n\n        # Flush stream\n        for packet in stream.encode():\n            container.mux(packet)\n\n    print(f\"Successfully created dummy video: {output_filename}\")\n\n    # --- Decoding and processing part of the quickstart ---\n    container = av.open(output_filename)\n\n    for frame in container.decode(video=0):\n        print(f\"Decoded frame {frame.index} with PTS {frame.pts}\")\n        # Example: Save the first frame\n        if frame.index == 0:\n            frame.to_image().save(f\"frame-{frame.index:04d}.jpg\")\n            print(f\"Saved frame-0000.jpg\")\n        break # Only process the first frame for this quickstart\n\n    container.close()\n    print(\"Container closed.\")\n\nexcept ImportError:\n    print(\"NumPy not found. Skipping video creation. To run the full quickstart, install numpy (pip install numpy).\")\n    print(f\"Please ensure '{output_filename}' exists for the decoding example, or create it manually.\")\n    # Attempt to decode if a file exists, otherwise skip\n    if os.path.exists(output_filename):\n        container = av.open(output_filename)\n        for frame in container.decode(video=0):\n            print(f\"Decoded frame {frame.index} with PTS {frame.pts}\")\n            break\n        container.close()\n    else:\n        print(\"No video file to decode without NumPy.\")\nfinally:\n    # Clean up the dummy video file\n    if os.path.exists(output_filename):\n        os.remove(output_filename)\n        print(f\"Cleaned up {output_filename}\")\n    if os.path.exists(\"frame-0000.jpg\"):\n        os.remove(\"frame-0000.jpg\")\n        print(f\"Cleaned up frame-0000.jpg\")","lang":"python","description":"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."},"warnings":[{"fix":"Update exception handling blocks to catch `av.ArgumentError` specifically for FFmpeg-originated argument errors, or `av.FFmpegError` for all FFmpeg-related errors. You can still catch `ValueError` if broader compatibility is needed, as `av.ArgumentError` inherits from it.","message":"As of v17.0.0, when an FFmpeg C function indicates an error, PyAV now raises `av.ArgumentError` instead of `ValueError`/`av.ValueError`. This helps to more precisely distinguish the source of an exception.","severity":"breaking","affected_versions":">=17.0.0"},{"fix":"Always use `with av.open(...) as container:` for opening containers. For streams obtained from output containers, ensure you call `.close()` on the stream after encoding all frames, and then call `.close()` on the container.","message":"Containers (`av.Container`) and streams (`av.Stream`) must be explicitly closed to ensure all data is flushed and resources are properly released, preventing potential data loss or memory leaks. Using them as context managers (`with av.open(...) as container:`) is the recommended practice.","severity":"gotcha","affected_versions":"all"},{"fix":"For development and debugging, enable verbose logging: `import av; av.logging.set_level(av.logging.VERBOSE)`. This will provide more descriptive error messages and operational details from the underlying FFmpeg libraries.","message":"PyAV disables FFmpeg's verbose logging by default, which can obscure detailed error messages. While this reduces console noise, it can make debugging challenging when issues arise.","severity":"gotcha","affected_versions":"all"},{"fix":"When iterating through `container.decode()` or `codec.decode()`, continue processing until no more frames are yielded. After processing all input packets, ensure a final flush by iterating `codec.decode()` or `stream.encode()` with `None` or no arguments until no more packets/frames are returned.","message":"When decoding, a single input packet does not always guarantee an output frame, and multiple packets might be required to produce a single frame. Additionally, it's crucial to 'flush' the decoder by sending `None` or empty packets at the end of the input stream to retrieve any remaining buffered frames.","severity":"gotcha","affected_versions":"all"},{"fix":"Prefer installing PyAV via pre-built wheels (`pip install av`) or `conda-forge` (`conda install -c conda-forge pyav`) as these typically include all necessary FFmpeg dependencies and handle linking. If building from source is unavoidable, carefully follow the official documentation's instructions for setting up the FFmpeg development environment and addressing system-specific linking requirements.","message":"Building PyAV from source, especially on Windows or with specific Python versions (e.g., Python 3.10 historically), can lead to `ImportError` or `ModuleNotFoundError` due to issues with dynamic library linking (DLLs on Windows) or internal Python API changes.","severity":"gotcha","affected_versions":"Installation from source on certain platforms/Python versions (e.g., Python 3.10 and earlier on Windows)"}],"env_vars":null,"last_verified":"2026-04-07T00:14:18.568Z","next_check":"2026-07-04T00:00:00.000Z"}