RunningHub VoxCPM Multi-Speaker (Dynamic Audio)
Multi-speaker VoxCPM with inputs that grow as you connect them
- model
- audio_1
- audio_2
- audio
This is the smarter sibling of the fixed five-slot Multi-Speaker node, and the answer to the complaint that node leaves you staring at empty sockets. RunningHub VoxCPM Multi-Speaker (Dynamic Audio) uses the same tagged [spk1]...[spk2] script format but lets reference-audio inputs appear and disappear as you actually connect them - it starts with two, and adds the next one every time all visible inputs are connected. No fixed upper limit, so a 12-voice radio drama is just a matter of wiring more clips.
The mechanism is worth knowing because it's the one thing in this pack that's a little magical. A frontend extension script (the pack ships it in js/voxcpm_audio_list.js) watches the node's connections and renames, adds, and trims audio_1, audio_2, ... inputs on the fly. That's browser-side behavior, which means two practical gotchas: it needs a page refresh after the pack updates to pick up the script, and the audio_N slot order maps to spkN at execution time - so audio_10 really does feed [spk10] in your script.
What the node actually asks for
- script - the tagged dialogue, same format as the fixed version.
- speaker_controls - this is the big difference. Instead of one
control_Nwidget per speaker, you write all descriptions in a single multiline field using the tags themselves:[spk1]Sichuan accent [spk2]Adult female, northeastern accent [spk5]Narrator, mature male - reference_texts - optional tagged exact transcripts for each clip, e.g.
[spk1]Reference words. Blank falls back to VoxCPM2's reference-only conditioning, which is safe and usually fine. - audio_1, audio_2, ... - the dynamic reference clips. Leave one empty and it stays a designed voice; connect them all and a new slot appears.
The rest is the standard set: cfg_value (2.0), inference_steps (10), seed, normalize_text, denoise_reference, max_len (4096), retry_badcase (on). Output is one audio wire with the whole dialogue.
Setup
Identical to the rest of the pack:
cd ComfyUI/custom_nodes
git clone https://github.com/RH-RunningHub/ComfyUI_RH_VoxCPM.git
cd ComfyUI_RH_VoxCPM && pip install -r requirements.txt
hf download openbmb/VoxCPM2 --local-dir ComfyUI/models/voxcpm/VoxCPM2
Restart ComfyUI, then - and this is the part people skip - hard-refresh the browser tab. The dynamic inputs are driven by a frontend extension, and a stale page is the #1 reason this node looks broken right after install.
Traps to sidestep
The auto-growth is the whole feature and the whole failure mode. If you connect audio_1 and audio_2 and no audio_3 appears, the JS didn't load - refresh. If you then connect audio clips in a different order than the tags in your script, the voice-to-speaker mapping goes sideways because mapping is positional, not by tag content. And if you disconnect an audio input, the script trims trailing inputs, which can renumber slots mid-workflow - don't build a huge multi-speaker graph on top of a live-growing socket list. For a fixed cast of five or fewer, the plain Multi-Speaker node is honestly the more predictable choice; this one earns its keep when your speaker count varies between runs or climbs past five.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| model | VOXCPM_MODEL | — | |
| script | STRING | [spk5]今日AI新闻速报 [spk1]T8那个瓜娃子,又更新什么了? [spk2]管他干啥呀,带派不就行了。 [spk1]天天只知道做视频,耳都不耳人一哈。 [spk2]别笑哈,你试你也过不了第二关。 | — |
| speaker_controls | STRING | [spk1]四川话 [spk2]成年女性,东北话 [spk5]旁白音,成熟男性 | — |
| cfg_value | FLOAT | 2.00.1–5 | — |
| inference_steps | INT | 101–50 | — |
| seed | INT | 00–18446744073709550000 | — |
| audio_1opt | AUDIO | — | |
| audio_2opt | AUDIO | — | |
| normalize_textopt | BOOLEAN | false | — |
| denoise_referenceopt | BOOLEAN | false | — |
| max_lenopt | INT | 409664–8192 | — |
| retry_badcaseopt | BOOLEAN | true | — |
| reference_textsopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |