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 two lines of command.
curl -LsSf https://astral.sh/uv/install.sh | sh
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
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)
- Demux — mp4box.js reads the input MP4/MOV and extracts raw encoded samples
- Decode —
VideoDecoder(hardware) decodes samples into rawVideoFrames - Resize —
OffscreenCanvasscales frames if resolution change is requested - Encode —
VideoEncoder(hardware) re-encodes frames with the chosen codec/bitrate - Mux — mp4-muxer or webm-muxer packages encoded chunks into the output container
- 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
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 vidcompress-0.1.3.tar.gz.
File metadata
- Download URL: vidcompress-0.1.3.tar.gz
- Upload date:
- Size: 2.3 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c612e78c5af409b58c610ae5d10fb2ce348103e9d270fd38b1f48a144df46cd
|
|
| MD5 |
d3aa58b2c0f08d97c8b3190a11caf2ad
|
|
| BLAKE2b-256 |
6b4e6fef60076dc24c402492cddf936ac1dcbe4da079f2d56115be79c4b74525
|
File details
Details for the file vidcompress-0.1.3-py3-none-any.whl.
File metadata
- Download URL: vidcompress-0.1.3-py3-none-any.whl
- Upload date:
- Size: 17.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e1bcc96983e876600e6c5753987682496a03fd95c3d82a2816a3bf0a4d083fa5
|
|
| MD5 |
4f1849e6593db89a6e9018eb0c9aacc3
|
|
| BLAKE2b-256 |
0b39483c2ec8549a7a67e18c0f6d405100ca0fceb1ac9a8665d17f491704c97d
|