DEV Community

王俊俊
王俊俊

Posted on

Transcribing Video in the Browser Without Uploading the Film

I needed timed subtitles for language study videos that already lived on my disk. Uploading a two-hour lecture to a transcription SaaS felt wrong for privacy and for bandwidth. The shape that worked was: keep the media element local, demux audio in the browser, and send only short mono chunks to a Worker.

The constraint

Playback stays in the page. Local files and direct links (MP4, WebM, HLS) go straight into a <video> / media element. A signed-out library can live in IndexedDB. Sign-in can sync library metadata and subtitle tracks; the film itself never becomes an upload.

That split forces the transcription path to be audio-only.

Chunked audio instead of a full upload

When a file has no usable subtitles, the client:

  1. Demuxes audio in the browser
  2. Skips long silences when possible
  3. Encodes short 16 kHz mono segments (roughly 20–30 seconds)
  4. POSTs each chunk to a Cloudflare Worker

The Worker runs speech-to-text (Workers AI / Whisper-class model), returns timed text, and the client turns that into cues. Existing SRT, VTT, and ASS imports follow the same cue model, so "I already have subtitles" and "generate them" share one player.

Keeping requests small matters more than clever batching. Failed chunks retry without restarting a multi-gigabyte upload.

Why a Worker on the same host helps

A single host serving the Vue app and the API avoids CORS theater for cookie/session flows and keeps the mental model simple: one origin for the player shell. Hono on a Worker is enough for auth, credit accounting, and the STT proxy.

The learning loop is the product

None of the model work matters if seeking is clumsy. The UI unit is a subtitle cue: previous / next, replay, loop one line, or loop an A–B range. Bilingual cues sit on the video. Word lookup opens against that sentence, not a generic dictionary homepage.

If you study from files you already have, that architecture is what I shipped in LangScribe local playback, optional AI captions, and a player built around the line you are trying to hear.

Top comments (0)