Nodes/comfyui-magic-hour/Magic Hour: Talking Photo
ComfyUI Node

Magic Hour: Talking Photo

Magic Hour: Talking Photo

By magichourhq·Created about 17 hours ago·Updated about 16 hours ago· 0
Magic Hour: Talking Photo
  • image
  • audio
  • video
  • video_path
  • credits_charged
◄generation_moderealistic►
◄start_seconds0.0►
◄end_seconds0.0►
◄prompt►

This is the example the pack's own README leads with, and it's the one people actually want: photo of a person, audio of them talking, video of them talking. It's the cheapest convincing "avatar" result in the whole node set, because you don't need footage - you need one decent portrait.

The two modes, and why the prompt field is a trap

generation_mode is realistic (default) or prompted, and they're not a quality setting. realistic drives the head from the audio alone: mouth shapes, small head motion, blinks. prompted additionally takes your prompt text to steer expression and performance.

Here's the part that wastes people's time: prompt is only used in prompted mode. Type a beautiful description of the performance you want, leave generation_mode on realistic, and it goes nowhere. The field is still sitting there looking active in the node UI - the tooltip is the only thing telling you it does nothing. The node won't warn you.

So: realistic for a straight read, prompted when the delivery matters ("she's laughing mid-sentence", "he's reading a serious announcement"). The prompt shapes performance, not appearance - the photo already decided what the person looks like.

The 60-second ceiling

The pack caps audio at 60 seconds and uses min(clip length, 60) as the available length. Leave end_seconds at 0 and you get the whole thing up to a minute; anything longer is truncated, not compressed. Long scripts are made in segments and stitched, or you move to a different tool.

The tooltip on end_seconds says this plainly - 0 = use the whole audio (max 60s window) - and it's the single most-missed constraint in the pack.

How it works

The image becomes a temp PNG, the AUDIO becomes a temp 16-bit WAV, both upload. The job runs remotely, watching only for the audio window you specified, and the resulting MP4 is downloaded into ComfyUI/output/magic_hour/ and wrapped as a VIDEO.

Frame-zero rule applies: only the first image of a batch is used. Two portraits into one node gives you one talking portrait.

Inputs and outputs

| field | what it is | | --- | --- | | image (required) | the portrait. Front-on, mouth fully visible, even lighting. Not a profile, not a hand-over-mouth selfie | | audio (required) | the speech. Clean, no music bed | | generation_mode | realistic or prompted | | start_seconds / end_seconds | the audio window; end_seconds 0 means to the end of the clip, capped at 60s | | prompt | performance direction - prompted mode only |

Outputs: video (a proper VIDEO, wire to Save Video), video_path (STRING), credits_charged (INT).

Install

cd ComfyUI/custom_nodes
git clone https://github.com/magichourhq/comfyui-magic-hour
pip install -r comfyui-magic-hour/requirements.txt

Restart ComfyUI, then look under Magic Hour. Dependency: magic-hour>=0.87.1, nothing else - no InfiniteTalk weights, no Wan, no MultiTalk LoRA to fetch. That's the actual argument for this node: the local equivalent is a multi-pack install with a transformers dependency fight at the end of it, and this is one pip line. ComfyUI Manager users can search "Magic Hour".

export MAGIC_HOUR_API_KEY=your_key_here

before launching, or the bare key in comfyui-magic-hour/api_key.txt. Not a widget, because widget values are stored inside the workflow JSON.

What goes wrong

The mouth moves, the face doesn't. Audio-only driving produces convincing lips and slightly uncanny stillness. That's realistic mode being realistic. If you want life in the eyes and shoulders, prompted mode and a prompt about expression helps, and the local InfiniteTalk/MultiTalk route helps more.

Teeth. Always teeth. Frame through the result before you publish; the two worst frames are usually a hard consonant.

Audio longer than 60s, half a video back. Covered above, and it's the number one report.

Prompt ignored. Check generation_mode. Again.

Queue blocked for minutes. Video job, synchronous wait.

A face going to a third party. For your own, fine. For a colleague or a client, get the yes in writing first.

The workflow pattern that works: generate the voice locally with a TTS model (free, fast, private), feed both into this node, and only pay for the pixels. That's also one of the few genuinely sensible hybrid pipelines in this pack - local for what's cheap, hosted for what isn't.

CategoryMagic Hour

Inputs (6)

NameTypeDefaultDescription
imageIMAGE—
audioAUDIO—
generation_modeCOMBOrealistic2 options: realistic, prompted
start_secondsFLOAT0.00–3600—
end_secondsFLOAT0.00–36000 = use the whole audio (max 60s window)
promptSTRINGOnly used in 'prompted' mode

Outputs (3)

NameTypeDescription
videoVIDEO—
video_pathSTRING—
credits_chargedINT—