Skip to main content

Simple Video Utils

Lightweight utilities for extracting frames and metadata from videos. Built for sign language processing workflows.

Python License

Installation

pip install simple-video-utils

Usage

Extract Video Metadata

from simple_video_utils.metadata import video_metadata

meta = video_metadata("video.mp4")
print(f"{meta.width}x{meta.height} @ {meta.fps} fps, {meta.duration}s")
# Output: VideoMetadata(width=1920, height=1080, fps=30.0, nb_frames=450, time_base='1/15360', duration=15.0)

Keyframe Indices (GOP Structure)

from simple_video_utils.metadata import keyframe_indices

keys = keyframe_indices("video.mp4")
# Presentation-order frame indices of the keyframes, e.g. [0, 250, 500]
# Demux-only (no decoding) — cheap even for long videos.

Read Frames from File

from simple_video_utils.frames import read_frames_exact

# Read specific frame range (inclusive)
frames = list(read_frames_exact("video.mp4", start_frame=0, end_frame=10))
# Returns 11 frames as numpy arrays (H, W, 3) in RGB format

# Read from frame to end of video
frames = list(read_frames_exact("video.mp4", start_frame=5, end_frame=None))

# Downsample to a target frame rate (drops frames uniformly, never duplicates)
frames = list(read_frames_exact("video.mp4", fps=15))

One Open, Many Reads

from simple_video_utils.metadata import open_video, video_metadata_from_container, keyframe_indices
from simple_video_utils.frames import read_frames_exact

# Metadata + windowed frame reads from a single container open —
# e.g. sampling indices from metadata, then decoding just that window.
with open_video("video.mp4") as video:
    meta = video_metadata_from_container(video)
    keys = keyframe_indices(video)
    frames = list(read_frames_exact(video, start_frame=10, end_frame=20))

Every helper rewinds the container before reading, so call order doesn't matter. Requires seekable input; consume one frame read at a time.

open_video sets the container's decode thread_type up front (default "AUTO") — PyAV forbids changing it once a stream's codec is open, which happens on first metadata probe or frame read. Pass thread_type="NONE" if you fork worker processes around decoding (e.g. a DataLoader): an inherited AUTO-threaded decoder can deadlock post-fork.

Read Frames from Stream

from simple_video_utils.frames import read_frames_from_stream

# Useful for uploaded files or in-memory video data
with open("video.mp4", "rb") as f:
    meta, frames_gen = read_frames_from_stream(f)
    for frame in frames_gen:
        # Process each frame (numpy array)
        pass

Slice into Clips

from simple_video_utils.slicing import slice_video

# One MP4 (bytes) per (start, end) second range
clips = slice_video("video.mp4", [(0.0, 1.5), (2.0, 3.2)])

# Center-crop to a square and resize to 256x256 (e.g. for model input)
clips = slice_video("video.mp4", [(0.0, 1.5)], size=256)

Clips are streamable MP4 (moov first), so a consumer can demux them from a pipe or socket without seeking.

Split an incoming video stream into packet-copied clips as it arrives — each clip is yielded as soon as its window has been read, without re-encoding. Each carries its start on the source timeline, which counting the clips does not give you: an empty window yields nothing while the timeline moves past it.

from simple_video_utils.slicing import slice_video_stream

with open("video.mp4", "rb") as stream:
    for start, data in slice_video_stream(stream, duration=0.5):
        process(start, data)

Join clips in order. Overlapping slices from the same encoded stream are de-duplicated and remuxed losslessly; anything else is decoded and encoded once as H.264 MP4:

from simple_video_utils.joining import join_videos

video = join_videos(clips)

Remote Videos

from simple_video_utils.metadata import video_metadata
from simple_video_utils.frames import read_frames_exact

# Works with remote URLs
url = "https://example.com/video.mp4"
meta = video_metadata(url)
frames = list(read_frames_exact(url, 0, 5))

Development

pip install -e ".[dev]"
pytest tests/
ruff check .

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simple_video_utils-0.9.1.tar.gz (39.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simple_video_utils-0.9.1-py3-none-any.whl (24.3 kB view details)

Uploaded Python 3

File details

Details for the file simple_video_utils-0.9.1.tar.gz.

File metadata

  • Download URL: simple_video_utils-0.9.1.tar.gz
  • Upload date:
  • Size: 39.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for simple_video_utils-0.9.1.tar.gz
Algorithm Hash digest
SHA256 7d20e1782266354395c2752686a0e2cc0465f5710558d694615111f01561fa9a
MD5 b97948fa6c5d5233fd2d52cb3c73849c
BLAKE2b-256 b1c17861f8c887dd63888cee600242cd1e98350469365a06850e2b238ea398ac

See more details on using hashes here.

Provenance

The following attestation bundles were made for simple_video_utils-0.9.1.tar.gz:

Publisher: release.yaml on sign/simple-video-utils

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file simple_video_utils-0.9.1-py3-none-any.whl.

File metadata

File hashes

Hashes for simple_video_utils-0.9.1-py3-none-any.whl
Algorithm Hash digest
SHA256 93166682ebbcc735f4d2022c088d93fe09a15ad2614b7a1fa3fd18c05ed4dd93
MD5 7536417e74418d6768ebb97ba3e9f537
BLAKE2b-256 fc39ba951f21641e11870a9075cb7a313acca984d5d07aa73941640c270fc5b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for simple_video_utils-0.9.1-py3-none-any.whl:

Publisher: release.yaml on sign/simple-video-utils

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.9.1 This release

2 files

0.9.0

2 files

0.8.0

2 files

0.7.4

2 files

0.7.3

2 files

0.7.2

2 files

0.7.1

2 files

0.7.0

2 files

0.6.0

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.1

2 files

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