Files
Ethanfel 95cf706b19 feat: add multi-speaker generation with JS-powered dynamic slots
- Add OmniVoiceSpeaker node (label + ref_audio + ref_text → OMNIVOICE_SPEAKER)
- Add OmniVoiceSpeakers node (roster with dynamic speaker_N inputs driven by
  num_speakers INT widget; slots expand/collapse via ComfyUI JS extension)
- Add web/multi_speaker.js: ComfyUI extension that hooks onNodeCreated and
  onConfigure to sync speaker_N inputs in real time (max 8 speakers)
- Extend OmniVoiceGenerate with optional speakers (OMNIVOICE_SPEAKERS) input;
  when connected it routes each paragraph to the assigned speaker and
  concatenates the results — supports alternate_paragraphs and tagged_speakers modes
- Remove OmniVoiceMultiSpeakerGenerate (generation now lives in the existing
  Generate node)
- Refactor generator.py: extract _write_tmp_wav helper, add _tensors_to_audio

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 09:08:23 +02:00

28 lines
1.1 KiB
Python

from .nodes import OmniVoiceModelLoader, OmniVoiceGenerate, OmniVoiceEpubLoader, OmniVoiceVoicePreset, OmniVoiceMixVoices, OmniVoiceVoiceDesign, OmniVoiceSpeaker, OmniVoiceSpeakers
NODE_CLASS_MAPPINGS = {
"OmniVoiceModelLoader": OmniVoiceModelLoader,
"OmniVoiceGenerate": OmniVoiceGenerate,
"OmniVoiceEpubLoader": OmniVoiceEpubLoader,
"OmniVoiceVoicePreset": OmniVoiceVoicePreset,
"OmniVoiceMixVoices": OmniVoiceMixVoices,
"OmniVoiceVoiceDesign": OmniVoiceVoiceDesign,
"OmniVoiceSpeaker": OmniVoiceSpeaker,
"OmniVoiceSpeakers": OmniVoiceSpeakers,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"OmniVoiceModelLoader": "OmniVoice Model Loader",
"OmniVoiceGenerate": "OmniVoice Generate",
"OmniVoiceEpubLoader": "OmniVoice EPUB Loader",
"OmniVoiceVoicePreset": "OmniVoice Voice Preset",
"OmniVoiceMixVoices": "OmniVoice Mix Voices",
"OmniVoiceVoiceDesign": "OmniVoice Voice Design",
"OmniVoiceSpeaker": "OmniVoice Speaker",
"OmniVoiceSpeakers": "OmniVoice Speakers",
}
WEB_DIRECTORY = "./web"
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]