Convert any video to ultra-lightweight WebM or transparent animated WebP for seamless web embedding.
Project description
airclip
Convert any video to an ultra-lightweight web-embeddable format.
30 seconds of video → ~50-200 KB without visible quality loss.
Two output modes:
| Mode | Format | Use case | Embed with |
|---|---|---|---|
| Standard | WebM (VP9) | Solid-background animations | <video> |
| Transparent | Animated WebP | Alpha-channel animations | <img> |
Why
Embedding videos on the web usually means large files, slow loads, and visible player chrome. airclip solves this for animation and diagram content:
| Standard mode | Transparent mode | |
|---|---|---|
| Input | MP4, MOV, AVI, MKV, WebM | MOV with alpha (e.g. Manim -t) |
| Output | WebM (VP9) | Animated WebP |
| 30s video | ~50-200 KB | ~150-500 KB |
| Background | Solid color (blends in) | Fully transparent |
The output looks native to the page — no borders, no player UI, just content.
How it works
Standard mode (WebM VP9):
- VP9 encoding — modern codec, much better compression than H.264
- High CRF — animation content compresses extremely well at CRF 35-45
- Reduced framerate — 24fps is visually identical to 60fps for diagrams
- Downscale to 720p — on web, nobody notices the difference from 1080p
- Two-pass encoding — analyzes content first, allocates bits where they matter
- No audio — animations don't need it, saves ~30% file size
Transparent mode (animated WebP):
- Preserves the alpha channel from source videos (e.g. Manim's
-tflag) - Uses
libwebp_animwithbgrapixel format for sharp, lossless alpha - Output works on any background — light, dark, gradient, or patterned
- Embeds as
<img>, not<video>— simpler, auto-animates, no JS needed
Install
pip install imageio-ffmpeg
Or have ffmpeg available on your PATH.
Usage
# Single file
python -m airclip video.mp4
# Entire directory
python -m airclip videos/
# Custom settings
python -m airclip video.mp4 --fps 15 --crf 42 --height 480
# Fast mode (skip 2-pass, ~2x faster)
python -m airclip video.mp4 --no-2pass
# Output to a different directory
python -m airclip videos/ --outdir dist/
# Transparent background (outputs animated WebP)
python -m airclip animation.mov --transparent
# Transparent with higher quality
python -m airclip animation.mov --transparent --crf 28
As a library
from airclip import convert_lightweight
result = convert_lightweight(
"input.mp4",
output_path="output.webm",
target_fps=24,
crf=38,
max_height=720,
)
# Transparent output (animated WebP)
result = convert_lightweight(
"animation.mov",
target_fps=24,
crf=28,
transparent=True,
)
print(f"{result['input_kb']:.0f} KB → {result['output_kb']:.0f} KB")
print(f"{result['ratio']:.1f}x smaller")
Options
| Flag | Default | Description |
|---|---|---|
--fps |
24 | Target framerate. Use 15 for near-static content. |
--crf |
38 | Quality level. Higher = smaller. 35-45 works well for animations. |
--height |
720 | Max output height in pixels. |
--no-2pass |
off | Skip 2-pass encoding (faster, slightly larger output). |
--transparent |
off | Preserve alpha channel. Outputs animated WebP instead of WebM. |
--outdir |
same as input | Output directory for converted files. |
CRF guide
| CRF | Quality | Best for |
|---|---|---|
| 30-34 | High | Live action, complex motion |
| 35-38 | Good | Animations with fine detail |
| 39-42 | Small | Diagrams, slides, code demos |
| 43-50 | Tiny | Static content, simple shapes |
Embedding on web
Standard WebM (opaque)
<video autoplay muted loop playsinline>
<source src="animation.webm" type="video/webm">
</video>
video {
width: 100%;
background: transparent;
border: none;
border-radius: 12px;
}
Autoplay on scroll (optional):
const observer = new IntersectionObserver((entries) => {
entries.forEach(e => {
e.isIntersecting ? e.target.play() : e.target.pause();
});
}, { threshold: 0.5 });
document.querySelectorAll('video').forEach(v => observer.observe(v));
Transparent WebP
<img src="animation.webp" style="width: 100%">
No <video> element needed — animated WebP auto-plays in all modern browsers and naturally blends into any background.
Best results when
- Content is vector-like: shapes, text, diagrams, code
- Motion is smooth and predictable (not chaotic)
- No audio needed
- Standard: background is a solid or near-solid color
- Transparent: source rendered at 720p+ (e.g.
manim -t -qm) with alpha channel
Results
Same animation, three formats
| Original | Standard Mode | Transparent Mode | |
|---|---|---|---|
| Format | Manim QTRLE (.mov) | VP9 WebM | Animated WebP |
| Size | 2,532 KB | 102 KB | 391 KB |
| Compression | — | 24.9x smaller | 6.5x smaller |
| Resolution | 720p 30fps | 720p 24fps | 720p 24fps |
| Background | Alpha channel | Baked in | Alpha preserved |
| Embed with | — | <video> |
<img> |
Standard mode bakes the background in — smallest file, works on matching backgrounds. Transparent mode preserves the alpha channel — larger, but works on any background.
Across 6 test videos
| Metric | Value |
|---|---|
| Average compression | 12x |
| Total input | ~1.2 MB |
| Total output | ~93 KB |
| Visible quality loss | None |
License
MIT
Project details
Release history Release notifications | RSS feed
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 airclip-0.2.0.tar.gz.
File metadata
- Download URL: airclip-0.2.0.tar.gz
- Upload date:
- Size: 7.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7825b6fe76e227773f84c7adb16417d17b65c7e5ce3e286722632307e4d4c7dc
|
|
| MD5 |
e94d88f8f2d647c90b015e38576333ba
|
|
| BLAKE2b-256 |
85a4aa00c18a5e9a4534185ca297a0552d67c42e75895c4138199d7a6036ae24
|
Provenance
The following attestation bundles were made for airclip-0.2.0.tar.gz:
Publisher:
publish.yml on akashchekka/airclip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airclip-0.2.0.tar.gz -
Subject digest:
7825b6fe76e227773f84c7adb16417d17b65c7e5ce3e286722632307e4d4c7dc - Sigstore transparency entry: 1317075204
- Sigstore integration time:
-
Permalink:
akashchekka/airclip@a6f215da12d85166e7853e906a11e5b1694c6a2f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/akashchekka
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a6f215da12d85166e7853e906a11e5b1694c6a2f -
Trigger Event:
release
-
Statement type:
File details
Details for the file airclip-0.2.0-py3-none-any.whl.
File metadata
- Download URL: airclip-0.2.0-py3-none-any.whl
- Upload date:
- Size: 7.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25af9aa1c6f7726d283cb55f0e0c4512aec27e6abe9c46628750e8a6c4cbf348
|
|
| MD5 |
9ad6ce1250d8700f80f8f438e5ddec72
|
|
| BLAKE2b-256 |
a7d651fabba5c648b762c758fc28bbd070c509927353a2029284bfc9ec3dca62
|
Provenance
The following attestation bundles were made for airclip-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on akashchekka/airclip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
airclip-0.2.0-py3-none-any.whl -
Subject digest:
25af9aa1c6f7726d283cb55f0e0c4512aec27e6abe9c46628750e8a6c4cbf348 - Sigstore transparency entry: 1317075226
- Sigstore integration time:
-
Permalink:
akashchekka/airclip@a6f215da12d85166e7853e906a11e5b1694c6a2f -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/akashchekka
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a6f215da12d85166e7853e906a11e5b1694c6a2f -
Trigger Event:
release
-
Statement type: