GPU frame ripper. Kill ffmpeg.
Project description
<<<<<<< HEAD
ripd
GPU frame ripper. Kill ffmpeg.
Hardware-accelerated video frame extraction using NVIDIA NVDEC. Zero subprocess overhead. Native resolution. 6× faster than ffmpeg on a T4.
pip install ripd
ripd video.mp4 --output ./frames
The problem with ffmpeg
Every ML team extracting training data from video does this:
subprocess.Popen(["ffmpeg", "-i", video, "-vf", "scale=448:256", ...])
Three compounding problems:
- Subprocess overhead — one OS process per video clip. At 1,000 clips per tar, that's 1,000 process creations.
- CPU decode — ffmpeg decodes on CPU. Your GPU sits idle while one CPU core maxes out.
- Forced downscale — scripts hardcode a target resolution because that's the only sane way to normalize mixed-resolution datasets when you don't have a proper crop strategy. You permanently discard the original detail.
Result: ~14 hours to extract 100 Kinetics tars. One CPU core saturated. A dataset of 448×256 JPEGs that's already thrown away everything above that resolution.
The fix
ripd uses PyNvVideoCodec 2.0.2 — NVIDIA's own Python binding for the NVDEC hardware decoder — to decode frames directly on-GPU with zero subprocess overhead and no forced resize.
| Pipeline | Time (100 tars) | CPU impact | Output resolution | Concurrent training |
|---|---|---|---|---|
| ffmpeg subprocess | ~14 hours | 100% one core | Forced 448×256 | Degrades training speed |
| ripd | ~2.25 hours | ~5% (NVDEC only) | Native | No impact |
6× faster. ~0 CPU cost. Full-resolution output.
The NVDEC engine on any modern NVIDIA GPU is completely separate from the CUDA compute cores. Running it at 100% has zero measurable impact on a concurrently training neural network.
Install
pip install ripd
Requirements:
- NVIDIA GPU with NVDEC support (Turing/RTX 20xx or newer recommended)
- CUDA driver ≥ 525
- Python 3.10+
PyNvVideoCodec:pip install PyNvVideoCodec
Usage
CLI
# Extract frames from a single video at 10 FPS
ripd video.mp4 --output ./frames
# Extract at 5 FPS, PNG format
ripd video.mp4 --output ./frames --fps 5 --format png
# Extract training triplets (im1/im2/im3)
ripd video.mp4 --output ./triplets --mode triplet --max_triplets 10
# Extract from a URL (requires yt-dlp)
ripd --url "https://example.com/clip.mp4" --output ./frames
# Extract from a directory of videos
ripd --videos_dir ./raw_videos --output ./frames
# Extract from Kinetics .tar.gz archives
ripd --tars_dir ./kinetics_tars --output ./triplets --mode triplet
# Cap resolution (aspect-preserving)
ripd video.mp4 --output ./frames --max_size 720
# Dry run — count frames without writing
ripd video.mp4 --output ./frames --dry_run
Python API
import ripd
# Extract frames
n = ripd.extract_frames("clip.mp4", "./frames", fps=10)
print(f"Extracted {n} frames")
# Extract triplets for VSR training
n = ripd.extract_triplets("clip.mp4", "./triplets", max_triplets=5)
print(f"Extracted {n} triplets")
# Download from URL first
video_path = ripd.download_url("https://example.com/clip.mp4", "./tmp")
n = ripd.extract_frames(video_path, "./frames")
Triplet output format
Compatible with PyTorch DataLoader with no intermediate processing:
triplets/
clip_00/
im1.jpg ← frame at t₀
im2.jpg ← frame at t₁ ← training target (center)
im3.jpg ← frame at t₂
clip_01/
...
Cloud API
Don't have a local NVIDIA GPU? Use the hosted API:
# Extract triplets from a video file
curl -X POST "https://seiferm80--ripd-fastapi-app.modal.run/v1/extract/triplets?max_triplets=5" \
-F "file=@clip.mp4" \
--output triplets.zip
# Extract frames at 5 FPS
curl -X POST "https://seiferm80--ripd-fastapi-app.modal.run/v1/extract/frames?fps=5" \
-F "file=@clip.mp4" \
--output frames.zip
Interactive docs: https://seiferm80--ripd-fastapi-app.modal.run/docs
Deploy your own instance
pip install ripd[deploy]
modal deploy deploy/modal_app.py
Why native resolution matters
Pre-scaling to 448×256 before saving means:
- The dataset captures bicubic interpolation artifacts, not real video content
- You permanently lose the ability to train at higher crop sizes later
With native resolution, a 256×256 random crop from a 1080p frame is a window into genuine high-frequency detail — motion blur, film grain, compression artifacts — that the model learns to resolve.
License
Apache 2.0 — see LICENSE
Built at M80AI.
Ripd 🗡️
Rips video frames 6x faster than ffmpeg — built for ML training datasets.
No more waiting. No more CLI hell. Just clean, lossless frames in seconds.
ade075770daeef017ccd0892d3db0a7a88288a6f
Project details
Release history Release notifications | RSS feed
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 ripd-0.1.0.tar.gz.
File metadata
- Download URL: ripd-0.1.0.tar.gz
- Upload date:
- Size: 13.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bdd4c39c0bf27c5cee0c2aa306223e11d11d816e6a11f0fa82ba4d329f25ab81
|
|
| MD5 |
73729f0fda0e3b8c142520b1a55289cd
|
|
| BLAKE2b-256 |
54f56b4ccb6cd95fa328b0c60ce4849381b9e595d5ebbe0c289605c462fdf419
|
File details
Details for the file ripd-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ripd-0.1.0-py3-none-any.whl
- Upload date:
- Size: 11.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb8faddb980c44787ddb898fe924f2835da88cd8f842a30048b0593c0eeca866
|
|
| MD5 |
d6331c58225ef1e10ea49ee07df90097
|
|
| BLAKE2b-256 |
96159d15c49a5b1038245e40efbeb7deb19c91927be376ab8e079607c40fd250
|