subvid.app

Put subtitles to any video directly from your browser and free

74
18
74
3
TypeScript
public

subvid.app

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


subvid.app — subtitle editor with timeline and live preview

Astro
Tailwind CSS
Whisper
Cloudflare Workers

What it does

  1. Upload a video — drag & drop or browse. Supports MP4, MOV, WebM, and MKV.
  2. Configure languages — pick the audio language (or auto-detect) and the subtitle language.
  3. Generate subtitles — Whisper transcribes the audio; NLLB translates when needed.
  4. Edit in the timeline — fix text, timing, and styling with undo/redo.
  5. Export — download an .srt file or a new video with burned-in captions.

Everything runs client-side. Your video never leaves your device.

Features

  • AI transcriptionWhisper via transformers.js, with optional WebGPU acceleration.
  • AI translationNLLB-200 for multilingual subtitle tracks.
  • Subtitle editor — segment list, timeline scrubbing, multi-language tracks, caption presets (font, color, background, outline, position).
  • Export options
    • .srt subtitle 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).

Tech stack

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)

Requirements

  • 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.

Getting started

# 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 dev

No environment variables or external services are required for local development.

Scripts

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

Project structure

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.

Architecture notes

  • 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.

Browser capabilities

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

Deployment

The site is deployed as static assets on Cloudflare Workers. Configuration lives in wrangler.jsonc:

pnpm deploy

You need a Cloudflare account and Wrangler authenticated (wrangler login).

Adding a language

  1. Add the locale code to i18n.locales in astro.config.mjs.
  2. Create src/pages/<code>/index.astro (copy src/pages/es/index.astro).
  3. Add a translation block in src/i18n/ui.ts mirroring the English keys.
  4. Register the display name in languages inside src/i18n/ui.ts.

Privacy

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.

License

See the repository for license details.

Author

Built by midudev.

v0.3.3[beta]