EcoHash Dedicated TTS
EcoHash Dedicated TTS Won't Run Until You Fill In the Voice
- AUDIO
Here's the first thing you need to know about EcoHash Dedicated TTS, and it's the thing everyone trips over: voice looks like an optional text field and is not one. Leave it blank and the node refuses to make the call at all, before any network traffic, with "Choose or enter a voice ID supported by the selected TTS model."
That's an unusual design choice - most nodes would send the empty string and let the service decide. Here it's deliberate, and once you know why, the node becomes predictable. Voice IDs are model-specific. af_bella means something on a Kokoro-flavoured deployment and nothing at all on the next one. A blank field would silently get you whatever the host's default happens to be, which is a nasty way to discover you're generating a whole voiceover in the wrong voice.
The job it does
Text in, AUDIO out. It's the missing half of a video workflow - you've got a clip and no narration, or you want a talking head, and the head needs a voice track to drive it. In this ecosystem that chain is well-trodden: generate speech, then drive the mouth with an audio-driven avatar model like InfiniteTalk or a Wan flavour of the same. Video without audio is now the odd case, so the voice stage earns its node.
The honest framing from the audio side of the KB still applies, though. Open TTS closed most of the gap - Chatterbox at 0.5B genuinely competes with paid services for a cloned voice - but the two jobs where hosted still wins are best-in-class multi-language reliability and song generation. If you're renting an endpoint anyway, you're buying exactly that reliability, and paying per character for it.
What it sends
The request is a JSON POST to /audio/speech with model, input (your text), voice, speed, and response_format=wav. The reply must be a 16-bit PCM WAV file; the node parses it into ComfyUI's AUDIO structure with the sample rate the service sends back.
Read that constraint carefully, because it's the single most common reason a self-hosted TTS endpoint fails here. Plenty of inference servers hand back MP3, or float WAV, or a streamed chunked response. Any of those gets you "Speech API returned unsupported audio. Expected a 16-bit PCM WAV response". Not a bug in the node - a genuine incompatibility with what your deployment does, and the fix lives on the server side.
The inputs, then. model is the exact served ID, free text. text is multi-line and goes in as input verbatim, so paragraph breaks you type are part of the request. voice is a string: when the service advertises its voices, the selector offers them, otherwise you type a model-specific ID. Switching models either picks a declared voice for you or clears the field, which is a small kindness that prevents a very confusing failure. speed runs 0.5 to 2.0, default 1.0 - keep it there unless you're chasing a specific pacing, because pitch and timing both start misbehaving well before the extremes. And connection picks the saved endpoint, mandatory in practice.
Output is AUDIO - wire it to Preview Audio, Save Audio, or the audio input of whatever downstream node wants a driving track.
Install and configure
Manager: search EcoHash (comfyui-ecohash), install, restart, refresh. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/ecohash-ai/ComfyUI-EcoHash.git
cd ComfyUI-EcoHash
pip install -r requirements.txt
One dependency: requests. No model files, no torch changes, nothing that touches the rest of your install. Windows Portable users should install into the embedded interpreter with .\python_embeded\python.exe -m pip install -r .\ComfyUI\custom_nodes\ComfyUI-EcoHash\requirements.txt.
Key and endpoint live server-side, not in a widget: sidebar EcoHash → Connections → save the key → Add connection with a name and the full API URL including its prefix. Anything that isn't api.ecohash.com needs its own key; it will not inherit the global one.
Where it goes wrong
"Voice is blank or rejected." Refresh models, or type the exact voice ID the deployment serves. A voice from a different model family is not portable, and a voice list isn't guaranteed to be advertised at all - the pack's own troubleshooting says so.
Audio plays but sounds broken downstream. Check the sample rate the endpoint returned. The node trusts the WAV header; if the service lies about it, you get a pitch-shifted result that looks like a node bug and isn't.
Nothing regenerated. Same text, same voice, same inputs - ComfyUI served the cached audio and never called the API. Change the text.
It won't produce a specific person's voice. There's no cloning or reference-audio input here. That's a whole different pipeline, and no amount of tweaking speed gets you there.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| model | STRING | Exact model ID served by your dedicated endpoint; it need not appear in the public EcoHash catalog. | |
| text | STRING | — | |
| voice | STRING | Voice ID supported by the selected model | |
| speed | FLOAT | 1.000.5–2 | — |
| connectionopt | COMBO | 1 options: |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| AUDIO | AUDIO | — |