Nodes/comfyui-magic-hour/Magic Hour: Face Swap (Video)
ComfyUI Node

Magic Hour: Face Swap (Video)

Magic Hour: Face Swap (Video)

By magichourhq·Created about 17 hours ago·Updated about 16 hours ago· 0
Magic Hour: Face Swap (Video)
  • video
  • face_image
  • video
  • video_path
  • credits_charged
◄versiondefault►
◄start_seconds0.0►
◄end_seconds0.0►

Video face swap is the reason half the people searching for this pack are here. One photo of a face, one clip, and the face in the clip is now that face - for the whole duration, tracking through motion, at a quality that doesn't scream "masked and pasted".

The thing that trips everyone

The node hardcodes all-faces mode. Not a widget, not an option - the request always goes out in all-faces mode, which means every face in the frame gets swapped with your single face_image. Two people in the shot, both get your face. A crowd scene, you've made a crowd of clones.

That's a design choice on Magic Hour's side, and for the classic use case - one subject, one reference - it's exactly right. But it's the thing beginners don't expect, because locally you'd crop a face, swap it, and paste it back with a mask, so you'd naturally only touch the face you chose. Here there's no target selection. That's a real limitation, not something you can work around from inside the node.

If you need one specific face swapped out of several, your options are: pre-crop and reassemble the frames yourself, or go local.

How it works

Your VIDEO is written to a temp MP4, your face_image to a temp PNG, both uploaded. The job runs remotely, tracking the face through the clip and re-rendering it, then the finished MP4 is downloaded into ComfyUI/output/magic_hour/ and wrapped as a VIDEO.

version picks the engine generation: default, v2 or v1. Leaving it on default is the right move unless you have a reason - it lets Magic Hour route you to whatever they currently consider best. Reach for v1/v2 only to reproduce an older look or to dodge a regression in the current one. The node only sends a version when it isn't default, so the default path is genuinely "their choice, not yours".

Inputs and outputs

Required: video, face_image, version, start_seconds, end_seconds.

The window is the cost lever and it behaves consistently across this pack: end_seconds at 0 means to the end of the clip. If your source is long and you only need a beat, set both ends. Two minutes of footage is far more credits than twelve seconds of it, and the tracking quality doesn't improve with length.

Outputs: video (real VIDEO - Save Video, Video Combine, Preview all work), video_path (STRING with the saved file), 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. The only dependency is the magic-hour SDK (>=0.87.1) - nothing to put in models/, no insightface model zoo to fetch, no onnxruntime install. That's the whole appeal compared with ReActor-style local swaps, which are fiddly to set up and then quality-bound by a single inswapper model. ComfyUI Manager users can search "Magic Hour" if cloning isn't your thing.

export MAGIC_HOUR_API_KEY=your_key_here

before launching, or a bare api_key.txt in the pack folder. Key never in a widget: widget values live inside the workflow JSON.

Where it fails, and what to do

Reference image quality sets the ceiling. A small, soft, three-quarter-angle reference gives you a soft, drifting swap. Front-on, well-lit, decently large, neutral expression. This is the single highest-leverage thing you control.

Fast motion and occlusion. Hands crossing the face, whip pans, someone turning away - tracking loses the face and you get warping for a few frames. Test the hardest part of your clip first.

The long wait. Video jobs take tens of seconds to minutes; the node waits synchronously and your queue is blocked. Don't batch five of these and assume you can keep working.

401 / 402 / 422. Bad key, no credits or plan limit, unsupported settings. The node surfaces Magic Hour's own message rather than a generic exception, which is genuinely helpful - read it before assuming the node is broken.

The economics. Magic Hour's consumer web product has a reputation for thrifty free tiers - small swap allowances, watermarks, slow queues - and that reputation gets attached to the API by association. They're different surfaces: the API is metered per call with no watermark, and credits_charged tells you exactly what each run took. Judge it on that number, not on the web app.

And the standing warning, from the node's own description: only swap faces you have the right to use. It's the oldest rule in this corner of the hobby and it's the one that gets people's accounts deleted.

CategoryMagic Hour

Inputs (5)

NameTypeDefaultDescription
videoVIDEO—
face_imageIMAGE—
versionCOMBOdefault3 options: default, v2, v1
start_secondsFLOAT0.00–3600—
end_secondsFLOAT0.00–36000 = to the end of the video

Outputs (3)

NameTypeDescription
videoVIDEO—
video_pathSTRING—
credits_chargedINT—