VoxCPM SRT Dubber (Replace Audio)
Replace one line of dialogue without regenerating the whole track
- model
- cache_group
- original_audio
- AUDIO
The Processor builds a track from nothing. The Dubber is the surgical version: it takes your existing audio, keeps everything except the lines you want changed, and re-speaks just those. If you flubbed a word, want to change a line, or need a whole character's voice replaced in an old recording, this saves you from re-rendering the entire video's audio. It's the pack's "edit in place" node.
How it works
You feed it the original audio, an SRT that matches it, and a space-separated list of which entries to replace. For each selected entry it:
- Mutes the original audio across that entry's time range.
- Generates new speech with VoxCPM, using the speaker cache that matches the SRT prefix.
- Resamples the generated 16 kHz voice up/down to your original audio's sample rate.
- Inserts it at the entry's start time.
Everything else in the track is untouched. Output is AUDIO at the original file's sample rate - a nice detail, because it means the result drops straight back into the same project without a resampling mismatch. One caveat: stereo input gets averaged to mono for processing, so don't expect the replace to preserve a stereo image.
entries_to_replace is the trap
It's a string like 1 3 5, and the numbers are subtitle index numbers, not line order. The README's example is the perfect warning: in a non-standard SRT numbered 1 2 3 5 6, entering 4 matches nothing. And if your SRT has duplicate numbers (some generators do), entering 4 replaces both entries numbered 4. The Dubber parses your SRT and matches on the index column, so keep that file consistent with what's actually on screen.
The rest of the inputs are the pack's common synth controls: normalize_text, stretch_method (none/librosa/pydub - pydub needs FFmpeg in PATH), cfg_value, inference_timesteps, seed, retry_max_attempts/retry_threshold for the length-ratio retry logic, and keep_model_loaded. Same defaults as the Processor: cfg 2.0, 30 steps, retry 3/6.0.
One more edge case worth knowing: if the SRT's end time for an entry runs past the end of the audio file, the node extends the timeline with silence rather than erroring - so a sloppy SRT can give you a slightly longer track with a tail of silence. Trim it, or fix the SRT.
Installing it
This node is part of the judian17/ComfyUI-SRT-subtitles-VoxCPM pack:
cd ComfyUI/custom_nodes
git clone https://github.com/judian17/ComfyUI-SRT-subtitles-VoxCPM
Restart ComfyUI, or grab it via ComfyUI Manager (search "SRT subtitles VoxCPM"). First run pulls openbmb/VoxCPM-0.5B into models/TTS, and the pack's requirements add librosa, pydub, soundfile and the transformers stack to your environment. The shipped example SRT_VoxCPM_edit.json shows the full wiring - Loader, a few Cache Builders trimmed from the original audio, a Cache Combiner chain, then the Dubber feeding SaveAudio.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| model | VOXCPM_MODEL | — | |
| cache_group | CACHE_GROUP | — | |
| original_audio | AUDIO | — | |
| srt_text | STRING | — | |
| entries_to_replace | STRING | 1 2 | — |
| normalize_text | BOOLEAN | true | — |
| stretch_method | COMBO | librosa | 3 options: none, librosa, pydub |
| keep_model_loaded | BOOLEAN | true | — |
| stretch_n_fft | INT | 320128–8192 | — |
| stretch_hop_length | INT | 88–2048 | — |
| cfg_value | FLOAT | 2.01–10 | — |
| inference_timesteps | INT | 301–100 | — |
| seed | INT | -1-1–9223372036854776000 | — |
| retry_max_attempts | INT | 30–10 | — |
| retry_threshold | FLOAT | 6.002–20 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| AUDIO | AUDIO | — |