Nodes/ComfyUI-Omnivoice/OmniVoice Speakers
ComfyUI Node

OmniVoice Speakers

The roster node that gives your audiobook an actual cast

By ethanfel·Created 5 months ago·Updated 5 months ago· 6
OmniVoice Speakers
  • speaker_1
  • speaker_2
  • speaker_3
  • speaker_4
  • speaker_5
  • speaker_6
  • speaker_7
  • speaker_8
  • speakers
num_speakers2
modealternate_paragraphs

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's label (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_1speaker_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_speakers says. 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_speakers does 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.

CategoryOmniVoice

Inputs (10)

NameTypeDefaultDescription
num_speakersINT22–8Number of active speaker slots. Changing this value adds or removes speaker_N inputs on the node.
modeCOMBOalternate_paragraphsalternate_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_1optOMNIVOICE_SPEAKER
speaker_2optOMNIVOICE_SPEAKER
speaker_3optOMNIVOICE_SPEAKER
speaker_4optOMNIVOICE_SPEAKER
speaker_5optOMNIVOICE_SPEAKER
speaker_6optOMNIVOICE_SPEAKER
speaker_7optOMNIVOICE_SPEAKER
speaker_8optOMNIVOICE_SPEAKER

Outputs (1)

NameTypeDescription
speakersOMNIVOICE_SPEAKERS