DEV Community

王俊俊
王俊俊

Posted on AI-assisted

I built a language-learning player

I wanted the thing I actually do when I study: open a lecture or a show, see the line in two languages, hit replay until the sentence sticks, and click a word I do not know. Desktop players can do pieces of this. Most of them also want an install, a GPU stack, and an API key before the first video plays.

So I built LangScribe as a website. The interesting constraint was privacy: the video file should stay on the machine. Subtitles and a library can sync. The film should not.

What runs where

The app is one Vue 3 frontend. A Cloudflare Worker (Hono) serves the built site and the API on the same host, so the player and the account API are not two deployments.

Playback never leaves the browser. Local files and direct links (MP4, WebM, HLS) are handed to the media element. A signed-out library lives in IndexedDB. Sign in with Google and the library plus subtitle tracks sync; the video file still does not get uploaded.

That split is the whole product. Guest mode has to be useful. Cloud mode has to be optional.

Subtitles without shipping the film

If a video has no subtitles, the browser demuxes the audio, skips silence, and uploads short 16 kHz mono chunks, about 20–30 seconds each. Speech-to-text is Cloudflare Workers AI, Whisper large-v3-turbo. The worker returns timed text; the client turns that into cues and can export SRT. Existing SRT, VTT, and ASS files import the same way.

I did not want a second "upload your course to our servers" step. Chunked audio is enough for transcription, and it keeps the request small.

Translation that can see the previous line

Free translation works without an account, line by line, as you watch.

AI translation is the path that cares about context. Lines go up in small batches with a few preceding subtitle pairs, to a Llama 3.3 70B model on Workers AI. A batch that fails to parse falls back to single-line calls. The player only asks for lines near the playhead, then refills when you are about to run out of translated text. Word lookup is a separate, cached call: part of speech, a short explanation in that sentence, pronunciation.

Credits apply to AI subtitles, AI translation, and AI lookups. Free translation does not. The server records usage; the page does not decide that a feature is free.

The player loop

None of the model work matters if seeking feels clumsy. The UI is built around the cue list: previous line, next line, replay, loop one line, or loop an A–B range. Bilingual cues sit on the video. Click a word and the card opens on that sentence, not on a dictionary homepage.

That is the architecture I would keep if I rewrote the UI: local media, optional account, audio-only transcription, translation with a little context, and a player that treats a subtitle line as the unit of study.

If you learn from video, you can try it at LangScribe.

Top comments (0)