Simple Video Utils
Lightweight utilities for extracting frames and metadata from videos. Built for sign language processing workflows.
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)
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simple_video_utils-0.9.0.tar.gz.
File metadata
- Download URL: simple_video_utils-0.9.0.tar.gz
- Upload date:
- Size: 38.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1e016f96017bf560920f192a1551eda64aeadbb818e8ac18da3a0f215ad1818
|
|
| MD5 |
651af22a2054786cf566ad45eece4e4e
|
|
| BLAKE2b-256 |
8285ffe0047df9a0d18433954c3117266463dadea7659e45cb835e5c41849f74
|
Provenance
The following attestation bundles were made for simple_video_utils-0.9.0.tar.gz:
Publisher:
release.yaml on sign/simple-video-utils
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
simple_video_utils-0.9.0.tar.gz -
Subject digest:
f1e016f96017bf560920f192a1551eda64aeadbb818e8ac18da3a0f215ad1818 - Sigstore transparency entry: 2688100001
- Sigstore integration time:
-
Permalink:
sign/simple-video-utils@f2398dcb144ee61cc6dbbf89748d6d2fbe4de166 -
Branch / Tag:
refs/tags/v0.9.0 - Owner: https://github.com/sign
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@f2398dcb144ee61cc6dbbf89748d6d2fbe4de166 -
Trigger Event:
release
-
Statement type:
File details
Details for the file simple_video_utils-0.9.0-py3-none-any.whl.
File metadata
- Download URL: simple_video_utils-0.9.0-py3-none-any.whl
- Upload date:
- Size: 24.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f6d271ab37614264aafd23410beef26932c54fbce52b4a304de2583173c1cc2
|
|
| MD5 |
fb084f56ae8d8eaa478af5829053e251
|
|
| BLAKE2b-256 |
19fcdbf954610996b6da150c8fa2ab15cd95dc75d4ecc4e2e4032274117d3012
|
Provenance
The following attestation bundles were made for simple_video_utils-0.9.0-py3-none-any.whl:
Publisher:
release.yaml on sign/simple-video-utils
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
simple_video_utils-0.9.0-py3-none-any.whl -
Subject digest:
2f6d271ab37614264aafd23410beef26932c54fbce52b4a304de2583173c1cc2 - Sigstore transparency entry: 2688100068
- Sigstore integration time:
-
Permalink:
sign/simple-video-utils@f2398dcb144ee61cc6dbbf89748d6d2fbe4de166 -
Branch / Tag:
refs/tags/v0.9.0 - Owner: https://github.com/sign
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yaml@f2398dcb144ee61cc6dbbf89748d6d2fbe4de166 -
Trigger Event:
release
-
Statement type: