Nodes/ComfyUI-Kaola-Qwen-TTS/Stage Manager 🎬
ComfyUI Node

Stage Manager 🎬

Stage Manager 🎬

By kana112233Β·Created 8 months agoΒ·Updated 7 months agoΒ· 0
Stage Manager 🎬
  • model
  • role_A_audio
  • role_B_audio
  • role_C_audio
  • role_D_audio
  • role_E_audio
  • role_F_audio
  • role_G_audio
  • audio_mix
  • audio_role_A
  • audio_role_B
  • audio_role_C
  • audio_role_D
  • audio_role_E
  • audio_role_F
  • audio_role_G
  • srt_content
β—„scriptNarrator: The adventure begins. Hero: Let's go!β–Ί
β—„role_definitionsNarrator [A]: A clear, neutral voice. Hero [B]: A brave, young voice.β–Ί
β—„my_turn_interval0.5β–Ί
β—„overlap_handlingignoreβ–Ί
β—„top_p1.00β–Ί
β—„temperature0.70β–Ί
β—„repetition_penalty1.05β–Ί
β—„seed0β–Ί
β—„save_to_filefalseβ–Ί
β—„filename_prefixstage_managerβ–Ί
β—„languageAutoβ–Ί
β—„max_new_tokens2048β–Ί
β—„top_k50β–Ί
β—„enable_text_normalizationtrueβ–Ί

If you want one voice reading one line, the pack's Custom Voice, Voice Design, and Voice Clone nodes are simpler. Qwen3TTSStageManager is for when you want a scene: a narrator, two characters, a voice in your head, and a coherent timeline - all from one node, with subtitles. It's the flagship of ComfyUI-kaola-Qwen-TTS and the reason the pack's example workflow is literally called qwen3_tts_full_studio. The name is hype; the thing mostly delivers.

The pitch: you feed it a model, a script, and a casting sheet, and it casts roles, generates each line, places everything on a timeline, mixes it, and hands you a full stereo track plus per-role stems and an SRT subtitle file. Without it, the same scene is a rat's nest of individually wired Voice Design and Clone nodes fighting over timing. With it, the graph stays almost flat.

How it works

Under the hood it's a mini director with three jobs.

Casting. Your role_definitions box lists one role per line: Name [A]: description, or just Name: description. The [A]–[G] brackets are explicit slot assignments; leave them off and the node auto-assigns the first free slot. The real trick is that the description is dual-purpose. If the matching audio slot (role_A_audio … role_G_audio) has a wire plugged in - ideally from the pack's Ref Audio node so it carries a transcript - that role becomes clone mode and the description is ignored. No wire? Then the description is used as a voice design prompt: "a deep, husky 50-year-old detective" becomes the instruction that invents the voice. So a single scene can mix an AI-designed king with a cloned recording of you, per role.

Script. Each line is Name: line - Chinese colons : work, and so do inline emotions: Wizard: (Mysterious) The seal is broken. gets merged into that role's design instruction. Lines without a name continue the previous speaker. There's a second, explicit format - 1 00:00:00,000 --> 00:00:01,500 Name: line - for frame-accurate placement; otherwise lines stack on the timeline with my_turn_interval of silence between them. Before generating, it pre-scans the script and hard-fails with a readable list of any role that appears in the script but isn't in role_definitions - that error alone has saved me more debugging than any log line.

Mix. Every generated line is placed on a per-role track buffer at 24 kHz, the role tracks are summed into audio_mix, and each line gets a timestamp. Outputs: audio_mix, audio_role_A through audio_role_G, and srt_content with precise HH:MM:SS,mmm timing.

Inputs worth touching

  • model - a QWEN3_TTS_MODEL from the pack's Model Loader. Use the VoiceDesign checkpoint: it does both design and zero-shot cloning. Base also works; the CustomVoice checkpoint is for preset speakers elsewhere, and mismatching model types raises an error.
  • script and role_definitions - the two text boxes above. This is 90% of your actual work.
  • overlap_handling - ignore (let clips overlap), shift_start (push the late one back), or truncate (cut to fit) when explicit timestamps collide.
  • my_turn_interval - seconds of gap between auto-placed lines; 0.5 is a good default, raise it for ponderous dialogue.
  • save_to_file + filename_prefix - when on, writes _MIX.wav and every role stem into ComfyUI's output folder.
  • temperature, top_p, seed - the usual sampling dials; seed is per-line (seed + line index), so changing it re-rolls everything.

Feed srt_content to the pack's Save File node for a real .srt, and audio_mix to SaveAudio. enable_text_normalization on by default is correct - leave it.

Install and models

cd ComfyUI/custom_nodes
git clone https://github.com/kana112233/ComfyUI-kaola-Qwen-TTS
cd ComfyUI-kaola-Qwen-TTS
pip install -r requirements.txt

Restart ComfyUI, or search ComfyUI-kaola-Qwen-TTS in ComfyUI Manager. The qwen-tts dependency force-pins a transformers version, which can clash with other packs - the usual audio-in-ComfyUI tax. Models auto-download to your HuggingFace cache or live in ComfyUI/models/qwen3_tts/; the 1.7B needs ~4GB+ VRAM, and the 0.6B is the escape hatch on smaller cards. Install flash-attn on NVIDIA if you want faster inference.

Where people get burned

The missing-role error (fix: add the role to role_definitions), and the silent failure where a line that's only [sound effects] or brackets generates nothing - the code literally logs a note that pure-bracket text often produces empty audio. Reference clips under 400 samples throw, so keep your clones to a few seconds. And set expectations on likeness: Qwen3-TTS cloning trails VibeVoice and Chatterbox on raw similarity, per the community, so lean on design for distinctive voices and save cloning for voices you can't describe. For a one-node dialogue scene with subtitles, nothing else in ComfyUI gets you there this fast.

CategoryQwen3TTS

Inputs (22)

NameTypeDefaultDescription
modelQWEN3_TTS_MODELβ€”
scriptSTRINGNarrator: The adventure begins. Hero: Let's go!β€”
role_definitionsSTRINGNarrator [A]: A clear, neutral voice. Hero [B]: A brave, young voice.β€”
my_turn_intervalFLOAT0.50–5β€”
overlap_handlingCOMBOignore3 options: ignore, shift_start, truncate
top_poptFLOAT1.000–1β€”
temperatureoptFLOAT0.700–2β€”
repetition_penaltyoptFLOAT1.050–2β€”
seedoptINT00–18446744073709550000β€”
save_to_fileoptBOOLEANfalseβ€”
filename_prefixoptSTRINGstage_managerβ€”
role_A_audiooptAUDIOβ€”
role_B_audiooptAUDIOβ€”
role_C_audiooptAUDIOβ€”
role_D_audiooptAUDIOβ€”
role_E_audiooptAUDIOβ€”
role_F_audiooptAUDIOβ€”
role_G_audiooptAUDIOβ€”
languageoptCOMBOAuto11 options: Auto, Chinese, English, Japanese, Korean, German, +5
max_new_tokensoptINT20481–8192β€”
top_koptINT501–100β€”
enable_text_normalizationoptBOOLEANtrueβ€”

Outputs (9)

NameTypeDescription
audio_mixAUDIOβ€”
audio_role_AAUDIOβ€”
audio_role_BAUDIOβ€”
audio_role_CAUDIOβ€”
audio_role_DAUDIOβ€”
audio_role_EAUDIOβ€”
audio_role_FAUDIOβ€”
audio_role_GAUDIOβ€”
srt_contentSTRINGβ€”