Skip to main content

Local video compression powered by WebCodecs — hardware-accelerated, zero FFmpeg required

Project description

VidCompress

Local, hardware-accelerated video compression that runs entirely in your browser. No FFmpeg install, no cloud uploads — just a single command.

uvx vidcompress

How it works

VidCompress launches a tiny local web server and opens a browser tab. All video encoding/decoding happens client-side using the WebCodecs API, which talks directly to your GPU's hardware encoder (VideoToolbox on Mac, NVENC on NVIDIA, AMF on AMD).

┌──────────────────────────────────────────────────────────┐
│  Browser (Chrome/Edge)                                   │
│                                                          │
│  MP4Box.js     VideoDecoder     VideoEncoder   mp4-muxer │
│  (demux)   →   (HW decode)  →  (HW encode) →  (remux)   │
│                                                          │
│  ↕ GPU: VideoToolbox / NVENC / AMF / VA-API              │
└──────────────────────────────────────────────────────────┘
│  Python server (FastAPI) — only serves static files      │
└──────────────────────────────────────────────────────────┘

Your files never leave your machine.

Quick start

With uv (recommended)

# Run directly — no install needed
uvx vidcompress

# Or install globally
uv tool install vidcompress
vidcompress

With pip

pip install vidcompress
vidcompress

From source

git clone https://github.com/arpantripathi/ffmpeg-compression-local.git
cd ffmpeg-compression-local
uv run vidcompress

Features

  • Hardware-accelerated — uses your GPU encoder, not software encoding
  • Zero dependencies — no FFmpeg, no native libraries to install
  • Fully local — nothing leaves your machine
  • Codec choice — H.264, H.265 (HEVC), VP9, AV1
  • Resolution scaling — downscale to 1080p, 720p, 480p, 360p
  • Quality control — adjustable quality slider with exponential bitrate mapping
  • Audio re-encoding — automatic AAC/Opus transcoding
  • Drag & drop — simple, clean UI

Supported codecs

Codec Container Mac (Apple Silicon) Windows (NVIDIA) Windows (AMD)
H.264 (AVC) MP4 VideoToolbox NVENC AMF
H.265 (HEVC) MP4 VideoToolbox NVENC AMF
VP9 WebM Software* Software* Software*
AV1 MP4 VideoToolbox (M3+) NVENC (RTX 40+) AMF (RX 7000+)

*VP9 encoding may fall back to software on some platforms. Hardware support depends on your browser and GPU drivers.

Performance

Typical encoding speeds for 1080p video (hardware-accelerated):

Codec Apple M1/M2 NVIDIA RTX 3060+ AMD RX 6000+
H.264 200-400 fps 300-500 fps 200-350 fps
H.265 150-300 fps 200-400 fps 150-250 fps
AV1 60-120 fps (M2+) 100-200 fps (RTX 40+) 80-150 fps

A 10-minute 1080p video typically compresses in 30-90 seconds.

Browser requirements

  • Chrome 94+ or Edge 94+ (full WebCodecs support)
  • Firefox: partial support (video encoding may not work)
  • Safari: partial support (limited codec options)

CLI options

vidcompress [OPTIONS]

Options:
  -p, --port PORT    Port to serve on (default: 8899)
  --host HOST        Host to bind to (default: 127.0.0.1)
  --no-open          Don't open browser automatically
  --version          Show version and exit
  -h, --help         Show help

Publishing to PyPI (for maintainers)

This section covers how to publish vidcompress so anyone can run uvx vidcompress.

1. Prerequisites

# Create a PyPI account at https://pypi.org/account/register/
# Then create an API token at https://pypi.org/manage/account/token/
# (scope it to the "vidcompress" project after first upload)

2. Check the package name

Before publishing, verify that vidcompress is available on PyPI. If it's taken, update the name field in pyproject.toml.

3. Build

uv build

This creates dist/vidcompress-0.1.0.tar.gz and dist/vidcompress-0.1.0-py3-none-any.whl.

4. Test on TestPyPI first (recommended)

# Upload to TestPyPI
uv publish --publish-url https://test.pypi.org/legacy/ --token pypi-YOUR_TEST_TOKEN

# Try installing from TestPyPI
uv tool install --index-url https://test.pypi.org/simple/ vidcompress

5. Publish to PyPI

uv publish --token pypi-YOUR_TOKEN

Or set the token as an environment variable:

export UV_PUBLISH_TOKEN=pypi-YOUR_TOKEN
uv publish

6. Verify

# Anyone can now run:
uvx vidcompress

Subsequent releases

  1. Bump the version in both pyproject.toml and src/vidcompress/__init__.py
  2. uv build
  3. uv publish --token pypi-YOUR_TOKEN

Development

git clone https://github.com/arpantripathi/ffmpeg-compression-local.git
cd ffmpeg-compression-local

# Run in development
uv run vidcompress

# Or with live reload (edit static files, refresh browser)
uv run vidcompress --port 3000

The Python server is minimal — it only serves static files. All encoding logic is in src/vidcompress/static/app.js.

Architecture

src/vidcompress/
├── __init__.py        # Version
├── __main__.py        # python -m vidcompress
├── cli.py             # CLI argument parsing + server launch
├── server.py          # FastAPI static file server (10 lines)
└── static/
    ├── index.html     # UI structure
    ├── style.css      # Dark theme
    └── app.js         # WebCodecs transcoding pipeline

Frontend pipeline (app.js)

  1. Demux — mp4box.js reads the input MP4/MOV and extracts raw encoded samples
  2. DecodeVideoDecoder (hardware) decodes samples into raw VideoFrames
  3. ResizeOffscreenCanvas scales frames if resolution change is requested
  4. EncodeVideoEncoder (hardware) re-encodes frames with the chosen codec/bitrate
  5. Mux — mp4-muxer or webm-muxer packages encoded chunks into the output container
  6. Download — output is offered as a browser download

Limitations

  • Input formats: MP4 and MOV files only (mp4box.js limitation). WebM input is not supported yet.
  • File size: Limited by browser memory. Files over ~2 GB may cause issues.
  • Codec availability: Depends on your browser, OS, and GPU. H.265 and AV1 encoding may not be available on all systems.
  • No B-frame control: WebCodecs doesn't expose fine-grained encoding parameters like CRF or B-frame count.
  • Audio: Audio re-encoding may fail for some input formats. The video will still be compressed.

License

MIT

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

vidcompress-0.1.0.tar.gz (57.0 kB view details)

Uploaded Source

Built Distribution

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

vidcompress-0.1.0-py3-none-any.whl (15.4 kB view details)

Uploaded Python 3

File details

Details for the file vidcompress-0.1.0.tar.gz.

File metadata

  • Download URL: vidcompress-0.1.0.tar.gz
  • Upload date:
  • Size: 57.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vidcompress-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3ca390cd4c497d47dd1ee04f0e760bde5e8230298c88113dd292b8b41848af4f
MD5 60d83e5080e9ae1f40329087439ad2d4
BLAKE2b-256 f792c8ba4c3d96c5d3cccf87499c2bd189d7da7fd3269f1ef379716b162cf7f1

See more details on using hashes here.

File details

Details for the file vidcompress-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: vidcompress-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for vidcompress-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a120313328cf6d238fb5acb876c7402cb2eb82094d2cb46686feab33ffa5d8b8
MD5 f912ae72b87acc2bee0f78c4602fa0fd
BLAKE2b-256 abf7326559c653cf25bdb7352699c9a26700e87b83bb9aa581e5320597f74881

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