Nodes/ComfyUI-F5-TTS-TH/🧚 Narrator Switcher (Beta test)
ComfyUI Node

🧚 Narrator Switcher (Beta test)

Narrator Switcher, beta and honest about it

By gordon123·Created about a year ago·Updated 9 days ago· 14
🧚 Narrator Switcher (Beta test)
  • sample_audio_narator
  • sample_audio_1
  • sample_audio_2
  • sample_audio_3
  • sample_audio_4
  • sample_audio_5
  • remove_silence
  • audio
  • text
text
sample_text_narator
model_pathVIZINTZOR/F5-TTS-THAI/model/model_1000000.pt
seed-1
char_name_1Character1
sample_text_1
char_name_2Character2
sample_text_2
char_name_3Character3
sample_text_3
char_name_4Character4
sample_text_4
char_name_5Character5
sample_text_5
speed1.0
cross_fade_duration0.15
nfe_step32
cfg_strength2.0
sway_sampling_coef-1.0
fix_duration0.0
max_chars250

If F5-TTS-Advance TH is the solo mic, this node is the radio drama. Narrator Switcher takes one multi-line script, splits it into [Speaker]text segments, and voices each one with a different cloned voice - a narrator plus up to five characters - then hands you a single concatenated audio file. It's built for exactly what the name says: fairy tales, audiobooks, Thai dialogue scenes.

And yes, "(Beta test)" is in the display name. This is a wrapper around the pack's own F5TTS_Advance node, and it behaves like a beta: it works, it's clever, and it has rough edges you should know about before you trust it with a 20-minute script.

How it works

Under the hood it isn't a new model - it instantiates F5TTS_Advance and calls its synthesize step once per line of your script, then concatenates the waveforms and returns JSON saying who said what. The flow:

  • Every line that starts with [Name] is parsed for its speaker; the tag is matched case-insensitively (and trailing colons are stripped, so [Narrator:] works too).
  • A line without a tag falls back to the narrator voice, which makes it a natural default for scene descriptions.
  • Each speaker you define needs three inputs: char_name_N, sample_audio_N (their reference clip), and sample_text_N (what that clip says).
  • It then runs one full F5-TTS pass per segment and stitches it all together.

The outputs are audio (the full concatenated waveform) and text - a JSON string with a {speaker, text} entry per line, which is genuinely useful if you're syncing subtitles afterward.

The inputs that matter

The required set is small: text (the multiline script), sample_audio_narator + sample_text_narator (the fallback voice), model_path (same VIZINTZOR/F5-TTS-THAI/model/model_1000000.pt default as the rest of the pack), and seed.

Then the character block, repeated five times: char_name_1 / sample_audio_1 / sample_text_1 through _5. A couple of practical notes: only fill in a character slot you actually have a clip for - an empty or unnamed slot is skipped, and any tag that doesn't match a defined character silently falls back to the narrator. And because each speaker gets a full F5-TTS generation, your total runtime scales with the number of lines: a 50-line script is 50 generations. This is not a real-time tool; it's a "let it bake while you get coffee" tool.

All the F5TTS_Advance dials carry over - speed, remove_silence, max_chars, nfe_step, cfg_strength - and they apply to every segment. If one character's pacing is off you're re-rendering the whole script, so get your reference clips right first.

The honest beta checklist

  • Quality is per-clip. The narrator's reference voice is what every un-tagged line uses, so a weak narrator clip drags the whole piece down. Five seconds of clean audio per character, ideally in the same recording conditions, makes a bigger difference than any sampler setting.
  • Gaps between segments. Each line is generated independently, so pauses between speakers are whatever F5-TTS decided; cross_fade_duration (default 0.15) is your only glue.
  • Concatenation is naive. It literally torch.cats the chunks - no crossfade between them beyond that, and if you set remove_silence on, each line gets its own trimming. Fine for short dialogue, not a polished mixing console.

Installing and troubleshooting

Same pack, same install - Manager search "F5-TTS-TH" or the manual clone below. The submodule step is the one that bites:

cd ComfyUI/custom_nodes
git clone https://github.com/gordon123/ComfyUI-F5-TTS-TH.git
cd ComfyUI-F5-TTS-TH
git submodule update --init --recursive
pip install -r requirements.txt

If a speaker comes out in the narrator's voice, your tag doesn't match char_name_N exactly - the match is case-insensitive but whitespace-sensitive. If a line comes out garbage, it's the same max_chars/long-text issue as the base node; keep individual utterances under a couple hundred characters. And remember the underlying model's weights are CC-BY-NC-4.0 - non-commercial - so this is for hobby storytelling, not the audiobook you plan to sell.

For a beta, it's surprisingly usable for short multi-voice pieces. Just don't blame it when a 200-line fairy tale takes a while - that's the price of doing zero-shot voice cloning on five different voices in a single node.

Category🇹🇭 Thai TTS

Inputs (28)

NameTypeDefaultDescription
textSTRING
sample_audio_naratorAUDIO
sample_text_naratorSTRING
model_pathSTRINGVIZINTZOR/F5-TTS-THAI/model/model_1000000.pt
seedINT-1
char_name_1optSTRINGCharacter1
sample_audio_1optAUDIO
sample_text_1optSTRING
char_name_2optSTRINGCharacter2
sample_audio_2optAUDIO
sample_text_2optSTRING
char_name_3optSTRINGCharacter3
sample_audio_3optAUDIO
sample_text_3optSTRING
char_name_4optSTRINGCharacter4
sample_audio_4optAUDIO
sample_text_4optSTRING
char_name_5optSTRINGCharacter5
sample_audio_5optAUDIO
sample_text_5optSTRING
remove_silenceoptBOOLtrue
speedoptFLOAT1.00.1–5
cross_fade_durationoptFLOAT0.150–1
nfe_stepoptINT321–128
cfg_strengthoptFLOAT2.00–10
sway_sampling_coefoptFLOAT-1.0-5–5
fix_durationoptFLOAT0.00–30
max_charsoptINT2501–1000

Outputs (2)

NameTypeDescription
audioAUDIO
textSTRING