Nodes/ComfyUI CoolB Nodes/CB Save Speaker ⚡️
ComfyUI Node

CB Save Speaker ⚡️

File the clip and the transcript together, once

By CoolBreeze164·Created 30 days ago·Updated 22 days ago· 2
CB Save Speaker ⚡️
  • ref_audio
    ◄ref_text►
    ◄speaker_namespeaker►
    ◄audio_formatmp3►

    What it does, and why "with transcript" is the whole feature

    Voice cloning wants a reference clip and, for most engines, the words spoken in it. CB Save Speaker writes both out as one named unit: an audio file and a JSON sidecar holding the transcript, so that later - in any workflow, from any project - you pick a name and get the pair back. CB Load Speaker is the other half.

    The alternative is what most people do: a folder of ref_1.wav, ref_2.wav, plus a note somewhere about which line was in which. This is that, done properly and about four seconds faster.

    How it works

    You give it audio, text, a name and a format. It sanitises the name - the Windows-hostile set < > : " / \ | ? * becomes underscores, control characters go, leading/trailing dots and spaces are trimmed, and it's capped at 150 characters - and then writes two files into models/SPEAKERS:

    • alice.mp3 (or .wav), and
    • alice.json with speaker_name, ref_text, audio_file, audio_format, sample_rate and a created_utc timestamp.

    The JSON is written to a .tmp file and then os.replaced into position, so a crash mid-run doesn't leave you a half-written sidecar that Load Speaker would then choke on.

    Audio encoding is where the code actually gets interesting, because it's clearly been bitten before. For MP3 it tries torchaudio with an explicit format="mp3", then torchaudio without the kwarg, then PyAV directly. If all of that fails - a torchaudio build without an MP3 backend and no PyAV - it writes a WAV instead and notes it once in the console: it prints [Speaker Pack] MP3 encoding failed; saved WAV fallback in the console. For WAV it does torchaudio then a pure-Python wave writer. Either way the file is staged as .saving.<ext> first so a failed encode never leaves a truncated file in place.

    Because the file name is the speaker name, saving alice again overwrites both files. It'll also clean up a stale alice.wav if you re-save as MP3, so you don't end up with two copies of the same voice and a coin-flip over which one Load Speaker grabs.

    Inputs and outputs

    | | | |---|---| | ref_audio (AUDIO, required) | the reference clip, from an audio loader or your TTS output | | ref_text (multiline STRING) | the transcript - whatever was actually said in that clip | | speaker_name (STRING, default speaker) | the library name, and the filename | | audio_format (enum: mp3, wav) | default mp3; pick wav if you want lossless for cloning |

    No outputs. It's an output node, so it runs on every queue whether or not anything downstream wants it.

    Installing it

    Manager → Custom Nodes Manager → search ComfyUI CoolB Nodes → Install → restart. Manual:

    cd ComfyUI/custom_nodes
    git clone https://github.com/CoolBreeze164/ComfyUI-CoolB-Nodes
    

    Set nothing up in advance: the folder is created on first save. Want it elsewhere? Change speakers_folder in the pack's config.json - the README's models/SPEAKERS is just the default.

    Common issues

    You asked for MP3 and got a WAV. That's the fallback path described above. It only announces itself in the console, so if format matters (and it usually doesn't - WAV is fine, just bigger), watch the log around the save.

    Re-saving didn't create a new entry. Correct - same name, same files, overwritten. Version your voices with the name itself (alice_soft, alice_read) rather than expecting the node to number them.

    Two differently-named speakers collided. Sanitisation strips characters, so alice/v2 and alice:v2 both become alice_v2 and the second save wins. Keep names to letters, numbers, underscores and dashes.

    Nothing shows up in Load Speaker. The audio and the JSON both have to land. If the save threw partway, check the folder rather than the dropdown - and remember the combo list is a snapshot from when ComfyUI read the schema, so restart or refresh before you conclude the save failed.

    Emptiness at the edges. An empty transcript is allowed and saved as an empty ref_text; that's fine for engines that ignore it, less fine for the ones that use it. And a reference clip that's too short or noisy will produce a bad clone no matter how tidy the sidecar is - come back with five to ten clean seconds.

    CategoryCoolB Nodes ⚡️

    Inputs (4)

    NameTypeDefaultDescription
    ref_audioAUDIO—
    ref_textSTRING—
    speaker_nameSTRINGspeaker—
    audio_formatCOMBOmp32 options: mp3, wav

    Outputs (0)

    No outputs