Magic Hour: AI Voice Cloner
Point It at a Voice Clip, Then Make That Voice Say Anything
- audio
- audio
- audio_path
- credits_charged
Two inputs. A voice you already have as audio, and the words you want it to say. That's the entire node - no model dropdown, no pitch slider, no reference-quality setting to fiddle with. It's the shortest path from "here's a clip of how someone sounds" to "here's that voice reading my script."
The obvious use is dialogue: you've got a character voice, or a narrator whose timbre you like, and you need forty more lines. In a ComfyUI graph the payoff is chaining - audio out feeds Lip Sync or Talking Photo from the same pack, and now a still image and a reference clip become a talking clip.
How it works
Like everything in this pack, it's a network call, not a local model. The AUDIO you wire in gets decoded and written to a temp 16-bit PCM WAV, uploaded as the voice reference, and sent to Magic Hour's ai_voice_cloner endpoint along with your text. When the job finishes, the node downloads the result into ComfyUI/output/magic_hour/, decodes it, and returns it as a ComfyUI AUDIO - a waveform tensor plus sample rate, ready for any node that takes audio.
So: no VRAM, no weights, credits per call. If you want the local version of this, the KB's audio generation essay covers it - Chatterbox and F5-TTS both do zero-shot cloning, and cloning is precisely the gap local models closed in 2025–26. The honest reason to use this node anyway is that you don't want to install a TTS stack, or you want the voice to match the rest of a Magic Hour pipeline. The honest reason to reach for local instead is privacy: a cloned voice is about as sensitive as input gets, and here it's uploaded. The pack is first-party (Magic Hour's own repo, Apache-2.0), which is the version of the API-node pattern you can install without reading every line.
The inputs
audio - the reference clip, as a ComfyUI AUDIO. In practice that's Load Audio, or the audio output of a local TTS node, or the audio output of the Voice Generator next door if you want to re-clone into a different register. Note there's no length widget here: whatever you wire in is uploaded whole. Give it clean, single-speaker, close-mic'd speech - a clip with music under it is asking for a voice that sounds like the music.
prompt - the text to speak. It's the only other field, and there's no SSML or emphasis control anywhere on the node, so don't count on pause tags. Write it the way you want it read.
Outputs
audio is the generated speech as a ComfyUI AUDIO - wire it to a save/preview audio node, or straight into Magic Hour: Lip Sync / Magic Hour: Talking Photo. audio_path is the downloaded file's path as a string, handy if audio decoding fails on your machine. credits_charged is an INT for what that call cost.
Install
ComfyUI Manager → search "Magic Hour". Or:
cd ComfyUI/custom_nodes
git clone https://github.com/magichourhq/comfyui-magic-hour
pip install -r comfyui-magic-hour/requirements.txt
One dependency, the magic-hour SDK; Python 3.10+; restart ComfyUI. Key before launch:
export MAGIC_HOUR_API_KEY=...
# or: echo 'YOUR_KEY' > ComfyUI/custom_nodes/comfyui-magic-hour/api_key.txt
The key is intentionally not a widget - node values are saved into the workflow JSON, so a key on the node leaks with every share.
Where people get burned
The node isn't in the menu. Voice nodes are opt-out: if MAGIC_HOUR_DISABLE_VOICE_NODES=1 is set in the environment ComfyUI started with, both voice nodes are skipped at import. Check your launch script or your service unit before you start reinstalling things.
The audio output won't preview but audio_path is fine. The pack decodes the downloaded file with PyAV, which ships with ComfyUI rather than with this pack - so a broken or trimmed ComfyUI install can decode-fail on a job that actually succeeded and got paid for. The file is already saved; grab the path and move on.
401 / 402. The pack turns API errors into readable text. 401 = key wrong or deleted. 402 = out of credits or the job needs a paid plan. Read the node's error rather than assuming the node is broken.
Your queue freezes during the call. The node waits for the job, and the job is a network round trip. That's normal.
Consent, and mean it. The author's own node description says "only use voices you have the right to use," and that's not boilerplate. Voice cloning is where the hobbyist version of this story goes badly - someone's voice attached to words they never said. Get permission, keep it to people who gave it.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| audio | AUDIO | — | |
| prompt | STRING | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| audio | AUDIO | — |
| audio_path | STRING | — |
| credits_charged | INT | — |