Generate, edit, translate, and export subtitles for any video — entirely in your browser.
No uploads. No backend. No API keys.
🌐 Live site · 📦 Repository · 🚀 Getting started
- Upload a video — drag & drop or browse. Supports MP4, MOV, WebM, and MKV.
- Configure languages — pick the audio language (or auto-detect) and the subtitle language.
- Generate subtitles — Whisper transcribes the audio; NLLB translates when needed.
- Edit in the timeline — fix text, timing, and styling with undo/redo.
- Export — download an
.srtfile or a new video with burned-in captions.
Everything runs client-side. Your video never leaves your device.
- AI transcription — Whisper via transformers.js, with optional WebGPU acceleration.
- AI translation — NLLB-200 for multilingual subtitle tracks.
- Subtitle editor — segment list, timeline scrubbing, multi-language tracks, caption presets (font, color, background, outline, position).
- Export options
.srtsubtitle file- MP4 with hard-coded subtitles (WebCodecs + mediabunny when available; canvas + MediaRecorder as fallback)
- Internationalization — English (default) and Spanish, with static pages per locale.
- Offline-friendly models — AI weights are downloaded once and cached in the browser (IndexedDB).
| Layer | Technology |
|---|---|
| Framework | Astro 6 (static site) |
| Styling | Tailwind CSS 4 |
| Speech recognition | @xenova/transformers (Whisper) |
| Translation | transformers.js (NLLB-200) |
| Audio extraction | @ffmpeg/ffmpeg (WASM) |
| Video export | mediabunny + WebCodecs |
| Deployment | Cloudflare Workers (static assets) |
- Node.js ≥ 22.12.0
- pnpm (recommended package manager for this repo)
For end users, a modern Chromium-based browser (Chrome, Edge, Brave) or Firefox is recommended. Safari works but WebCodecs export may fall back to the slower MediaRecorder path.
# Clone the repository
git clone https://github.com/midudev/subvid.app.git
cd subvid.app
# Install dependencies
pnpm install
# Start the dev server (http://localhost:4321)
pnpm devNo environment variables or external services are required for local development.
| Command | Description |
|---|---|
pnpm dev |
Start Astro dev server at localhost:4321 |
pnpm build |
Build the production site to ./dist/ |
pnpm preview |
Preview the production build locally |
pnpm preview:cf |
Build and preview with Wrangler (Cloudflare Workers runtime) |
pnpm deploy |
Build and deploy to Cloudflare Workers |
src/
├── components/ # Astro UI (upload, config, editor, export modal, …)
├── i18n/ui.ts # Translations (en, es) — server + client strings
├── layouts/ # HTML shell, hreflang, meta tags
├── pages/ # Routes: / (en), /es/ (es)
├── scripts/
│ ├── app.ts # Main client logic (state, transcription, export)
│ ├── transcriber.worker.ts # Web Worker for AI models
│ └── dom.ts # DOM helpers
└── styles/ # Global and app-specific CSS
The app is a multi-stage SPA embedded in static Astro pages. Server-rendered copy lives in src/i18n/ui.ts; runtime strings for the active locale are injected into window.__I18N__ so only one language ships per page.
- Main thread — UI, video playback, timeline, FFmpeg orchestration, export rendering.
- Transcriber worker — loads Whisper/NLLB and runs inference off the main thread so the UI stays responsive.
- FFmpeg worker — extracts audio from the uploaded video before transcription.
- Model downloads — fetched from Hugging Face on first use (~150 MB for Whisper base + translation model). Progress is shown in the status dock; models can be cleared from the downloads panel.
| Capability | Used for |
|---|---|
| WebGPU | Faster Whisper inference (when supported) |
| WebCodecs | Fast MP4 export with burned-in subtitles |
| SharedArrayBuffer / cross-origin isolation | Required by FFmpeg WASM in some environments |
The site is deployed as static assets on Cloudflare Workers. Configuration lives in wrangler.jsonc:
pnpm deployYou need a Cloudflare account and Wrangler authenticated (wrangler login).
- Add the locale code to
i18n.localesinastro.config.mjs. - Create
src/pages/<code>/index.astro(copysrc/pages/es/index.astro). - Add a translation block in
src/i18n/ui.tsmirroring the English keys. - Register the display name in
languagesinsidesrc/i18n/ui.ts.
subvid.app is designed around local-first processing:
- Videos are read from disk via the File API — never uploaded.
- AI models run in Web Workers with WASM/WebGPU.
- No analytics backend or user accounts in this codebase.
See the repository for license details.
Built by midudev.