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.3.0.tar.gz (10.1 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.3.0-py3-none-any.whl (10.5 kB view details)

Uploaded Python 3

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

Hashes for vidcompressorx-0.3.0.tar.gz
Algorithm Hash digest
SHA256 036268fc0e906d7cfa7eccb005ca5d5bcd314443edf484700d5229c28e2f7872
MD5 c5e7b1dd6598e645026672ffebe41df5
BLAKE2b-256 ec9d3d8f1855cdcf589c7f940c6896569e6bf1a532f027a8643ac12f38e88ec2

See more details on using hashes here.

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

Hashes for vidcompressorx-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f3d54018f3f4fac1ffec08ef536e22d831d5a38b5089528d55071f1e8f3d5083
MD5 c92d1968f50a17034939036ec63e383b
BLAKE2b-256 44dafc2add9f59fc23ad068c60e3f9add1d0b4a60fbc26fe38bf314da3f8e807

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