Skip to main content

iterframes

PyPI CI Documentation

Video frames as NumPy arrays, decoded while your code is busy with the last one.

import iterframes

for frame in iterframes.read("video.mp4", height=224, width=224):
    model(frame)  # (224, 224, 3) uint8 RGB, resized by FFmpeg, no copy

model runs on one frame while a Rust thread decodes the next ones. That thread never takes the GIL, so decoding overlaps with your work instead of adding to it, even when your code is pure Python. pip install iterframes brings FFmpeg with it: nothing else to install, no system packages, no ffmpeg binary to call.

The landing page at alesanfra.github.io/iterframes shows what the decoder does while your loop runs. The documentation is at iterframes.readthedocs.io: the guides explain the features, the API documents every argument and error, and the development guide covers building from source.

Numbers

One video, 901 frames of 480x270 H.264, decoded and converted to RGB, best of seven runs on an Apple silicon Mac with the bundled FFmpeg 9.0.2. The benchmarks are in tests/test_benchmark.py; run them on your own videos before believing them.

Time
Every frame, iterframes 0.046 s
Every frame, PyAV, same decode and conversion 0.208 s
32 frames at random positions 0.036 s
First 10 frames (stop=10) 0.003 s
Second half (start=450) 0.028 s

In the overlap benchmark, which upscales the same video to 1080p, adding per-frame work as expensive as decoding took 16% longer in total, not twice as long: the decoding had already happened.

What you get

  • Frames without copies. RGB uint8 arrays of shape (height, width, 3), straight out of FFmpeg's buffers.
  • Batches as one array. read_batches decodes into a single (batch, height, width, 3) block, ready for a model.
  • Resizing while decoding, not a cv2.resize afterwards, from nearest to Lanczos.
  • Random access. Read frames by number, without decoding the rest.
  • Hardware decoding on NVIDIA GPUs (NVDEC) and Apple silicon (VideoToolbox), in the wheels. On NVIDIA the frames can stay on the GPU for PyTorch.
  • Wheels for Linux (x86_64, aarch64), macOS (Apple silicon), and Windows, for every CPython from 3.11 on.
# Batches of 12 frames, decoded into one (12, 224, 224, 3) array
for batch in iterframes.read_batches("video.mp4", 12, height=224, width=224):
    ...

# Stop whenever you like; the decoder stops with the loop
for index, frame in enumerate(iterframes.read("video.mp4")):
    if index == 100:
        break

Random access

Sample clips for training, or grab a thumbnail, without reading the whole file:

clip = list(iterframes.read("video.mp4", frames=[0, 30, 60]))
every_fifth = iterframes.read("video.mp4", start=100, stop=200, step=5)
last = next(iterframes.read("video.mp4", frames=[-1]))

Both work with read_batches. Negative numbers count from the end, and frame n is the one read yields n-th. iterframes indexes the file once, without decoding it, then decodes each frame from the key frame before it; frames asked for in order cost no more than reading the video straight through. See Reading frames by number.

When a frame nearby will do, approximate reads the key frame closest to each of frames, which costs one decoded frame instead of the frames from the key frame on:

# The nearest key frame within 5 frames, else the frame itself.
frames = list(iterframes.read("video.mp4", frames=[100, 200, 300], approximate=5))

See Approximate frames.

Hardware decoding

Pass device to decode on a GPU instead of the CPU, which then stays free for your model. The names are PyTorch's:

# NVIDIA GPU on Linux and Windows; with height and width, the GPU resizes too
for frame in iterframes.read("video.mp4", height=224, width=224, device="cuda"):
    ...

# Apple silicon (VideoToolbox)
for frame in iterframes.read("video.mp4", device="mps"):
    ...

# Whatever the machine has, else the CPU
for frame in iterframes.read("video.mp4", device="auto"):
    ...

print(iterframes.DEVICES)  # ('cpu', 'mps') on a Mac

The frames still arrive as NumPy arrays in memory. A GPU saves CPU time but is not always faster than the CPU decoder, so measure both; see Hardware decoding.

With an NVIDIA GPU, on_device=True keeps the frames on it, in NV12, for PyTorch and other libraries to take without a copy:

import torch

for frame in iterframes.read("video.mp4", device="cuda", on_device=True):
    y = torch.from_dlpack(frame.y)    # (height, width) uint8, on the GPU
    uv = torch.from_dlpack(frame.uv)  # (height / 2, width / 2, 2)

Frames on the GPU shows how to convert them to RGB there.

Compared with OpenCV, decord, and PyAV

iterframes OpenCV VideoCapture decord PyAV
Decoding runs Ahead of your code, on a background thread When you call read() When you index the reader When you ask for the next frame
Pixels RGB BGR RGB Any format FFmpeg supports
Resize while decoding Yes No, with cv2.resize after Yes Yes, with reformat
Batches as one array Yes, read_batches No Yes, get_batch No
Seeking and random access Yes, frames=[...] or start, stop, step Yes Yes, fast Yes
Audio, encoding, muxing No Encoding with VideoWriter Audio reading Yes
Hardware decoding NVIDIA, Apple silicon, in the wheels Depends on the build and backend NVIDIA, when built from source Depends on the build
Latest wheels Linux, macOS, Windows, CPython 3.11+ Linux, macOS, Windows x86_64 only, last release in 2021 Linux, macOS, Windows

Pick iterframes to read videos into a model, in order or by frame number, and keep decoding out of your loop's way. Pick PyAV when you need the rest of FFmpeg: audio, encoding, streams, or precise control over the decoder. OpenCV is the natural choice when the rest of the pipeline already uses it.

Installation

pip install iterframes

The wheels bundle FFmpeg and work on any CPython from 3.11 on, on Linux (x86_64, aarch64), macOS (Apple silicon), and Windows (x86_64). Other platforms build from source, FFmpeg included.

Contributing

Contributions are welcome. The development guide lists features that are waiting for someone to build them.

License

iterframes is released under the Apache License 2.0. The wheels include FFmpeg, built under the LGPL, and dav1d, under the BSD 2-clause license. They are listed in NOTICE, with their license texts in licenses/.

Metadata

Release files for iterframes 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for iterframes 0.7.0
File Size Uploaded
iterframes-0.7.0.tar.gz 1.5 MB Details

Built distributions (wheels)

Table of built distributions (wheels) for iterframes 0.7.0
File
iterframes-0.7.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
iterframes-0.7.0-cp311-abi3-manylinux_2_28_x86_64.whl CPython 3.11 abi3 Linux glibc 2.28+ x86-64 Details
iterframes-0.7.0-cp311-abi3-manylinux_2_28_aarch64.whl CPython 3.11 abi3 Linux glibc 2.28+ ARM64 Details
iterframes-0.7.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details

Total release size: 36.4 MB

Release files / iterframes-0.7.0.tar.gz

Download URL iterframes-0.7.0.tar.gz
Size 1.5 MB
Tags Source
SHA-256 checksum
How to use checksums
dc613230d16cc47b2efe4358143f7efe64559cacf2f436c68460b824ded8dde1
BLAKE2b-256 checksum
How to use checksums
d06ba04e23cf26077e60528deabba879e086a6c5a2a0a7b25b849f4dfbd68036
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / iterframes-0.7.0-cp311-abi3-win_amd64.whl

Download URL iterframes-0.7.0-cp311-abi3-win_amd64.whl
Size 7.5 MB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
974a03cf2470265aec9aa758e849f9413999c23c337636f7612d6a3320233ad1
BLAKE2b-256 checksum
How to use checksums
95bfc778893da5b95c9d25d8d8db3a993e1b45d54eeb7f4385546f9e69b5aba6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / iterframes-0.7.0-cp311-abi3-manylinux_2_28_x86_64.whl

Download URL iterframes-0.7.0-cp311-abi3-manylinux_2_28_x86_64.whl
Size 10.1 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
1d62a050f27b7add970e4dd34a7e52ffd84dfd198de8b191108f5907db3d2bea
BLAKE2b-256 checksum
How to use checksums
3fa920b798fbe471f6b538bcf0b3e9c18caff7b1f606b45a0a12079f15ae8f92
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / iterframes-0.7.0-cp311-abi3-manylinux_2_28_aarch64.whl

Download URL iterframes-0.7.0-cp311-abi3-manylinux_2_28_aarch64.whl
Size 9.5 MB
Tags CPython 3.11 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
53a506e744b0858d859746931c877f3c255ebbf193c749cc4fe991245a0abb35
BLAKE2b-256 checksum
How to use checksums
2c4554c2f5b83a3a244ed12bca229913abf98713a628f58ab544efe27679f862
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / iterframes-0.7.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL iterframes-0.7.0-cp311-abi3-macosx_11_0_arm64.whl
Size 7.7 MB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
7aa02c959eb452fee87e8ae985db99b10459a3cf1df6a5d24788a35aa9afbe11
BLAKE2b-256 checksum
How to use checksums
ec25e2f5ffd8550e0905109bc31aa7dbb9a9b8a3bbc9ce68a497e3ba34afd3f4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.7.0 This release

5 release files

0.6.0

5 release files

0.5.0

5 release files

0.4.0

4 release files

0.2.0

2 release files

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page