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
- Bump the version in both
pyproject.tomlandsrc/vidcompress/__init__.py uv builduv 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)
- 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.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ca390cd4c497d47dd1ee04f0e760bde5e8230298c88113dd292b8b41848af4f
|
|
| MD5 |
60d83e5080e9ae1f40329087439ad2d4
|
|
| BLAKE2b-256 |
f792c8ba4c3d96c5d3cccf87499c2bd189d7da7fd3269f1ef379716b162cf7f1
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a120313328cf6d238fb5acb876c7402cb2eb82094d2cb46686feab33ffa5d8b8
|
|
| MD5 |
f912ae72b87acc2bee0f78c4602fa0fd
|
|
| BLAKE2b-256 |
abf7326559c653cf25bdb7352699c9a26700e87b83bb9aa581e5320597f74881
|