Home/Work/Case 05

Dubljly دبلجلي

Paste an English lecture. Get it back in Arabic: a synced voice-over, subtitles, a study pack, and a tutor that knows the lecture.

RoleFounder · solo build
When2026 · live since the Amman AI Hackathon
StackFastAPI · React 18 · Postgres
ModelsGroq · Gemini · Cerebras · Azure TTS
~25Klines of hand-written code, plus 3,800 of tests
97API route handlers in one FastAPI service
7pipeline steps, run by a single worker
~30sto the study pack, target for a 10-minute lecture
01 / The problem

The best lectures
are in English.

An Arabic-speaking student has two options: read subtitles while trying to follow the content, or wait for a human dubbing studio that will never get to that video.

Dubljly answers one question for that student: can I learn from this lecture in my own language, without waiting? It started as my graduation project and I rebuilt it from scratch for the Amman AI Hackathon.

Subtitles split attention between reading and watching.
Human dubbing costs too much for one lecture.
Arabic runs longer than English, so naive dubbing drifts off the speaker.
No way to ask a question about what was just said.
A timed Arabic voice-over, a study pack first, and a tutor for that lecture.
02 / One lecture, start to finish

Paste a
link.

A YouTube link or an upload goes into a seven-step pipeline. Here is what the student sees.

Step 01 · Fetch and transcribe

Get the words, with their timing.

yt-dlp fetches the video, Whisper transcribes it, and the transcript is cut into timed segments. Long work never runs inside a request: one worker thread pulls jobs from a queue table, and the student watches a six-stage progress bar.

Step 02 · Study pack first

Start learning in about half a minute.

The learning pack (summary, key terms and their Arabic meanings) is built before the dub, so it appears in about 30 to 40 seconds. The full dub follows in about 2 to 3 minutes. Both are spec targets, not measured figures.

Step 03 · Translate, voice, mix

The voice stays with the speaker.

Each segment is translated and voiced on its own, then placed at its original start time, never joined end to end. A fit ladder shortens or speeds up any clip that overruns its slot. The voice-over is mixed with the original audio and exported as MP4, with Arabic and English subtitles.

Step 04 · Ask the tutor

A tutor that knows the lecture.

The student can ask about what they just watched, in Arabic. The whole app is Arabic and right-to-left by default, with an English toggle, real RTL layout rules and fonts chosen for Arabic.

03 / Under the hood

One service.
No extras.

One FastAPI service serves both the API and the React app. No Redis, no Celery, no Docker. Code simplified from the real pipeline.

Adaptersno vendor SDK in the pipeline
text = stt.transcribe(audio) # Whisper todaypack = llm.run("study_pack", text) # router picks a providerclip = tts.speak(seg.arabic, voice) # Azure or edge-ttsplace(clip, at=seg.start) # never end to end
ValidationPydantic, one retry, then fall back
out = llm.json(task, schema=StudyPack)# invalid? retry once with the error attached# still invalid? next provider in the routerpack = StudyPack.model_validate(out)
97 handlers: 49 GET · 38 POST · 8 PUT · 1 PATCH · 1 DELETE24 tables7 data-safe migrationsCI guardrails on every pushCredits, promo codes, admin console
04 / Decisions worth explaining
01Why no Redis, Celery or Docker?

So the whole product stays one deployable service. A single background worker pulls jobs from a queue table in Postgres, and no long job ever runs inside a request handler, so the API stays responsive while lectures process.

02Why place each clip on the timeline instead of joining them?

Arabic often runs longer than English. Joined end to end, every sentence pushes the voice further from the speaker. Placing each clip at its segment’s original start, and fitting any overrun, keeps the voice with the face.

03What happens when a model returns broken JSON?

Structured calls ask for JSON and validate it with Pydantic. Invalid output gets one retry with the validation error attached, then the router falls back to the next provider. The stack mixes Groq, Gemini and Cerebras for language and Azure or edge-tts for voice, all swappable without touching the pipeline.

04How does the UI stay true to the design?

The mockups are the spec. The React screens are rebuilt from them and checked against the design files with a hash check, and the frontend types mirror the documented API contract, enforced by guardrail scripts in CI.

05What is measured, and what is a target?

The 30 to 40 second study pack and the 2 to 3 minute dub for a 10-minute lecture are spec targets, not measured figures. There are no user or revenue numbers yet, so none are claimed here.

Python 3.12FastAPISQLModelAlembicPydanticGroq WhisperGeminiCerebrasAzure Speechyt-dlpffmpegReact 18Tailwind 4TanStack QueryClerkPostgres

Need something like this? I build these end to end, as a full-time engineer, on contract, or with SKAI Group.

Book a 30-min call
Next case · 06Agent Skills OS
Contact

Let's build

Need your content in Arabic, or an AI product built this carefully? One email is enough to start.