Wan VACE - Local Video Editing
Changing one thing in a video without touching the rest (via cloud Wan VACE)
- video_file_path
- video_url
You've got a clip of a person walking past a wall, and you want the poster on that wall swapped for something else - with the person, the motion, and everything else untouched. That's local video editing, and WanVACEVideoEdit ("Wan VACE - Local Video Editing") is the cloud take on it: the Wan 2.1 VACE model, running on Alibaba's DashScope API, editing only the region you tell it to.
This is the fiddliest node in the ru4ls/ComfyUI_Wan pack, because unlike plain repainting it needs a mask to know where to edit. But it's also the one where the result feels like magic when it works. And it's worth noting what you're not doing: no 14B model grinding on your GPU for 15-40 minutes. It's all on their servers, billed per job.
How it works
VACE is Alibaba's Video-Aware Context Extension framework - the same tech that powers the open-source Wan 2.1 VACE you may have seen running locally, just hosted. You feed it a video plus a description of the edit, and the model re-generates only the masked area while preserving the rest of the scene and its motion. The cloud side handles the heavy lifting of tracking what the mask points at across frames.
The important inputs are the mask controls:
- mask_image_url - a URL to a mask image that marks the region to edit. White = edited, black = left alone. This is the core of a local edit.
- mask_type -
tracking(default) lets the model follow the masked object as it moves through the clip;fixedholds the mask in place. - mask_frame_id - which frame the mask image refers to (default 1). If your mask is drawn on frame 1 and the object moves, tracking needs to know that.
- expand_ratio and expand_mode - how much padding to give the masked area (0.05 default) and the shape it grows in (
hullpolygon,bbox, ororiginal). Crank expand_ratio if your edit's edges look cropped.
Everything else is familiar from the rest of the pack. prompt describes the edit ("replace the poster with a neon sign"), video_url is the source clip, and the optional ref_images_url takes a single reference image if you want the edit to match something specific. control_condition (posebodyface, posebody, depth, scribble) extracts motion/composition features from the input to keep the edit aligned with the original movement. size gives you output resolutions from 1280*720 down to square.
The big gotcha: URLs, not files
The input video_url and mask_image_url are URLs that Alibaba's servers fetch - they can't read your local files. You'll need the source video hosted somewhere publicly reachable (or served from a local endpoint). This trips up everyone on their first VACE run. Same story for any reference image.
Install and setup
Search ComfyUI_Wan in ComfyUI Manager, or:
cd ComfyUI/custom_nodes
git clone https://github.com/ru4ls/ComfyUI_Wan.git
pip install -r ComfyUI_Wan/requirements.txt
Then restart and configure the key - copy config/.env.template to config/.env in the pack folder and set DASHSCOPE_API_KEY (and DASHSCOPE_API_KEY_CHINA if you'll use the mainland China region). The pack's requirements are light: requests, Pillow, numpy, python-dotenv. Everything heavy is server-side, and it's paid per job - keep that in mind before you queue a batch of edits.
Outputs
You get two strings out: video_file_path (the mp4 downloaded to your output_dir, default ./videos) and video_url (the remote copy). To actually see the result in ComfyUI, feed video_file_path into a "Load Video (Path)" node from ComfyUI-VideoHelperSuite - the pack's README calls this out for every video node, and it's the step people forget.
A warning on expectations: mask tracking is where cloud VACE wobbles. If the object rotates a lot or leaves the frame, tracking can drift. When that happens, try fixed, or pad the mask with a bigger expand_ratio. The fix is almost always on the mask side, not the prompt.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | wan2.1-vace-plus | 1 options: wan2.1-vace-plus |
| prompt | STRING | Edit the video with the following description | — |
| video_url | STRING | URL of the input video | |
| region | COMBO | international | 2 options: international, mainland_china |
| ref_images_urlopt | STRING | Newline-separated URLs for reference images (only 1 image supported) | |
| mask_image_urlopt | STRING | URL of the mask image | |
| mask_frame_idopt | INT | 11–1000 | — |
| mask_video_urlopt | STRING | URL of the mask video | |
| control_conditionopt | COMBO | 5 options: , posebodyface, posebody, depth, scribble | |
| mask_typeopt | COMBO | tracking | 2 options: tracking, fixed |
| expand_ratioopt | FLOAT | 0.050–1 | — |
| expand_modeopt | COMBO | hull | 3 options: hull, bbox, original |
| sizeopt | COMBO | 1280*720 | 5 options: 1280*720, 720*1280, 960*960, 832*1088, 1088*832 |
| seedopt | INT | 00–2147483647 | — |
| prompt_extendopt | BOOLEAN | false | — |
| watermarkopt | BOOLEAN | false | — |
| output_diropt | STRING | ./videos | Directory where the generated video will be saved. Browse to select a custom directory. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| video_file_path | STRING | — |
| video_url | STRING | — |