OmniVoice Speakers
The roster node that gives your audiobook an actual cast
- speaker_1
- speaker_2
- speaker_3
- speaker_4
- speaker_5
- speaker_6
- speaker_7
- speaker_8
- speakers
OmniVoice Speakers is where single-voice TTS stops being single-voice. You feed it a bunch of OmniVoice Speaker nodes - one per character - and it becomes a roster that tells OmniVoice Generate how to route paragraphs between them. A narrator and two characters reading alternate passages, a podcast with rotating hosts, a script with named parts: this node is the cast list, and Generate is the actor who plays everyone.
The hook is that it works on one model and one Generate node. OmniVoice's diffusive multi-speaker handling means the roster drives per-paragraph cloning internally - you don't need a Generate node per character, and the output comes back as one continuous audio file, which is exactly what you want for a chapter.
How it works
The roster is assembled from connected Speaker nodes, and it has two modes, picked by mode:
alternate_paragraphs- the default, and the lazy one. Paragraphs (split on blank lines) just rotate through the speakers in order: 1 → 2 → 3 → 1 → …. No tags in your text, no fuss. Great for a two-hander; falls apart if you want specific characters on specific lines.tagged_speakers- the precise one. You prefix paragraphs with[Label], like[Narrator] The door creaked open.then a blank line, then[Alice] Who is there?. The label must match a Speaker node'slabel(case-insensitive), and any unrecognized tag silently falls back to speaker 1. Multi-line speeches work: continuation lines without a tag get glued to the previous speaker's segment.
The one input that looks like magic: num_speakers (2–8). Change it and the node's input slots physically appear and disappear - that's a small web extension the pack ships, so it needs the ComfyUI frontend to have loaded the pack's web/ directory. Behind the scenes it shows only the first N speaker_N slots.
The inputs that matter
num_speakers- how many slots you get. Set it to 2 first, prove the pipeline, then expand.mode- alternate vs. tagged, as above.speaker_1…speaker_8- the actual voices, one Speaker node per slot.
One output: speakers (type OMNIVOICE_SPEAKERS), which wires straight into the speakers input on OmniVoice Generate. Connect it and Generate ignores its own ref_audio, instruct, and mode - the roster takes over.
Installing it
Part of ethanfel/ComfyUI-Omnivoice. ComfyUI Manager (search "OmniVoice") or:
cd ComfyUI/custom_nodes
git clone https://github.com/ethanfel/ComfyUI-Omnivoice.git
then restart. Note the web-extension dependency: the dynamic speaker slots only work if ComfyUI loaded the pack's frontend files, which requires the restart (and a refresh of your browser tab if you're mid-session).
Common issues
- "At least 2 speakers must be connected" - the roster demands a minimum of two wired speakers, no matter what
num_speakerssays. Also watch out: slots you declare but leave disconnected are skipped, so a three-slot roster with only two wires just runs two voices. - The wrong character talks in tagged mode. Label mismatch. The tag in your text has to match a Speaker's
label, and unmatched tags fall back to speaker 1, which is the exact failure that looks random. - Speaker slots not appearing. If changing
num_speakersdoes nothing, the web extension didn't load - restart ComfyUI and hard-refresh the browser. (The inputs still exist server-side, so workflows from a working session usually load fine.) - Multi-speaker output has odd pacing. Each paragraph is cloned and generated separately, then concatenated. If the voices feel inconsistent, check the transcripts on the Speaker nodes - the same reference-quality rules apply here as anywhere in OmniVoice.
This is the pack's most ambitious node and it's genuinely neat when it works. The honest caveat: keeping several distinct voices consistent over a long script is where TTS still shows its seams. Two voices, great. A full cast, expect to babysit it.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| num_speakers | INT | 22–8 | Number of active speaker slots. Changing this value adds or removes speaker_N inputs on the node. |
| mode | COMBO | alternate_paragraphs | alternate_paragraphs – paragraphs (separated by blank lines) rotate through speakers in order: 1 → 2 → 3 → 1 → … tagged_speakers – prefix each paragraph with [Label] to assign a specific speaker. Labels must match those on the Speaker nodes. Unrecognised tags fall back to speaker 1. Example: [Narrator] The door creaked open. [Alice] Who is there? |
| speaker_1opt | OMNIVOICE_SPEAKER | — | |
| speaker_2opt | OMNIVOICE_SPEAKER | — | |
| speaker_3opt | OMNIVOICE_SPEAKER | — | |
| speaker_4opt | OMNIVOICE_SPEAKER | — | |
| speaker_5opt | OMNIVOICE_SPEAKER | — | |
| speaker_6opt | OMNIVOICE_SPEAKER | — | |
| speaker_7opt | OMNIVOICE_SPEAKER | — | |
| speaker_8opt | OMNIVOICE_SPEAKER | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| speakers | OMNIVOICE_SPEAKERS | — |