Skip to main content

Video compression pipeline with metric-based keyframe selection

Project description

๐ŸŽฌ VidCompressorX

PyPI version Python 3.9+ License: MIT

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:

  1. Extracted as JPEG images
  2. Encoded with FFmpeg (H.264, CRF 23)
  3. 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 complete
  • metric_file_created: Metrics CSV exported
  • retained_indices_computed: Keyframe selection complete
  • retained_indices_file_created: Indices CSV exported
  • output_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 Error
  • inv_ssim: Inverse SSIM
  • lpips: LPIPS score
  • difference: 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.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. 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

vidcompressorx-0.4.0.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

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

vidcompressorx-0.4.0-py3-none-any.whl (10.7 kB view details)

Uploaded Python 3

File details

Details for the file vidcompressorx-0.4.0.tar.gz.

File metadata

  • Download URL: vidcompressorx-0.4.0.tar.gz
  • Upload date:
  • Size: 10.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for vidcompressorx-0.4.0.tar.gz
Algorithm Hash digest
SHA256 2e694ac4371fb1511d53cf8d9b8a499000aa8bc8754c65da0f8a09c19de02544
MD5 398c9e8f16fee21ea74138a758fe99d0
BLAKE2b-256 1e9543466d95de8f6d1528a247a920c9ab6b0b1f36c59ee367e1f498cf0dd654

See more details on using hashes here.

File details

Details for the file vidcompressorx-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: vidcompressorx-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 10.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for vidcompressorx-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dbc1a6e8be1d36d02d0f19a3d3b55f9ae5678f962a5e9b640846158d003d1e08
MD5 f81348b2ead49a975704eb0ba8aded28
BLAKE2b-256 b0dc6454ae3df546a2d229c86e29a90db21188caccdbeda9fcad076aba30571a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page