Image 1 — DubForge & DubStage - dub a video scene with your own voice, GPL-3.0, fully offline
Image 2 — DubForge & DubStage - dub a video scene with your own voice, GPL-3.0, fully offline
Image 3 — DubForge & DubStage - dub a video scene with your own voice, GPL-3.0, fully offline

DubForge & DubStage - dub a video scene with your own voice, GPL-3.0, fully offline

My wife wanted to play The Choicer Voicer, a little game show where you do vocal impressions of audio clips. It never picked up her microphone, a known engine-level bug that the developer is actively working on, but that didn't help us on a Saturday evening. She was disappointed, so I built her a simpler version of the part she actually wanted: dubbing a scene, line by line.

It turned into two tools, because the tedious half of dubbing is bookkeeping, cutting the audio into lines, writing down every timestamp, then trying to hit them by ear.

DubForge takes a YouTube link or a local file, trims it to a time span, optionally separates the vocals from the backing audio with Demucs, and detects the spoken segments from the loudness envelope. You correct the clip boundaries in a waveform editor, add subtitles, and it writes out a pack.

DubStage plays a pack line by line: hear the original, record over it, repeat as often as you want. Your take is drawn live on top of the original waveform on a shared time axis, so timing errors become visible instead of something you have to infer. At the end the scene plays back with your recordings mixed over the backing track, exportable as MP4.

Three design decisions that might be worth more than the feature list:

  • A pack is just a folder. Each clip's start time lives in its filename (07_MyLine_44-048.wav = 44.048 s), subtitles sit in a small JSON beside it. No database, no binary index — you can inspect or hand-edit a pack with a file manager and a text editor, and nothing about it is tied to my code.
  • Video is never decoded during playback. A pack is split into JPEG frames once and cached, so playback is just timed image swaps. That sidesteps codec availability entirely and made frame pacing far easier to get right.
  • The waveform comparison normalises both curves to their own peak. What you are judging is rhythm and timing, not whether your mic gain happens to match a film mix.

Stack: Python 3.9+, Tkinter, numpy, ffmpeg, sounddevice, Pillow. Demucs optional.

GPL-3.0: https://github.com/xmrius/dubstage

Where it's rough: Windows only right now, although the genuinely platform-bound parts are just the launcher scripts and two small fallbacks. A Linux or macOS port should be close to mechanical, and I'd welcome one. The optional Demucs path drags in PyTorch, which is a heavy dependency for a nice-to-have; making that a cleaner opt-in is on my list.

u/InternetMammoth8482 — 9 days ago