|
2 | 2 |
|
3 | 3 | # MasterSelects |
4 | 4 |
|
5 | | -<h3>Browser-based Video Compositor</h3> |
| 5 | +<h3>Browser-based Video Compositor & 3D Engine</h3> |
| 6 | + |
| 7 | +<br> |
| 8 | + |
| 9 | +<table><tr><td align="center" style="border:none;background:#0d1117;"> |
| 10 | +<h1>⚡ 660 KB <sub>gzip</sub></h1> |
| 11 | +<sup><b>initial load</b></sup> |
| 12 | +</td></tr></table> |
| 13 | + |
6 | 14 |
|
7 | 15 | <p> |
8 | | - GPU-first editing with <b>30 effects</b>, <b>37 blend modes</b>, <b>76 AI tools</b>, and only <b>13 dependencies</b>.<br> |
9 | | - Built from scratch in <b>2,500+ lines of WGSL</b> and <b>120k lines of TypeScript</b>. |
| 16 | + GPU-first editing with <b>30 effects</b>, <b>37 blend modes</b>, <b>76 AI tools</b>, <b>real 3D via Three.js</b>, and only <b>14 dependencies</b>.<br> |
| 17 | + Built from scratch in <b>2,400+ lines of WGSL</b> and <b>138k lines of TypeScript</b>.<br> |
| 18 | + Import <b>OBJ, glTF, GLB, FBX</b> models directly into the timeline. |
10 | 19 | </p> |
11 | 20 |
|
12 | 21 | <p> |
13 | | - <a href="https://github.com/Sportinger/MasterSelects/releases"><img src="https://img.shields.io/badge/version-1.4.0-blue.svg" alt="Version"></a> |
| 22 | + <a href="https://github.com/Sportinger/MasterSelects/releases"><img src="https://img.shields.io/badge/version-1.4.2-blue.svg" alt="Version"></a> |
14 | 23 | <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a> |
15 | 24 | <a href="https://app.fossa.com/projects/custom%2b61097%2fmasterselects"><img src="https://app.fossa.com/api/projects/custom%2b61097%2fmasterselects.svg?type=shield" alt="FOSSA Status"></a> |
16 | 25 | </p> |
17 | 26 |
|
18 | 27 | <p> |
19 | 28 | <a href="#"><img src="https://img.shields.io/badge/WebGPU-990000?style=flat-square&logo=webgpu&logoColor=white" alt="WebGPU"></a> |
| 29 | + <a href="#"><img src="https://img.shields.io/badge/Three.js-000000?style=flat-square&logo=threedotjs&logoColor=white" alt="Three.js"></a> |
20 | 30 | <a href="#"><img src="https://img.shields.io/badge/React_19-61DAFB?style=flat-square&logo=react&logoColor=black" alt="React 19"></a> |
21 | 31 | <a href="#"><img src="https://img.shields.io/badge/TypeScript-3178C6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript"></a> |
22 | 32 | <a href="#"><img src="https://img.shields.io/badge/Vite-646CFF?style=flat-square&logo=vite&logoColor=white" alt="Vite"></a> |
|
31 | 41 |
|
32 | 42 | --- |
33 | 43 |
|
34 | | -## Security Model |
| 44 | +## Supported Formats |
35 | 45 |
|
36 | | -MasterSelects is a **local-first editor**. Your timeline, media processing, rendering, and most AI-adjacent operations stay on your machine unless you explicitly call an external API. The project now has explicit trust boundaries instead of relying on "it's just localhost". |
| 46 | +Decoding depends on what the **browser** supports — the container is just the wrapper, the codec inside is what matters. |
37 | 47 |
|
38 | | -**Current protections:** |
39 | | -- **Native Helper bridge:** Binds to `127.0.0.1` only and requires a random startup Bearer token for HTTP and WebSocket bridge operations |
40 | | -- **Dev bridge hardening:** Vite `/api/ai-tools` and local file routes require a per-session token and reject non-loopback browser origins |
41 | | -- **Path restrictions:** Local file reads, listings, uploads, and locate/search operations are restricted to explicit allowed roots instead of arbitrary disk access |
42 | | -- **AI tool policy:** External bridge calls run through caller restrictions and approval/confirmation gates instead of getting unrestricted editor control |
43 | | -- **Secret handling:** API keys are stored in encrypted IndexedDB, `.keys.enc` import/export is disabled, and logs redact common secret/token patterns |
44 | | -- **Security verification:** CI includes secret scanning plus JS and Rust security checks, and the repo has dedicated tests for bridge auth, file access, and tool policy behavior |
| 48 | +<table> |
| 49 | +<tr><th colspan="2">Import (Decode)</th></tr> |
| 50 | +<tr><td><b>Containers</b></td><td>MP4, MOV, WebM, MKV, AVI, M4V</td></tr> |
| 51 | +<tr><td><b>Video codecs</b></td><td>H.264 (AVC), H.265 (HEVC)¹, VP8, VP9, AV1</td></tr> |
| 52 | +<tr><td><b>Audio codecs</b></td><td>AAC, MP3, Opus, Vorbis, FLAC, WAV/PCM</td></tr> |
| 53 | +<tr><td><b>Image</b></td><td>PNG, JPG, WebP, GIF, BMP, AVIF, SVG</td></tr> |
| 54 | +<tr><td><b>3D Models</b></td><td>OBJ, glTF, GLB, FBX — rendered via Three.js with lighting</td></tr> |
| 55 | +<tr><td><b>Download</b></td><td>YouTube, TikTok, Instagram, Twitter/X, Vimeo + <a href="https://github.com/yt-dlp/yt-dlp/blob/master/supportedsites.md">all yt-dlp sites</a> via Native Helper</td></tr> |
| 56 | +<tr><th colspan="2">Export (Encode)</th></tr> |
| 57 | +<tr><td><b>Containers</b></td><td>MP4, WebM</td></tr> |
| 58 | +<tr><td><b>Video codecs</b></td><td>H.264, H.265¹, VP9, AV1 — GPU-accelerated via WebCodecs</td></tr> |
| 59 | +<tr><td><b>Audio codecs</b></td><td>AAC (MP4), Opus (WebM)</td></tr> |
| 60 | +<tr><td><b>Interchange</b></td><td>FCPXML (Final Cut Pro / DaVinci Resolve), PNG sequence</td></tr> |
| 61 | +</table> |
45 | 62 |
|
46 | | -**Known boundary:** this is still not "perfect sandboxing". Same-user local processes, malicious browser extensions, and compromised same-origin code can still be dangerous. The goal here is **clear, test-covered local trust boundaries**, not pretending a browser app is magically zero-risk. |
| 63 | +¹ H.265 decode/encode depends on OS & hardware — full support on Windows, partial on macOS/Linux. |
47 | 64 |
|
48 | | -See [Security.md](docs/Features/Security.md) for the full trust model, secret handling, bridge details, and current limitations. |
| 65 | +> **MOV** files work because they share the same ISO BMFF container as MP4 — any MOV with H.264/H.265 inside plays fine. **MKV** works if it contains browser-decodable codecs (H.264, VP9, etc.). Files with unsupported codecs (e.g. ProRes in MOV) fall back to the Native Helper decode path when available. |
49 | 66 |
|
50 | 67 | --- |
51 | 68 |
|
52 | 69 | ## What Makes This Different |
53 | 70 |
|
54 | 71 | Most browser-based video editors share a pattern: Canvas 2D compositing, heavyweight dependency trees, and CPU-bound rendering that falls apart at scale. This project takes a fundamentally different approach. |
55 | 72 |
|
56 | | -**GPU-first architecture.** Preview, scrubbing, and export all run through the same **WebGPU ping-pong compositor**. Video textures are imported as `texture_external` (**zero-copy**, no CPU roundtrip). **37 blend modes**, 3D rotation, and inline color effects all execute in a **single WGSL composite shader** per layer. No Three.js, no GSAP, no Canvas 2D fallback in the hot path. |
| 73 | +**GPU-first architecture.** Preview, scrubbing, and export all run through the same **WebGPU ping-pong compositor**. Video textures are imported as `texture_external` (**zero-copy**, no CPU roundtrip). **37 blend modes**, 3D rotation, and inline color effects all execute in a **single WGSL composite shader** per layer. **Three.js** is lazily loaded only for 3D model rendering — no GSAP, no Canvas 2D fallback in the hot path. |
57 | 74 |
|
58 | 75 | **Zero-copy export pipeline.** Frames are captured as `new VideoFrame(offscreenCanvas)` directly from the GPU canvas. **No `readPixels()`**, no `getImageData()`, no staging buffers in the default path. The GPU renders, **WebCodecs encodes**. That's it. |
59 | 76 |
|
@@ -161,23 +178,25 @@ cargo run --release # WebSocket :9876, HTTP :9877 |
161 | 178 | | **AI Control** | Local HTTP bridge for external agents to steer the running editor | |
162 | 179 | | **Download** | yt-dlp integration for YouTube, TikTok, Instagram, Twitter/X, Vimeo, and other supported sites | |
163 | 180 |
|
164 | | -**Export codecs:** H.264, H.265, VP9, AV1 via WebCodecs (production). ProRes, DNxHR, FFV1, UTVideo, MJPEG via experimental FFmpeg WASM path (single-threaded, requires custom build). |
165 | | - |
166 | 181 | **Platforms:** Windows, Linux, macOS. Building the Native Helper requires Rust. Downloads also require `yt-dlp`. See [Native Helper docs](tools/native-helper/README.md) for platform-specific setup. |
167 | 182 |
|
168 | 183 | --- |
169 | 184 |
|
170 | | -## Security Model |
| 185 | +## Security |
| 186 | + |
| 187 | +MasterSelects is a **local-first editor**. Editing, rendering, caching, and most analysis stay in the browser unless you explicitly invoke an external provider or the Native Helper. |
171 | 188 |
|
172 | | -MasterSelects is local-first: editing, rendering, caching, and most analysis stay in the browser unless you explicitly invoke an external provider or the Native Helper. |
| 189 | +- **API keys:** stored in IndexedDB with per-browser Web Crypto encryption |
| 190 | +- **Native Helper:** binds to `127.0.0.1` only, requires a random startup Bearer token for HTTP and WebSocket |
| 191 | +- **Dev bridge:** Vite `/api/ai-tools` and local file routes require a per-session token and reject non-loopback origins |
| 192 | +- **Local file access:** restricted to explicit allowed roots (project root, temp, Desktop, Documents, Downloads, Videos) |
| 193 | +- **AI tool policy:** external bridge calls run through caller restrictions and approval gates |
| 194 | +- **Secret handling:** logs redact common secret/token patterns; `.keys.enc` export disabled |
| 195 | +- **CI checks:** secret scanning, JS and Rust security audits, dedicated tests for bridge auth and file access policy |
173 | 196 |
|
174 | | -- **API keys:** stored in IndexedDB with per-browser Web Crypto encryption. This protects against casual inspection, not against same-origin script execution. |
175 | | -- **Dev bridge:** sensitive Vite routes require a per-session Bearer token and only accept localhost browser origins. |
176 | | -- **Native Helper:** binds to `127.0.0.1` and requires a random startup token for HTTP and WebSocket bridge operations. |
177 | | -- **Local file access:** limited to explicit roots such as the project root, temp, Desktop, Documents, Downloads, and Videos, plus optional `MASTERSELECTS_ALLOWED_FILE_ROOTS`. |
178 | | -- **Key export:** `.keys.enc` export/import is disabled until passphrase-based encryption is implemented. |
| 197 | +**Known boundary:** this is not perfect sandboxing. Same-user local processes, malicious browser extensions, and compromised same-origin code can still be dangerous. The goal is **clear, test-covered local trust boundaries**. |
179 | 198 |
|
180 | | -See [Security docs](docs/Features/Security.md) for the trust model and known limitations, and [Native Helper docs](tools/native-helper/README.md) for auth examples. |
| 199 | +See [Security.md](docs/Features/Security.md) for the full trust model and limitations. |
181 | 200 |
|
182 | 201 | --- |
183 | 202 |
|
|
0 commit comments