IndexTTS2 Script Dubbing (SRT)
Paste an SRT script, get a full multi-character dub out the other end
- model
- emo_audio_prompt
- voice_1
- voice_2
- voice_3
- voice_4
- voice_5
- voice_6
- voice_7
- audio
This is the pack's centerpiece and the node that makes everything else look like a warm-up. Where the other nodes do one voice at a time, Script Dubbing takes a whole SRT subtitle file with character names on every line, matches each character to one of up to seven voice references, synthesizes every line, and assembles the whole thing onto the SRT timeline - a finished multi-character dub in one queue hit. It's the "make a video game line deliverable without editing audio" node, and it's genuinely impressive when it works.
The default script is a Monkey King scene (唐僧 vs 孙悟空), the console logs are in Chinese, and the author clearly built this with a Chinese-first audience in mind. Don't let that put you off - the SRT format and the English/Chinese model work fine either way, but know that the pack's personality shows up here.
How it works
The node parses your script_srt (both standard multi-line SRT and the compact single-line form), splits each line into character, optional emotion, and dialogue using the colon (: or :) as the separator, then matches characters to your connected voice references. Each line is synthesized with IndexTTS-2 and placed on a timeline. The assembly rule is worth knowing: every clip lands at max(its SRT start, the end of the previous clip) - clips are never truncated and never overlap, so if a synthesized line runs long it just pushes everything after it forward. Your output can be longer than the original SRT timeline. That's a feature (no clipped words), just budget for it.
Emotion resolution has a clear priority: emotion written in parentheses after the character name (e.g. 唐僧(高兴的说):) forces text-emotion mode and wins. Otherwise, if emo_audio_prompt is connected, the node slices it by each line's SRT timestamp to drive the emotion. With neither, you get voice-only synthesis. The parenthesized form is the most controllable of the three.
The inputs that matter
script_srt- the script, multiline. Format:
Character, colon, dialogue. Parentheses are optional emotion.1 00:00:01,000 --> 00:00:03,000 唐僧(高兴的说):悟空,你又调皮了。voice_1…voice_7-AUDIOinputs, one per character, fromLoadAudionodes. Any character with novoice_x_namematching a script name falls back to the first connected voice, with a console warning.voice_1_name…voice_7_name- must match the character names in your script exactly.emo_alpha- emotion strength for the audio-emotion path (0–2, default 1).save_segments+segments_prefix- when on, saves every per-line emotion slice and TTS clip as numbered WAVs to{output}/{prefix}_segments/and lists them in the output panel. Handy for reviewing individual lines; off by default.
Output is a single assembled audio (standard ComfyUI AUDIO) plus a UI file list when segments are saved.
Gotchas
It requires at least one voice reference - the node errors out otherwise, and the error message is in Chinese. Also: if a line's emotion text goes to the bundled Qwen classifier, remember the sad-vs-melancholic blind spot from the Emotion Text article. And emo_alpha only affects the audio-emotion path; parenthesized emotion is forced text mode and uses its own default.
Install
Same pack, same steps - Manager search "IndexTTS-2" or clone into custom_nodes, pip install -r requirements.txt, model in ComfyUI/models/IndexTTS-2/. The examples/05_script_dubbing.json workflow in the repo is worth importing instead of building the graph by hand, since it wires up the voice slots and SRT defaults for you.
Inputs (24)
| Name | Type | Default | Description |
|---|---|---|---|
| model | INDEXTTS2_MODEL | — | |
| script_srt | STRING | 1 00:00:01,000 --> 00:00:03,000 唐僧:悟空,你又调皮了。 2 00:00:04,000 --> 00:00:06,000 孙悟空:师父,俺老孙冤枉啊! | — |
| emo_alpha | FLOAT | 1.00–2 | — |
| temperature | FLOAT | 1.00.1–2 | — |
| top_k | INT | 00–100 | — |
| top_p | FLOAT | 1.000–1 | — |
| use_random | BOOLEAN | false | — |
| save_segments | BOOLEAN | false | — |
| segments_prefix | STRING | dubbing | — |
| emo_audio_promptopt | AUDIO | — | |
| voice_1opt | AUDIO | — | |
| voice_1_nameopt | STRING | — | |
| voice_2opt | AUDIO | — | |
| voice_2_nameopt | STRING | — | |
| voice_3opt | AUDIO | — | |
| voice_3_nameopt | STRING | — | |
| voice_4opt | AUDIO | — | |
| voice_4_nameopt | STRING | — | |
| voice_5opt | AUDIO | — | |
| voice_5_nameopt | STRING | — | |
| voice_6opt | AUDIO | — | |
| voice_6_nameopt | STRING | — | |
| voice_7opt | AUDIO | — | |
| voice_7_nameopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |