Audio Transcription (Real-time)
Live captions inside your ComfyUI graph, no API key required
- audio
- STRING
Audio Transcription (Real-time) is the node that turns a live audio stream into a rolling text transcript while the stream is still running - think subtitles on a live generative video, a live-caption overlay for a vTuber rig, or an AI assistant that hears you mid-workflow. The name is not a lie about the architecture: it's local, it uses faster-whisper under the hood, and it needs no API key and no cloud account. It comes from livepeer/ComfyUI-Stream-Pack, the node pack the Livepeer team built alongside ComfyStream for pushing real-time workflows through ComfyUI.
Where it sits in a workflow matters. It's built for streaming, not for transcribing a finished 2-hour podcast. You feed it the same AUDIO type any ComfyUI audio source produces - a dict with waveform and sample_rate, like comfystream's LoadAudioTensor or the core LoadAudio node - and it returns one STRING that updates as audio rolls in.
How it works
The mechanism is a rolling accumulation buffer with throttled output. Each call, the node appends your audio chunk to an internal buffer until it holds accumulation_duration seconds, then runs that buffer through faster-whisper. Whisper is transcript-heavy on silence, so it resamples everything to 16 kHz first, and the enable_vad flag turns on a voice-activity filter that skips dead air (it's on by default). Results go into a small queue, and the node only pops a transcription out when at least transcription_interval seconds have passed since the last output - that's the anti-flood mechanism, so your downstream text node doesn't get a message every frame.
One honest quirk: when the node isn't ready to output, it returns an empty string rather than blocking. Downstream nodes need to tolerate that (the pack's own SRT node handles it), so don't panic if your preview is blank between captions. There's also a __WARMUP_SENTINEL__ value emitted right after the Whisper model loads - it's a pipeline signal, not a real transcription; the SRT node passes it through so the rest of the graph knows the model is finally warm.
The inputs that matter
accumulation_duration(default 3 s) - how much audio it gathers before transcribing. Shorter = faster captions but worse accuracy; the source comments call 2 s "fast response" and 8 s "high quality". This is the knob you'll actually tune.transcription_interval(default 2 s) - minimum seconds between outputs. Raise it if your text display is chattering.whisper_model-tiny→large-v2.base(the default) is a sane real-time compromise;medium/large-v2are meaningfully more accurate but you'll feel the latency.language-autodetects per chunk; pinningenetc. is faster and more reliable if your stream is one language.enable_vad(default on) - filters silence so Whisper doesn't transcribe room tone.output_format(optional) -text,json_segments(timing per segment), orjson_words(word-level timing).json_segmentsis the default and is what the SRT Generator node expects.
Output: a single STRING. Wire it to a text display/save node, or straight into SRTGeneratorNode for timed subtitles.
Installing
It ships in ComfyUI-Stream-Pack, so install the pack once. Easiest is ComfyUI Manager → search "ComfyUI-Stream-Pack" → install. Or from the terminal:
cd ComfyUI/custom_nodes
git clone https://github.com/livepeer/ComfyUI-Stream-Pack
# restart ComfyUI; requirements install on first load
The pack's requirements.txt pulls in faster_whisper, scipy, mediapipe, opencv-contrib-python, diffusers and requests. Faster-whisper drags in CTranslate2, which is the biggest of the bunch, and the Whisper model itself downloads on first run - base is a few hundred MB, so the first transcription call will stall while it fetches (that's the warmup sentinel doing its job).
Where people get burned
- The model downloads on first use, not at install. Your first run looks frozen while faster-whisper pulls
basefrom Hugging Face. It's normal; let it finish. - It's stateful. The accumulation buffer lives on the node instance, so it assumes a single continuous stream per node. Don't feed it disjoint audio files and expect clean per-file captions.
- No CUDA, no problem - but slower. The source tries CUDA first (fp16), else falls back to CPU with int8 quantization. On a CPU-only box, keep the model at
tiny/base. - Empty-string output is the contract. If your downstream text node errors on empty input, filter empties or use the pack's SRT node, which already does.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| transcription_interval | FLOAT | 2.01–10 | Minimum seconds between transcription outputs (optimized for real-time) |
| accumulation_duration | FLOAT | 3.02–10 | Audio accumulation duration for optimal Whisper transcription (reduced for real-time: shorter = faster output, longer = better quality) |
| whisper_model | COMBO | base | Whisper model size (larger = more accurate but slower) |
| language | COMBO | auto | Language for transcription (auto = auto-detect) |
| enable_vad | BOOLEAN | true | Enable Voice Activity Detection to filter silence |
| output_formatopt | COMBO | json_segments | Output format: text (simple), json_segments (with timing), json_words (word-level timing) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| STRING | STRING | — |