The first weekend I tried to build LiveDub, I couldn't get the audio out of the browser. Not the hard part, not the model, not the TTS. Just getting the damn sound that was already playing in a tab and handing it to a script. Everything else was downstream of that, and nothing moved until I solved it.
Here's the thing about capturing browser tab audio that nobody warns you about: the browser doesn't hand you a stream you can just read. What you mostly have access to from an extension is the microphone, via getUserMedia. That gives you what the machine hears, which is not the same as what the tab is playing. You want the tab's own audio, clean, no speaker bleed, no room echo. A microphone grab of a movie playing on speakers is a disaster for transcription.
How to capture browser tab audio the way a dubber needs
There are two honest routes.
First is an off-screen capture element. You render the tab to a hidden canvas and pull the audio along with it. It works, it's clean, but it's heavier than it sounds and it fights with how some players render.
Second — the one I ended up on — is a loopback. The extension grabs the system audio output and subtracts everything that isn't that tab. Or you go lower and use a loopback channel at the OS level. On Windows that's where the loopback sits.
The short version: an extension can subscribe to the audio stream of its own tab. It doesn't need the mic, and it doesn't need to hear your speakers. That stream is what you pipe into Whisper.
The part that looks easy and isn't
Autoplay. Chrome used to let any tab blast audio the moment a page loaded, and tab capture was trivial. Then autoplay restrictions arrived, and suddenly a background tab isn't producing audio for you to capture until the user actually starts the video. So you can't just have a dubber sitting in a tab waiting. You have to ride the user's play state, or play in a way the browser lets audio flow.
I also burn CPU asking whether there's even audio before I kick off transcription. I watch the volume envelope and wait for a real pause — about 450ms of quiet — before I treat a chunk as a finished sentence. A fixed timer clips sentences in half and Whisper hallucinates on the pieces. A pause detector keeps the transcript whole.
Why this stays local
The whole pipeline — tab audio, Whisper, the LM Studio LLM that translates, Kokoro speaking — runs on my machine. Nothing is uploaded, and once the models are pulled it works offline. I watch a film in a language I don't speak and hear it in English while it plays, with the original dialogue ducking under the dub. No account, no credits, no API key.
It's Windows-only, Python 3.10+, and needs LM Studio (free) plus one small model around 2GB. No GPU required, though one makes Whisper noticeably snappier. And yes, it lags a sentence or two behind — it can't translate a line until the speaker finishes. Every dubbing tool has that delay; the honest ones admit it.
FAQ
Can a browser extension capture audio without the microphone?
Yes. An extension can subscribe to its own tab's audio stream directly, which is exactly how a local dubber avoids mic bleed and room noise.
Does capturing tab audio work offline?
Yes, once models are installed. The capture, transcription, translation, and speech all run on your machine with no network connection.
Is browser tab audio capture heavy on CPU?
The capture itself is light. The cost is in transcription, which is why it helps to watch for natural pauses instead of transcribing on a fixed clock.
If you want the finished thing rather than the archaeology, I sell LiveDub on Gumroad (https://symshah.gumroad.com/l/livedub) for $19 once. Setup is a download, LM Studio, one small model, and you're dubbing whatever you watch.
Top comments (0)