airclip 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
airclip-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.4
2
+ Name: airclip
3
+ Version: 0.1.0
4
+ Summary: Convert any video to an ultra-lightweight WebM that blends seamlessly into web pages.
5
+ Author: Akash Chekka
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/akashchekka/airclip
8
+ Project-URL: Repository, https://github.com/akashchekka/airclip
9
+ Keywords: video,webm,vp9,compression,web,ffmpeg
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Multimedia :: Video :: Conversion
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ Provides-Extra: bundled-ffmpeg
20
+ Requires-Dist: imageio-ffmpeg; extra == "bundled-ffmpeg"
21
+
22
+ # airclip
23
+
24
+ Convert any video to an ultra-lightweight WebM that blends seamlessly into web pages.
25
+
26
+ **30 seconds of video → ~50-200 KB** without visible quality loss.
27
+
28
+ ## Why
29
+
30
+ Embedding videos on the web usually means large files, slow loads, and visible player chrome. `airclip` solves this for animation and diagram content:
31
+
32
+ | Metric | Before | After |
33
+ |--------|--------|-------|
34
+ | 30s video | ~1-3 MB | ~50-200 KB |
35
+ | Format | MP4 (H.264) | WebM (VP9) |
36
+ | FPS | 60 | 24 |
37
+ | Resolution | 1080p | 720p |
38
+ | Audio | Included | Stripped |
39
+
40
+ The output blends into dark backgrounds — no borders, no player UI, just content that looks native to the page.
41
+
42
+ ## How it works
43
+
44
+ 1. **VP9 encoding** — modern codec designed for web, much better compression than H.264
45
+ 2. **High CRF** — animation content (solid backgrounds, vector shapes) compresses extremely well at CRF 35-45
46
+ 3. **Reduced framerate** — 24fps is visually identical to 60fps for slides and diagrams
47
+ 4. **Downscale to 720p** — on web, nobody notices the difference from 1080p
48
+ 5. **Two-pass encoding** — analyzes content first, then allocates bits where they matter
49
+ 6. **No audio** — animations don't need it, saves ~30% file size
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install imageio-ffmpeg
55
+ ```
56
+
57
+ Or have `ffmpeg` available on your PATH.
58
+
59
+ ## Usage
60
+
61
+ ```bash
62
+ # Single file
63
+ python -m airclip video.mp4
64
+
65
+ # Entire directory
66
+ python -m airclip videos/
67
+
68
+ # Custom settings
69
+ python -m airclip video.mp4 --fps 15 --crf 42 --height 480
70
+
71
+ # Fast mode (skip 2-pass, ~2x faster)
72
+ python -m airclip video.mp4 --no-2pass
73
+
74
+ # Output to a different directory
75
+ python -m airclip videos/ --outdir dist/
76
+ ```
77
+
78
+ ### As a library
79
+
80
+ ```python
81
+ from airclip import convert_lightweight
82
+
83
+ result = convert_lightweight(
84
+ "input.mp4",
85
+ output_path="output.webm",
86
+ target_fps=24,
87
+ crf=38,
88
+ max_height=720,
89
+ )
90
+
91
+ print(f"{result['input_kb']:.0f} KB → {result['output_kb']:.0f} KB")
92
+ print(f"{result['ratio']:.1f}x smaller")
93
+ ```
94
+
95
+ ## Options
96
+
97
+ | Flag | Default | Description |
98
+ |------|---------|-------------|
99
+ | `--fps` | 24 | Target framerate. Use 15 for near-static content. |
100
+ | `--crf` | 38 | Quality level. Higher = smaller. 35-45 works well for animations. |
101
+ | `--height` | 720 | Max output height in pixels. |
102
+ | `--no-2pass` | off | Skip 2-pass encoding (faster, slightly larger output). |
103
+ | `--outdir` | same as input | Output directory for converted files. |
104
+
105
+ ## CRF guide
106
+
107
+ | CRF | Quality | Best for |
108
+ |-----|---------|----------|
109
+ | 30-34 | High | Live action, complex motion |
110
+ | 35-38 | Good | Animations with fine detail |
111
+ | 39-42 | Small | Diagrams, slides, code demos |
112
+ | 43-50 | Tiny | Static content, simple shapes |
113
+
114
+ ## Embedding on web
115
+
116
+ The output is designed to look native on dark-themed pages:
117
+
118
+ ```html
119
+ <video autoplay muted loop playsinline>
120
+ <source src="animation.webm" type="video/webm">
121
+ <source src="animation.mp4" type="video/mp4"> <!-- fallback -->
122
+ </video>
123
+ ```
124
+
125
+ ```css
126
+ video {
127
+ width: 100%;
128
+ background: transparent;
129
+ border: none;
130
+ border-radius: 12px;
131
+ }
132
+ ```
133
+
134
+ For autoplay-on-scroll:
135
+
136
+ ```javascript
137
+ const observer = new IntersectionObserver((entries) => {
138
+ entries.forEach(e => {
139
+ e.isIntersecting ? e.target.play() : e.target.pause();
140
+ });
141
+ }, { threshold: 0.5 });
142
+
143
+ document.querySelectorAll('video').forEach(v => observer.observe(v));
144
+ ```
145
+
146
+ ## Best results when
147
+
148
+ - Background is a solid or near-solid color (dark themes work great)
149
+ - Content is vector-like: shapes, text, diagrams, code
150
+ - Motion is smooth and predictable (not chaotic)
151
+ - No audio needed
152
+
153
+ ## Results
154
+
155
+ Across 6 test videos: **~1.2 MB → ~93 KB average (12x compression)**. No visible quality loss in browser playback.
156
+
157
+ ## License
158
+
159
+ MIT
@@ -0,0 +1,138 @@
1
+ # airclip
2
+
3
+ Convert any video to an ultra-lightweight WebM that blends seamlessly into web pages.
4
+
5
+ **30 seconds of video → ~50-200 KB** without visible quality loss.
6
+
7
+ ## Why
8
+
9
+ Embedding videos on the web usually means large files, slow loads, and visible player chrome. `airclip` solves this for animation and diagram content:
10
+
11
+ | Metric | Before | After |
12
+ |--------|--------|-------|
13
+ | 30s video | ~1-3 MB | ~50-200 KB |
14
+ | Format | MP4 (H.264) | WebM (VP9) |
15
+ | FPS | 60 | 24 |
16
+ | Resolution | 1080p | 720p |
17
+ | Audio | Included | Stripped |
18
+
19
+ The output blends into dark backgrounds — no borders, no player UI, just content that looks native to the page.
20
+
21
+ ## How it works
22
+
23
+ 1. **VP9 encoding** — modern codec designed for web, much better compression than H.264
24
+ 2. **High CRF** — animation content (solid backgrounds, vector shapes) compresses extremely well at CRF 35-45
25
+ 3. **Reduced framerate** — 24fps is visually identical to 60fps for slides and diagrams
26
+ 4. **Downscale to 720p** — on web, nobody notices the difference from 1080p
27
+ 5. **Two-pass encoding** — analyzes content first, then allocates bits where they matter
28
+ 6. **No audio** — animations don't need it, saves ~30% file size
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install imageio-ffmpeg
34
+ ```
35
+
36
+ Or have `ffmpeg` available on your PATH.
37
+
38
+ ## Usage
39
+
40
+ ```bash
41
+ # Single file
42
+ python -m airclip video.mp4
43
+
44
+ # Entire directory
45
+ python -m airclip videos/
46
+
47
+ # Custom settings
48
+ python -m airclip video.mp4 --fps 15 --crf 42 --height 480
49
+
50
+ # Fast mode (skip 2-pass, ~2x faster)
51
+ python -m airclip video.mp4 --no-2pass
52
+
53
+ # Output to a different directory
54
+ python -m airclip videos/ --outdir dist/
55
+ ```
56
+
57
+ ### As a library
58
+
59
+ ```python
60
+ from airclip import convert_lightweight
61
+
62
+ result = convert_lightweight(
63
+ "input.mp4",
64
+ output_path="output.webm",
65
+ target_fps=24,
66
+ crf=38,
67
+ max_height=720,
68
+ )
69
+
70
+ print(f"{result['input_kb']:.0f} KB → {result['output_kb']:.0f} KB")
71
+ print(f"{result['ratio']:.1f}x smaller")
72
+ ```
73
+
74
+ ## Options
75
+
76
+ | Flag | Default | Description |
77
+ |------|---------|-------------|
78
+ | `--fps` | 24 | Target framerate. Use 15 for near-static content. |
79
+ | `--crf` | 38 | Quality level. Higher = smaller. 35-45 works well for animations. |
80
+ | `--height` | 720 | Max output height in pixels. |
81
+ | `--no-2pass` | off | Skip 2-pass encoding (faster, slightly larger output). |
82
+ | `--outdir` | same as input | Output directory for converted files. |
83
+
84
+ ## CRF guide
85
+
86
+ | CRF | Quality | Best for |
87
+ |-----|---------|----------|
88
+ | 30-34 | High | Live action, complex motion |
89
+ | 35-38 | Good | Animations with fine detail |
90
+ | 39-42 | Small | Diagrams, slides, code demos |
91
+ | 43-50 | Tiny | Static content, simple shapes |
92
+
93
+ ## Embedding on web
94
+
95
+ The output is designed to look native on dark-themed pages:
96
+
97
+ ```html
98
+ <video autoplay muted loop playsinline>
99
+ <source src="animation.webm" type="video/webm">
100
+ <source src="animation.mp4" type="video/mp4"> <!-- fallback -->
101
+ </video>
102
+ ```
103
+
104
+ ```css
105
+ video {
106
+ width: 100%;
107
+ background: transparent;
108
+ border: none;
109
+ border-radius: 12px;
110
+ }
111
+ ```
112
+
113
+ For autoplay-on-scroll:
114
+
115
+ ```javascript
116
+ const observer = new IntersectionObserver((entries) => {
117
+ entries.forEach(e => {
118
+ e.isIntersecting ? e.target.play() : e.target.pause();
119
+ });
120
+ }, { threshold: 0.5 });
121
+
122
+ document.querySelectorAll('video').forEach(v => observer.observe(v));
123
+ ```
124
+
125
+ ## Best results when
126
+
127
+ - Background is a solid or near-solid color (dark themes work great)
128
+ - Content is vector-like: shapes, text, diagrams, code
129
+ - Motion is smooth and predictable (not chaotic)
130
+ - No audio needed
131
+
132
+ ## Results
133
+
134
+ Across 6 test videos: **~1.2 MB → ~93 KB average (12x compression)**. No visible quality loss in browser playback.
135
+
136
+ ## License
137
+
138
+ MIT
@@ -0,0 +1 @@
1
+ from .airclip import convert_lightweight, get_video_info
@@ -0,0 +1,3 @@
1
+ from .airclip import main
2
+
3
+ main()
@@ -0,0 +1,200 @@
1
+ """airclip — Convert videos to ultra-lightweight web-embeddable format.
2
+
3
+ Takes any video and produces a tiny WebM (VP9) that blends seamlessly
4
+ into web pages. Optimized for animation/diagram content where
5
+ solid backgrounds and limited motion allow extreme compression.
6
+
7
+ Usage:
8
+ python -m airclip video.mp4 # Single file
9
+ python -m airclip video.mp4 --fps 15 --crf 40 # Custom
10
+ """
11
+ import argparse
12
+ import os
13
+ import subprocess
14
+ import sys
15
+ from pathlib import Path
16
+
17
+ # imageio-ffmpeg bundles ffmpeg so we don't need a system install
18
+ try:
19
+ import imageio_ffmpeg
20
+ FFMPEG = imageio_ffmpeg.get_ffmpeg_exe()
21
+ except ImportError:
22
+ FFMPEG = "ffmpeg"
23
+
24
+
25
+ def get_video_info(path: str) -> dict:
26
+ """Get duration and resolution using ffprobe."""
27
+ ffprobe = Path(FFMPEG).parent / Path(FFMPEG).name.replace("ffmpeg", "ffprobe")
28
+ if not ffprobe.exists():
29
+ # Fall back: try without info
30
+ return {"duration": 0, "width": 0, "height": 0, "fps": 30}
31
+ cmd = [
32
+ ffprobe, "-v", "quiet",
33
+ "-print_format", "json",
34
+ "-show_format", "-show_streams",
35
+ path,
36
+ ]
37
+ import json
38
+ r = subprocess.run(cmd, capture_output=True, text=True)
39
+ if r.returncode != 0:
40
+ return {}
41
+ data = json.loads(r.stdout)
42
+ stream = next((s for s in data.get("streams", []) if s["codec_type"] == "video"), {})
43
+ return {
44
+ "duration": float(data.get("format", {}).get("duration", 0)),
45
+ "width": int(stream.get("width", 0)),
46
+ "height": int(stream.get("height", 0)),
47
+ "fps": eval(stream.get("r_frame_rate", "30/1")),
48
+ }
49
+
50
+
51
+ def convert_lightweight(
52
+ input_path: str,
53
+ output_path: str | None = None,
54
+ target_fps: int = 24,
55
+ crf: int = 38,
56
+ max_height: int = 720,
57
+ two_pass: bool = True,
58
+ ) -> dict:
59
+ """Convert a video to ultra-lightweight WebM VP9.
60
+
61
+ Args:
62
+ input_path: Source video file.
63
+ output_path: Output path. Default: same name with .webm extension.
64
+ target_fps: Target framerate. 15-24 is ideal for animations.
65
+ crf: Constant Rate Factor. Higher = smaller. 35-45 for animations.
66
+ max_height: Max output height. 720 is good for web.
67
+ two_pass: Use 2-pass encoding for better quality/size ratio.
68
+
69
+ Returns:
70
+ Dict with input_size, output_size, ratio, duration.
71
+ """
72
+ inp = Path(input_path)
73
+ if output_path is None:
74
+ output_path = str(inp.with_suffix(".webm"))
75
+ out = Path(output_path)
76
+
77
+ input_size = inp.stat().st_size
78
+
79
+ # Scale filter: only downscale, keep aspect ratio
80
+ scale_filter = f"scale=-2:'min({max_height},ih)'"
81
+ vf = f"{scale_filter},fps={target_fps}"
82
+
83
+ if two_pass:
84
+ # Pass 1: analyze
85
+ pass1 = [
86
+ FFMPEG, "-y", "-i", str(inp),
87
+ "-vf", vf,
88
+ "-c:v", "libvpx-vp9",
89
+ "-b:v", "0", "-crf", str(crf),
90
+ "-pass", "1",
91
+ "-an",
92
+ "-f", "null",
93
+ "NUL" if sys.platform == "win32" else "/dev/null",
94
+ ]
95
+ subprocess.run(pass1, capture_output=True)
96
+
97
+ # Pass 2: encode
98
+ pass2 = [
99
+ FFMPEG, "-y", "-i", str(inp),
100
+ "-vf", vf,
101
+ "-c:v", "libvpx-vp9",
102
+ "-b:v", "0", "-crf", str(crf),
103
+ "-pass", "2",
104
+ "-an", # no audio for animations
105
+ "-auto-alt-ref", "1",
106
+ "-lag-in-frames", "25",
107
+ "-row-mt", "1",
108
+ str(out),
109
+ ]
110
+ subprocess.run(pass2, capture_output=True)
111
+
112
+ # Cleanup pass log files
113
+ for f in Path(".").glob("ffmpeg2pass-0*"):
114
+ f.unlink(missing_ok=True)
115
+ else:
116
+ cmd = [
117
+ FFMPEG, "-y", "-i", str(inp),
118
+ "-vf", vf,
119
+ "-c:v", "libvpx-vp9",
120
+ "-b:v", "0", "-crf", str(crf),
121
+ "-an",
122
+ "-row-mt", "1",
123
+ str(out),
124
+ ]
125
+ subprocess.run(cmd, capture_output=True)
126
+
127
+ output_size = out.stat().st_size if out.exists() else 0
128
+ info = get_video_info(str(inp))
129
+
130
+ return {
131
+ "input": str(inp.name),
132
+ "output": str(out.name),
133
+ "input_size": input_size,
134
+ "output_size": output_size,
135
+ "ratio": input_size / output_size if output_size else 0,
136
+ "duration": info.get("duration", 0),
137
+ "input_kb": input_size / 1024,
138
+ "output_kb": output_size / 1024,
139
+ }
140
+
141
+
142
+ def main():
143
+ parser = argparse.ArgumentParser(description="Convert videos to lightweight web-embeddable format")
144
+ parser.add_argument("input", help="Video file or directory of videos")
145
+ parser.add_argument("--fps", type=int, default=24, help="Target FPS (default: 24)")
146
+ parser.add_argument("--crf", type=int, default=38, help="Quality (higher=smaller, default: 38)")
147
+ parser.add_argument("--height", type=int, default=720, help="Max height in px (default: 720)")
148
+ parser.add_argument("--no-2pass", action="store_true", help="Skip 2-pass encoding (faster)")
149
+ parser.add_argument("--outdir", type=str, default=None, help="Output directory")
150
+ args = parser.parse_args()
151
+
152
+ target = Path(args.input)
153
+ if target.is_dir():
154
+ files = sorted(target.glob("*.mp4"))
155
+ else:
156
+ files = [target]
157
+
158
+ if not files:
159
+ print("No MP4 files found.")
160
+ return
161
+
162
+ print(f"\n Converting {len(files)} video(s) to lightweight WebM")
163
+ print(f" Settings: {args.fps}fps, CRF {args.crf}, max {args.height}p, 2-pass={not args.no_2pass}")
164
+ print(f" {'─' * 60}")
165
+
166
+ total_in = 0
167
+ total_out = 0
168
+
169
+ for f in files:
170
+ out_dir = Path(args.outdir) if args.outdir else f.parent
171
+ out_dir.mkdir(parents=True, exist_ok=True)
172
+ out_path = out_dir / f"{f.stem}.webm"
173
+
174
+ result = convert_lightweight(
175
+ str(f), str(out_path),
176
+ target_fps=args.fps,
177
+ crf=args.crf,
178
+ max_height=args.height,
179
+ two_pass=not args.no_2pass,
180
+ )
181
+
182
+ total_in += result["input_size"]
183
+ total_out += result["output_size"]
184
+
185
+ print(
186
+ f" {result['input']:40s} "
187
+ f"{result['input_kb']:7.0f} KB → {result['output_kb']:6.0f} KB "
188
+ f"({result['ratio']:5.1f}x smaller)"
189
+ )
190
+
191
+ print(f" {'─' * 60}")
192
+ print(
193
+ f" Total: {total_in/1024:,.0f} KB → {total_out/1024:,.0f} KB "
194
+ f"({total_in/total_out:.1f}x compression)"
195
+ )
196
+ print()
197
+
198
+
199
+ if __name__ == "__main__":
200
+ main()
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.4
2
+ Name: airclip
3
+ Version: 0.1.0
4
+ Summary: Convert any video to an ultra-lightweight WebM that blends seamlessly into web pages.
5
+ Author: Akash Chekka
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/akashchekka/airclip
8
+ Project-URL: Repository, https://github.com/akashchekka/airclip
9
+ Keywords: video,webm,vp9,compression,web,ffmpeg
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Topic :: Multimedia :: Video :: Conversion
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ Provides-Extra: bundled-ffmpeg
20
+ Requires-Dist: imageio-ffmpeg; extra == "bundled-ffmpeg"
21
+
22
+ # airclip
23
+
24
+ Convert any video to an ultra-lightweight WebM that blends seamlessly into web pages.
25
+
26
+ **30 seconds of video → ~50-200 KB** without visible quality loss.
27
+
28
+ ## Why
29
+
30
+ Embedding videos on the web usually means large files, slow loads, and visible player chrome. `airclip` solves this for animation and diagram content:
31
+
32
+ | Metric | Before | After |
33
+ |--------|--------|-------|
34
+ | 30s video | ~1-3 MB | ~50-200 KB |
35
+ | Format | MP4 (H.264) | WebM (VP9) |
36
+ | FPS | 60 | 24 |
37
+ | Resolution | 1080p | 720p |
38
+ | Audio | Included | Stripped |
39
+
40
+ The output blends into dark backgrounds — no borders, no player UI, just content that looks native to the page.
41
+
42
+ ## How it works
43
+
44
+ 1. **VP9 encoding** — modern codec designed for web, much better compression than H.264
45
+ 2. **High CRF** — animation content (solid backgrounds, vector shapes) compresses extremely well at CRF 35-45
46
+ 3. **Reduced framerate** — 24fps is visually identical to 60fps for slides and diagrams
47
+ 4. **Downscale to 720p** — on web, nobody notices the difference from 1080p
48
+ 5. **Two-pass encoding** — analyzes content first, then allocates bits where they matter
49
+ 6. **No audio** — animations don't need it, saves ~30% file size
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install imageio-ffmpeg
55
+ ```
56
+
57
+ Or have `ffmpeg` available on your PATH.
58
+
59
+ ## Usage
60
+
61
+ ```bash
62
+ # Single file
63
+ python -m airclip video.mp4
64
+
65
+ # Entire directory
66
+ python -m airclip videos/
67
+
68
+ # Custom settings
69
+ python -m airclip video.mp4 --fps 15 --crf 42 --height 480
70
+
71
+ # Fast mode (skip 2-pass, ~2x faster)
72
+ python -m airclip video.mp4 --no-2pass
73
+
74
+ # Output to a different directory
75
+ python -m airclip videos/ --outdir dist/
76
+ ```
77
+
78
+ ### As a library
79
+
80
+ ```python
81
+ from airclip import convert_lightweight
82
+
83
+ result = convert_lightweight(
84
+ "input.mp4",
85
+ output_path="output.webm",
86
+ target_fps=24,
87
+ crf=38,
88
+ max_height=720,
89
+ )
90
+
91
+ print(f"{result['input_kb']:.0f} KB → {result['output_kb']:.0f} KB")
92
+ print(f"{result['ratio']:.1f}x smaller")
93
+ ```
94
+
95
+ ## Options
96
+
97
+ | Flag | Default | Description |
98
+ |------|---------|-------------|
99
+ | `--fps` | 24 | Target framerate. Use 15 for near-static content. |
100
+ | `--crf` | 38 | Quality level. Higher = smaller. 35-45 works well for animations. |
101
+ | `--height` | 720 | Max output height in pixels. |
102
+ | `--no-2pass` | off | Skip 2-pass encoding (faster, slightly larger output). |
103
+ | `--outdir` | same as input | Output directory for converted files. |
104
+
105
+ ## CRF guide
106
+
107
+ | CRF | Quality | Best for |
108
+ |-----|---------|----------|
109
+ | 30-34 | High | Live action, complex motion |
110
+ | 35-38 | Good | Animations with fine detail |
111
+ | 39-42 | Small | Diagrams, slides, code demos |
112
+ | 43-50 | Tiny | Static content, simple shapes |
113
+
114
+ ## Embedding on web
115
+
116
+ The output is designed to look native on dark-themed pages:
117
+
118
+ ```html
119
+ <video autoplay muted loop playsinline>
120
+ <source src="animation.webm" type="video/webm">
121
+ <source src="animation.mp4" type="video/mp4"> <!-- fallback -->
122
+ </video>
123
+ ```
124
+
125
+ ```css
126
+ video {
127
+ width: 100%;
128
+ background: transparent;
129
+ border: none;
130
+ border-radius: 12px;
131
+ }
132
+ ```
133
+
134
+ For autoplay-on-scroll:
135
+
136
+ ```javascript
137
+ const observer = new IntersectionObserver((entries) => {
138
+ entries.forEach(e => {
139
+ e.isIntersecting ? e.target.play() : e.target.pause();
140
+ });
141
+ }, { threshold: 0.5 });
142
+
143
+ document.querySelectorAll('video').forEach(v => observer.observe(v));
144
+ ```
145
+
146
+ ## Best results when
147
+
148
+ - Background is a solid or near-solid color (dark themes work great)
149
+ - Content is vector-like: shapes, text, diagrams, code
150
+ - Motion is smooth and predictable (not chaotic)
151
+ - No audio needed
152
+
153
+ ## Results
154
+
155
+ Across 6 test videos: **~1.2 MB → ~93 KB average (12x compression)**. No visible quality loss in browser playback.
156
+
157
+ ## License
158
+
159
+ MIT
@@ -0,0 +1,11 @@
1
+ README.md
2
+ pyproject.toml
3
+ airclip/__init__.py
4
+ airclip/__main__.py
5
+ airclip/airclip.py
6
+ airclip.egg-info/PKG-INFO
7
+ airclip.egg-info/SOURCES.txt
8
+ airclip.egg-info/dependency_links.txt
9
+ airclip.egg-info/entry_points.txt
10
+ airclip.egg-info/requires.txt
11
+ airclip.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ airclip = airclip.airclip:main
@@ -0,0 +1,3 @@
1
+
2
+ [bundled-ffmpeg]
3
+ imageio-ffmpeg
@@ -0,0 +1 @@
1
+ airclip
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "airclip"
7
+ version = "0.1.0"
8
+ description = "Convert any video to an ultra-lightweight WebM that blends seamlessly into web pages."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ authors = [{ name = "Akash Chekka" }]
13
+ keywords = ["video", "webm", "vp9", "compression", "web", "ffmpeg"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "Topic :: Multimedia :: Video :: Conversion",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.10",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ ]
23
+ dependencies = []
24
+
25
+ [project.optional-dependencies]
26
+ bundled-ffmpeg = ["imageio-ffmpeg"]
27
+
28
+ [project.scripts]
29
+ airclip = "airclip.airclip:main"
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/akashchekka/airclip"
33
+ Repository = "https://github.com/akashchekka/airclip"
34
+
35
+ [tool.setuptools.packages.find]
36
+ include = ["airclip*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+