Caveats

Authority of Documentation

FFmpeg is extremely complex, and the PyAV developers have not been successful in making it 100% clear to themselves in all aspects. Our understanding of how it works and how to work with it is via reading the docs, digging through the source, performing experiments, and hearing from users where PyAV isn’t doing the right thing.

Only where this documentation is about the mechanics of PyAV can it be considered authoritative. Anywhere that we discuss something that is about the underlying FFmpeg libraries comes with the caveat that we can not be 100% sure on it. It is, unfortunately, often on the user to understand and deal with edge cases. We encourage you to bring them to our attention via GitHub so that we can try to make PyAV deal with it.

Unsupported Features

Our goal is to provide all of the features that make sense for the contexts that PyAV would be used in. If there is something missing, please reach out on GitHub or open a feature request (or even better a pull request). Your request will be more likely to be addressed if you can point to the relevant FFmpeg API documentation.

Sub-Interpreters

PyAV can enable Cython’s per-interpreter module state as experimental groundwork, but it still cannot be imported by CPython sub-interpreters with their own GIL. Cython extension types continue to share internal vtable state between interpreters; repeated or concurrent interpreter creation can crash the process (Cython issue #6445). PyAV will not declare compatibility with own-GIL sub-interpreters until Cython supports extension types safely across interpreters.

Garbage Collection

PyAV currently has a number of reference cycles that make it more difficult for the garbage collector than we would like. In some circumstances (usually tight loops involving opening many containers), a Container will not auto-close until many a few thousand have built-up.

Until we resolve this issue, you should explicitly call Container.close() or use the container as a context manager:

with av.open(path) as container:
    # Do stuff with it.