Nodes/Bjornulf_custom_nodes/๐Ÿ“โžœ๐Ÿ”Š TTS - Text to Speech
ComfyUI Node

๐Ÿ“โžœ๐Ÿ”Š TTS - Text to Speech

XTTS voice cloning in ComfyUI (it needs a separate backend server)

By justUmenยทCreated 2 years agoยทUpdated about a year agoยท 545
๐Ÿ“โžœ๐Ÿ”Š TTS - Text to Speech
  • connect_to_workflow
  • TTS_URL
  • TTS_LANGUAGE
  • TTS_SPEAKER
  • AUDIO
  • audio_path
  • audio_full_path
  • audio_duration
โ—„textโ€”โ–บ
โ—„languageEnglishโ–บ
โ—„speaker_wavdefaultโ–บ
โ—„autoplaytrueโ–บ
โ—„save_audiotrueโ–บ
โ—„overwritefalseโ–บ
โ—„seed0โ–บ

This node turns text into spoken audio using XTTS v2 - the voice-cloning model - so you can generate speech in any of 17 languages, in a voice you supply from a sample. The headline feature is that it clones: hand it a short .wav of a voice and it'll read your text in that voice, and it'll happily make an English voice sample speak Japanese or vice versa. Useful for narration, lip-sync pipelines (feed the audio to a talking-head model), or just an audible "workflow done" chime.

One thing to be crystal clear about before you get excited: this node is a frontend. It does not run the TTS model itself. It talks to a separate backend server - the author's Bjornulf_XTTS project - which you have to install and run alongside ComfyUI. Without that server running, this node can only replay audio it already generated.

How it works

When you run it, the node sends your text, language, and chosen voice sample to the XTTS server (by default at localhost:8020), gets back synthesized audio, and saves it under ComfyUI/Bjornulf_TTS/ in a folder path built from the language, the voice name, and the text. Here's the clever part: if you run the same node again with identical settings, it finds the already-generated file and just plays it back - no server call, no VRAM used. So once you've generated a line, you can turn the TTS server off (it eats ~3GB of VRAM) and the node still replays that audio. That's the intended way to run TTS alongside image generation without both fighting for VRAM.

The inputs and outputs that matter

  • text - the multiline text to speak.
  • language - one of 17 (English, French, Japanese, etc.). Note you don't need a matching-language voice sample; any voice can speak any language.
  • speaker_wav - which voice sample to use (default default). This points at a .wav in the speakers folder you set up (see install).
  • overwrite - off (default) reuses the cached file if it exists; on regenerates. Flip it on when you don't like a take and want a fresh one, then flip it back.
  • autoplay and save_audio - play inside the node on execution / write the file to disk.
  • seed, plus optional connect_to_workflow (a wildcard passthrough so you can pre-generate audio in a standalone workflow) and TTS_URL / TTS_LANGUAGE / TTS_SPEAKER inputs from the pack's TTS Configuration node.

Outputs: AUDIO (wire it into a Preview Audio node - the author says this node should always connect to one), plus audio_path, audio_full_path, and audio_duration for chaining into video/sync nodes like MuseTalk.

How to install it

ComfyUI Manager: search Bjornulf_custom_nodes, install, restart. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/justUmen/Bjornulf_custom_nodes
pip install -r Bjornulf_custom_nodes/requirements.txt

Then the extra steps this node specifically needs:

  1. Install and run the backend, Bjornulf_XTTS (github.com/justUmen/Bjornulf_XTTS). This is what actually synthesizes speech.
  2. Create a speakers link inside the node folder: ComfyUI/custom_nodes/Bjornulf_custom_nodes/speakers, pointing to wherever your voice samples (like default.wav) live.
  3. Test the server in a browser: http://localhost:8020/tts_stream?language=en&speaker_wav=default&text=Hello.

Common issues

The single biggest one: the node is Linux-first. The author states outright it's "never tested on Windows, only on Linux for now" - and confirmed the same thing publicly when releasing the pack. If you're on Windows, expect this node (and the video nodes) to be the rough edges.

After that, almost every failure is the backend. No audio and it tried to reach the server? The XTTS server isn't running, or isn't on port 8020, or the speakers link isn't set up so it can't find your .wav. Verify with the browser URL above before debugging the node. Remember the server wants ~3GB of VRAM, so if you're also generating images you'll likely want to generate the speech first (or use the pack's Pause node to stop the server before the heavy step). And if you're just replaying an existing line, you don't need the server up at all - that's the whole caching trick.

CategoryBjornulf

Inputs (11)

NameTypeDefaultDescription
textSTRINGโ€”
languageCOMBOEnglish17 options: Arabic, Czech, German, English, Spanish, French, +11
speaker_wavSTRINGdefaultโ€”
autoplayBOOLEANtrueโ€”
save_audioBOOLEANtrueโ€”
overwriteBOOLEANfalseโ€”
seedINT0โ€”
connect_to_workflowopt*โ€”
TTS_URLoptTTS_URLโ€”
TTS_LANGUAGEoptTTS_LANGUAGEโ€”
TTS_SPEAKERoptTTS_SPEAKERโ€”

Outputs (4)

NameTypeDescription
AUDIOAUDIOโ€”
audio_pathSTRINGโ€”
audio_full_pathSTRINGโ€”
audio_durationFLOATโ€”