Wan 2.2 VACE Fun 14b Video-to-Video (fal)
Drive a new video from an old one
- video
- ref_images
- first_frame
- last_frame
- video_url
- frames_zip_url
VACE is the closest thing open video has to ControlNet: instead of prompting a clip out of nothing, you feed it an existing video, VACE extracts the structure - a depth map or a pose track, frame by frame - and regenerates new footage that follows that motion while your prompt supplies the look. It's how you keep exact choreography from a reference clip and restyle everything on top of it. This node runs the Wan 2.2 VACE Fun 14b variant on fal, which matters because VACE on the 14B Wan model is heavy to run locally; handing it to fal is a reasonable call.
The reason to reach for this over a plain text-to-video model is control. You already have the motion - a dance, a camera move, a specific action - and you want a different subject or style performing it. That's exactly the job VACE was built for.
What it actually does
Your driving video and prompt go to fal.ai, fal runs Wan 2.2 VACE Fun 14b, and you get new footage back that inherits the input's structure. No VRAM, no downloads, billed per generation. The task picks which control signal it pulls from your video, and preprocess handles the extraction for you so you don't have to build a depth/pose pipeline yourself.
The inputs that matter
This node exposes a lot of knobs - most are advanced defaults you can ignore. The handful that actually shape the result:
- video (required): your driving clip - the motion the output will follow.
- prompt (required): the look you want painted onto that motion.
- task (
depthorpose): which structure to extract.posefor human/character motion,depthfor general scene and camera structure. - preprocess (default on): let it auto-extract the control signal from your video. Leave on unless you're feeding a pre-made control video.
- ref_images (optional): reference image(s) to anchor the subject's appearance.
- resolution (
480p/580p/720p) and num_frames: quality/length versus cost.
Everything else - sampler, guidance_scale, shift, the interpolation and downsample options - has sensible defaults; don't touch them until you have a specific reason. The outputs are two STRING values: video_url (the result) and frames_zip_url (a ZIP of frames, if you enabled return_frames_zip). Feed video_url into Fal Save Media from URL to download it, or Load Video from URL to bring frames back into the graph.
Installing it
ComfyUI Manager → search ComfyUI-fal-API → install → restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/gokayfem/ComfyUI-fal-API.git
cd ComfyUI-fal-API
pip install -r requirements.txt
Restart ComfyUI. No model in models/; you need fal-client and a fal API key in config.ini under [API], or FAL_KEY in the environment.
Where people get burned
The number-one mistake is task mismatch: pose on a clip with no clear human motion gives you garbage, and depth on a tight character dance throws away the pose detail you actually cared about. Pick the signal that matches your driving video. Second, if you feed a pre-made control video, turn preprocess off - otherwise it tries to extract structure from an already-extracted map and you get mush.
The node's giant parameter list is the other trap; it looks like you're supposed to tune all of it, and you're not. Change task, resolution, and num_frames, leave the sampler stack alone, and you'll get clean results. As always, no FAL_KEY means every run fails, and errors come through as fal's real text.
Inputs (31)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | — | |
| video | VIDEO | — | |
| taskopt | COMBO | depth | 2 options: depth, pose |
| preprocessopt | BOOLEAN | true | — |
| ref_imagesopt | IMAGE | — | |
| first_frameopt | IMAGE | — | |
| last_frameopt | IMAGE | — | |
| negative_promptopt | STRING | — | |
| seedopt | INT | 240–2147483647 | — |
| resolutionopt | COMBO | 480p | 3 options: 480p, 580p, 720p |
| aspect_ratioopt | COMBO | auto | 4 options: auto, 16:9, 9:16, 1:1 |
| num_inference_stepsopt | INT | 30 | — |
| guidance_scaleopt | FLOAT | 5.000–10 | — |
| sampleropt | COMBO | unipc | 3 options: unipc, dpm++, euler |
| match_input_num_framesopt | BOOLEAN | false | — |
| num_framesopt | INT | 8117–241 | — |
| match_input_frames_per_secondopt | BOOLEAN | false | — |
| frames_per_secondopt | INT | 165–30 | — |
| shiftopt | INT | 5 | — |
| accelerationopt | COMBO | regular | 3 options: none, low, regular |
| video_qualityopt | COMBO | high | 3 options: low, medium, high |
| video_write_modeopt | COMBO | balanced | 3 options: balanced, fast, small |
| return_frames_zipopt | BOOLEAN | false | — |
| num_interpolated_framesopt | INT | 00–5 | — |
| temporal_downsample_factoropt | INT | 00–5 | — |
| enable_auto_downsampleopt | BOOLEAN | false | — |
| auto_downsample_min_fpsopt | INT | 151–60 | — |
| interpolator_modelopt | COMBO | film | 2 options: rife, film |
| enable_safety_checkeropt | BOOLEAN | false | — |
| enable_output_safety_checkeropt | BOOLEAN | false | — |
| variationsopt | INT | 11–10 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video_url | STRING | — |
| frames_zip_url | STRING | — |