arkennemasis fal · Kling v3 Pro Motion Control · $0.168/s
Your photo, someone else's dance
- image
- video
- video
- video_path
- info
Motion transfer: you give it a character image and a reference video, and the character performs the reference's movement. It's the workflow behind every "my illustration is dancing" clip, and it's running through fal's Kling video endpoint as one node in comfyui-arkennemasis.
You cannot run this locally, and that isn't a hardware problem - Kling is closed. The community's read on it is that Kling set the bar for motion control and stayed the thing everything else gets compared to, which is why "MiniMax H3 can do motion control like Kling" was a +247 thread when it landed. That comparison cuts both ways, though: other labs' open weights have closed the gap enough that people argue about it now. What this node sells you is the version nobody argues about, priced per second.
Inputs
- image - the character. The tooltip's guidance is unusually specific and it's there because the model fails without it: clear body proportions, no occlusion, and the character occupying more than 5% of the frame.
- video - the motion reference. Realistic-style character, whole body or upper body visible, head included, nothing in front of it. And the duration limit depends on
character_orientation: 10 seconds max forimage, 30 seconds max forvideo. - character_orientation - required,
imageorvideo.videomatches the reference video's orientation and is the better choice for complex movement (and allows up to 30s).imagematches the reference image, which is better when you want the camera to move as shot (and caps at 10s). - prompt - optional. Empty leaves it out.
- keep_original_sound - default
true, keeps the reference clip's audio in the output. Turn it off if the reference is a TikTok with a soundtrack you don't own. - elements - a JSON field for facial-consistency binding: one element, referenced in the prompt as
@Element1, and only supported whencharacter_orientationisvideo. Advanced; leave it empty until the basic run works. - Plus max_cost_usd, reuse_identical_run, extra_json, max_concurrent.
What it costs
$0.168 per second of the reference video, so the length of your clip is the bill: 5s is $0.84, 10s is $1.68, 30s is $5.04. That's why the practical habit is to trim the reference first - you're not paying for the seconds you don't use. max_cost_usd (default $20) checks the estimate before uploading anything, so an accidental 30-second reference gets refused rather than quietly charged.
Mechanically, this node uploads the image and the video to fal's CDN (free), makes one billed call, polls while the node shows status, and downloads the result to output/fal/fal-ai_kling-video_v3_pro_motion-control/. One detail worth knowing: a video straight off disk with no trim or crop is uploaded as-is, but a trimmed or cropped VIDEO is re-encoded to MP4 by ComfyUI's own encoder first.
Outputs
video (a native ComfyUI VIDEO you can wire into a save node or a video-processing node), video_path as a string, and info - JSON with the request id, the cost estimate, the saved files and fal's full answer. Note this node returns no image outputs and no seed: video billing is by duration and there's nothing to re-roll.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
or install comfyui-arkennemasis from ComfyUI Manager. Restart, then add the key to the .env in the folder with run_nvidia_gpu.bat:
FAL_KEY=your-key-from-fal.ai/dashboard/keys
No models, no CUDA, nothing installed into your Python environment - the fal half of this pack is standard library only, and the key never appears in workflow JSON because there's no key widget to type it into.
When it fails
Bad output is nearly always a bad reference. If your character image has someone leaning on a counter, or a phone in front of their chest, wipe the result and go again with a cleaner one - the 5%-of-frame and no-occlusion hints exist because the model silently does something silly otherwise. Same on the video side: a shaky handheld reference gives you shaky motion.
If you spliced together two clips, mind the limits - over 10 seconds needs character_orientation on video, and over 30 gets rejected. If elements is set but the orientation is image, expect a refusal; that binding only works one way. And remember these runs take a while: polling has no fixed timeout by design, the node shows elapsed time, Cancel stops the job on fal as well as locally, and if ComfyUI restarts mid-generation, the free Recover Result node retrieves the finished clip by id from output/fal/_requests.jsonl instead of you paying $1.68 twice.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | Empty leaves it out. | |
| image | IMAGE | Reference image URL. The characters, backgrounds, and other elements in the generated video are based on this reference image. Characters should have clear body proportions, avoid occlusion, and occupy more than 5% of the image area. | |
| video | VIDEO | Reference video URL. The character actions in the generated video will be consistent with this reference video. Should contain a realistic style character with entire body or upper body visible, including head, without obstruction. Duration limit depends on character_orientation: 10s max for 'image', 30s max for 'video'. | |
| keep_original_sound | BOOLEAN | true | Whether to keep the original sound from the reference video. |
| character_orientation | COMBO | image | Controls whether the output character's orientation matches the reference image or video. 'video': orientation matches reference video - better for complex motions (max 30s). 'image': orientation matches reference image - better for following camera movements (max 10s). |
| elements | STRING | null | Optional element for facial consistency binding. Upload a facial element to enhance identity preservation in the generated video. Only 1 element is supported. Reference in prompt as @Element1. Element binding is only supported when character_orientation is 'video'. JSON. Empty leaves it out. |
| max_cost_usdopt | FLOAT | 20.00–100000 | Safety cap. If the estimated cost of this run is above this many US dollars the node stops BEFORE sending anything to fal. 0 = no cap. |
| reuse_identical_runopt | BOOLEAN | true | If these exact inputs (the settings AND the same pictures/clips/audio) were already paid for and the files are still in output/fal, return them instead of paying again - also after a ComfyUI restart. Turn off for a fresh take with the same settings. |
| extra_jsonopt | STRING | Advanced: a JSON object merged into the request last, for any fal field this node has no box for. Example: {"seed": 7}. Leave empty normally. | |
| max_concurrentopt | INT | 11–32 | How many paid fal calls may run at the same time in one run, across every fal node. 1 (default) = one after another. This node starts its paid part only while fewer than this many fal calls are running. Once any fal node fails, the ones still waiting are not started, so nothing more is billed. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| video | VIDEO | — |
| video_path | STRING | — |
| info | STRING | JSON: request id, cost estimate, saved files and fal's full answer. |