Video compression pipeline with metric-based keyframe selection
Project description
๐ฌ VidCompressorX
Intelligent video compression powered by perceptual metrics and adaptive keyframe selection.
VidCompressorX is a Python library that uses computer vision and deep learning to intelligently compress videos by identifying and retaining only the most significant frames. By analyzing frame-to-frame differences using multiple perceptual metrics (MSE, SSIM, LPIPS), it achieves substantial compression ratios while maintaining visual quality.
โจ Features
- ๐ง Multi-Metric Analysis โ Combines MSE, SSIM, and LPIPS for intelligent frame comparison
- ๐ฏ Adaptive Thresholding โ Automatically determines optimal keyframe selection thresholds
- ๐ Research-Friendly โ Extensive visualization and analysis tools for experimentation
- ๐ Production-Ready โ Clean API with proper state management and error handling
- ๐ Notebook Compatible โ Progress bars automatically adapt to Jupyter environments
- โก GPU Accelerated โ CUDA support for faster LPIPS computation
๐ Installation
pip install vidcompressorx
Requirements
- Python 3.9 or higher
- FFmpeg (for video encoding)
Install FFmpeg:
- Ubuntu/Debian:
sudo apt install ffmpeg - macOS:
brew install ffmpeg - Windows: Download from ffmpeg.org
๐ Quick Start
Basic Usage
from video_compressor import KeyframeSelector
# Initialize with your video
selector = KeyframeSelector('input_video.mp4')
# Compute frame-to-frame metrics
selector.compute_metrics()
# Select keyframes (adapt_factor controls aggressiveness)
# Higher values = more compression, lower values = more quality
selector.select_keyframes(adapt_factor=1.0)
# Create compressed video
selector.create_compressed_video()
# Check compression results
selector.get_sizes()
Output:
=== SIZE COMPARISON ===
Original: 45.23 MB
Keyframe: 8.91 MB
Reduction: 36.32 MB
Ratio: 5.08x
Advanced Usage
from video_compressor import KeyframeSelector
selector = KeyframeSelector('video.mp4', verbose=True)
# Step 1: Compute metrics
metrics = selector.compute_metrics()
selector.create_metric_file('output_metrics.csv')
# Step 2: Analyze threshold sensitivity
selector.analyze_thresholds(num_factors=20) # Creates plots in plots/
# Step 3: Manual threshold control
selector.select_keyframes(
abs_thres=50.0, # Absolute difference threshold
delta_thres=2.5, # Rate-of-change threshold
adapt_factor=None # Disable adaptive thresholding
)
# Step 4: Export keyframe indices
selector.create_retained_indices_file('keyframes.csv')
# Step 5: Visualize frames
selector.visualize_frames_fullscreen(
start_frame=0,
num_frames=36,
skip=10,
cmap_name='viridis'
)
# Step 6: Create final video
selector.create_compressed_video()
๐ฏ How It Works
1. Metric Computation
VidCompressorX analyzes consecutive frame pairs using three complementary metrics:
- MSE (Mean Squared Error) โ Pixel-level differences
- Inverse SSIM โ Structural similarity changes
- LPIPS โ Perceptual similarity using deep learning (AlexNet)
These are combined into a weighted score:
difference = 0.5 ร MSE + 0.3 ร inv_SSIM + 0.2 ร LPIPS
2. Keyframe Selection
Frames are selected based on two criteria:
- Absolute Threshold โ Frame difference exceeds baseline
- Delta Threshold โ Rate-of-change in difference is significant
keep_frame if (difference > abs_threshold) AND (|ฮdifference| > delta_threshold)
Adaptive thresholding automatically computes these based on video statistics:
threshold = mean(differences) + adapt_factor ร std(differences)
3. Video Reconstruction
Selected keyframes are:
- Extracted as JPEG images
- Encoded with FFmpeg (H.264, CRF 23)
- Compiled into final MP4 at original frame rate
๐ Understanding Adapt Factor
The adapt_factor parameter controls compression aggressiveness:
| Adapt Factor | Retention | Use Case |
|---|---|---|
-2.0 to 0.0 |
80-95% | Minimal compression, high quality |
0.0 to 1.0 |
50-80% | Balanced compression |
1.0 to 3.0 |
20-50% | Aggressive compression |
3.0 to 5.0 |
5-20% | Maximum compression |
Example:
# Conservative (high quality)
selector.select_keyframes(adapt_factor=0.5) # ~70% frames retained
# Balanced
selector.select_keyframes(adapt_factor=1.5) # ~40% frames retained
# Aggressive (high compression)
selector.select_keyframes(adapt_factor=3.0) # ~15% frames retained
๐ฌ Experimentation Tools
VidCompressorX includes standalone scripts for research and analysis:
Compute Metrics Only
python -m experiments.compute_metrics
from experiments.compute_metrics import compute_video_metrics
compute_video_metrics(
video_path='input.mp4',
output_path='metrics.csv',
verbose=True
)
Analyze Threshold Sensitivity
from experiments.keyframes_dist import analyze_thresholds
analyze_thresholds(
csv_path='metrics.csv',
save_all_keyframes=True # Saves CSV for each threshold tested
)
Generates plots showing retention vs. threshold relationships.
Batch Compression Analysis
python -m experiments.plot_compression
Processes multiple keyframe configurations and plots compression curves.
Frame Visualization
python -m experiments.visualize_frames video.mp4 metrics.csv -n 40 -s 10 -c coolwarm
Creates a fullscreen grid of frames color-coded by motion intensity.
Arguments:
-k/--start: Starting frame index (default: 500)-n/--num: Number of frames to display (default: 40)-s/--skip: Skip interval between frames (default: 0)-c/--cmap: Matplotlib colormap (default: 'coolwarm')
๐ Project Structure
vidcompressorx/
โโโ video_compressor/ # Core package
โ โโโ __init__.py # Public API exports
โ โโโ pipeline.py # KeyframeSelector class
โ โโโ metrics.py # Metrics computation
โ โโโ utils/
โ โโโ progress.py # Environment-aware progress bars
โโโ experiments/ # Research tools
โ โโโ compute_metrics.py # Standalone metrics computation
โ โโโ select_keyframes.py # CLI keyframe selection
โ โโโ keyframes_dist.py # Threshold analysis
โ โโโ plot_compression.py # Batch compression analysis
โ โโโ create_mp4.py # Manual video creation
โ โโโ visualize_frames.py # Frame visualization
โ โโโ metrics_utils.py # Shared metric utilities
โโโ pyproject.toml # Package configuration
โโโ setup.py # Setup script
โโโ README.md # This file
๐ API Reference
KeyframeSelector
Initialization:
selector = KeyframeSelector(video_path, verbose=True)
Methods:
| Method | Description | Returns |
|---|---|---|
compute_metrics() |
Analyzes all frame pairs | np.ndarray |
create_metric_file(output_path) |
Exports metrics to CSV | None |
select_keyframes(abs_thres, delta_thres, adapt_factor) |
Selects keyframes | (ratio, abs_t, delta_t) |
create_retained_indices_file(output_path) |
Exports indices to CSV | None |
analyze_thresholds(num_factors) |
Threshold sensitivity analysis | None |
visualize_frames_fullscreen(...) |
Frame grid visualization | None |
create_compressed_video() |
Generates final video | None |
get_sizes() |
Prints size comparison | None |
State Flags:
metrics_computed: Metrics calculation completemetric_file_created: Metrics CSV exportedretained_indices_computed: Keyframe selection completeretained_indices_file_created: Indices CSV exportedoutput_video_created: Final video generated
Metrics
Initialization:
from video_compressor import Metrics
metrics = Metrics(frame1, frame2, device='cuda', lpips_model=model)
Attributes:
mse: Mean Squared Errorinv_ssim: Inverse SSIMlpips: LPIPS scoredifference: Combined weighted metric
๐ง Troubleshooting
FFmpeg Not Found
Error: FFmpeg not installed
Solution: Install FFmpeg (see Installation section)
CUDA Out of Memory
RuntimeError: CUDA out of memory
Solution: Process shorter videos or use CPU:
# Force CPU usage
import torch
torch.cuda.is_available = lambda: False
Low Compression Ratio
Solution: Increase adapt_factor:
selector.select_keyframes(adapt_factor=2.5)
Too Much Compression
Solution: Decrease adapt_factor or set manual thresholds:
selector.select_keyframes(
abs_thres=30.0,
delta_thres=1.5
)
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐จโ๐ป Author
Satvik Virmani
Feel free to reach out for questions, suggestions, or collaboration opportunities!
๐ Acknowledgments
- LPIPS โ Zhang et al. for the perceptual similarity metric
- OpenCV โ For video processing capabilities
- FFmpeg โ For video encoding
๐ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
๐ Roadmap
- Support for more codecs (H.265, VP9, AV1)
- Real-time preview during selection
- Configurable metric weights
- Scene detection integration
- Multi-video batch processing
- Web interface for non-programmers
If you find VidCompressorX useful, please consider giving it a โญ on GitHub!
Project details
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 vidcompressorx-0.3.0.tar.gz.
File metadata
- Download URL: vidcompressorx-0.3.0.tar.gz
- Upload date:
- Size: 10.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
036268fc0e906d7cfa7eccb005ca5d5bcd314443edf484700d5229c28e2f7872
|
|
| MD5 |
c5e7b1dd6598e645026672ffebe41df5
|
|
| BLAKE2b-256 |
ec9d3d8f1855cdcf589c7f940c6896569e6bf1a532f027a8643ac12f38e88ec2
|
File details
Details for the file vidcompressorx-0.3.0-py3-none-any.whl.
File metadata
- Download URL: vidcompressorx-0.3.0-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3d54018f3f4fac1ffec08ef536e22d831d5a38b5089528d55071f1e8f3d5083
|
|
| MD5 |
c92d1968f50a17034939036ec63e383b
|
|
| BLAKE2b-256 |
44dafc2add9f59fc23ad068c60e3f9add1d0b4a60fbc26fe38bf314da3f8e807
|