Wan2.2 Animate: Automatic Character Replacement
Upload a video and a character image. Automatically replace the character in the video using the Wan2.2 Animate model.
Inside the workflow
A read-only preview of the source template. Open it in Cloud to explore the nodes and make changes.
Loading the graph
Open full-size workflow preview- Output
- Video
- Author
- Purz
Call this model from your code
The request below uses the same prepared graph and settings as the Playground. Each submission can start a paid run; do not automatically retry a submission whose outcome is unknown.
What you need
- Runs on
- Comfy Cloud
- Key
- COMFY_API_KEY
- Your files
- Uploaded by the code from their urls
Needs a paid Cloud plan and credits.
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"10": {
"class_type": "LoadImage",
"inputs": {
"image": "UPLOADED_image_FILENAME"
},
"_meta": {
"title": "Reference Image"
}
},
"19": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"344:232:15",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"159": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1280
},
"_meta": {
"title": "Width"
}
},
"160": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 720
},
"_meta": {
"title": "Height"
}
},
"301": {
"class_type": "VHS_LoadVideo",
"inputs": {
"custom_height": 0,
"custom_width": 0,
"force_rate": 0,
"format": "AnimateDiff",
"frame_load_cap": 0,
"select_every_nth": 1,
"skip_first_frames": 0,
"video": "UPLOADED_video_FILENAME"
},
"_meta": {
"title": "Input Video"
}
},
"314": {
"class_type": "VHS_VideoInfo",
"inputs": {
"video_info": [
"301",
3
]
},
"_meta": {
"title": "Video Info 🎥🅥🅗🅢"
}
},
"344:1": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"344:2",
0
],
"text": "色调艳丽,过曝,静态,细节模糊不清,字幕,风格,作品,画作,画面,静止,整体发灰,最差质量,低质量,JPEG压缩残留,丑陋的,残缺的,多余的手指,画得不好的手部,画得不好的脸部,畸形的,毁容的,形态畸形的肢体,手指融合,静止不动的画面,杂乱的背景,三条腿,背景人很多,倒着走"
},
"_meta": {
"title": "CLIP Text Encode (Negative Prompt)"
}
},
"344:18": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "lightx2v_I2V_14B_480p_cfg_step_distill_rank64_bf16.safetensors",
"model": [
"344:20",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"344:2": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "umt5_xxl_fp8_e4m3fn_scaled.safetensors",
"device": "default",
"type": "wan"
},
"_meta": {
"title": "Load CLIP"
}
},
"344:20": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "Wan2_2-Animate-14B_fp8_e4m3fn_scaled_KJ.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"344:21": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"344:2",
0
],
"text": "The post-apocalyptic elf warrior from the reference image dances alone in an empty night parking lot, taking over the dancer's exact moves. He bounces his shoulders, steps side to side in a relaxed groove, swings his arms low and wide, lifts a knee playfully and turns halfway on the spot before facing forward again. His tattered olive-green cloak flares and settles with each step, the alchemical vials on his belt sway and glint, and the cyan vents of the respirator around his neck glow softly. His blonde hair moves with the rhythm and his blue eyes stay on the camera. Warm amber streetlights light the cracked asphalt, parked white cars and autumn trees in the background, while distant red taillights glow through the dark. Smooth natural motion, consistent character, cinematic night photography."
},
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"344:232:15": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"314",
0
],
"images": [
"344:232:230",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"344:232:230": {
"class_type": "ImageFromBatch",
"inputs": {
"batch_index": [
"344:232:62",
4
],
"image": [
"344:232:58",
0
],
"length": 4096
},
"_meta": {
"title": "Get Image from Batch"
}
},
"344:232:57": {
"class_type": "TrimVideoLatent",
"inputs": {
"samples": [
"344:232:63",
0
],
"trim_amount": [
"344:232:62",
3
]
},
"_meta": {
"title": "Trim Video Latent"
}
},
"344:232:58": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"344:232:57",
0
],
"vae": [
"344:3",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"344:232:62": {
"class_type": "WanAnimateToVideo",
"inputs": {
"background_video": [
"344:332",
0
],
"batch_size": 1,
"character_mask": [
"344:325",
0
],
"clip_vision_output": [
"344:9",
0
],
"continue_motion_max_frames": 5,
"face_video": [
"344:334",
1
],
"height": [
"160",
0
],
"length": [
"301",
1
],
"negative": [
"344:1",
0
],
"pose_video": [
"344:335",
0
],
"positive": [
"344:21",
0
],
"reference_image": [
"344:342",
0
],
"vae": [
"344:3",
0
],
"video_frame_offset": 0,
"width": [
"159",
0
]
},
"_meta": {
"title": "WanAnimateToVideo"
}
},
"344:232:63": {
"class_type": "KSampler",
"inputs": {
"cfg": 1,
"denoise": 1,
"latent_image": [
"344:232:62",
2
],
"model": [
"344:60",
0
],
"negative": [
"344:232:62",
1
],
"positive": [
"344:232:62",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seed": [
"344:279",
0
],
"steps": 6
},
"_meta": {
"title": "KSampler"
}
},
"344:279": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 281253459907758
},
"_meta": {
"title": "Seed"
}
},
"344:3": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "wan_2.1_vae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"344:324": {
"class_type": "DownloadAndLoadSAM2Model",
"inputs": {
"device": "cuda",
"model": "sam2.1_hiera_base_plus.safetensors",
"precision": "fp16",
"segmentor": "video"
},
"_meta": {
"title": "(Down)Load SAM2Model"
}
},
"344:325": {
"class_type": "BlockifyMask",
"inputs": {
"block_size": 32,
"device": "cpu",
"masks": [
"344:327",
0
]
},
"_meta": {
"title": "Blockify Mask"
}
},
"344:326": {
"class_type": "Sam2Segmentation",
"inputs": {
"bboxes": [
"344:334",
3
],
"image": [
"344:338",
0
],
"individual_objects": False,
"keep_model_loaded": False,
"sam2_model": [
"344:324",
0
]
},
"_meta": {
"title": "Sam2Segmentation"
}
},
"344:327": {
"class_type": "GrowMaskWithBlur",
"inputs": {
"blur_radius": 0,
"decay_factor": 1,
"expand": 10,
"fill_holes": False,
"flip_input": False,
"incremental_expandrate": 0,
"lerp_alpha": 1,
"mask": [
"344:326",
0
],
"tapered_corners": True
},
"_meta": {
"title": "Grow Mask With Blur"
}
},
"344:328": {
"class_type": "OnnxDetectionModelLoader",
"inputs": {
"onnx_device": "CUDAExecutionProvider",
"vitpose_model": "vitpose-l-wholebody.onnx",
"yolo_model": "yolov10m.onnx"
},
"_meta": {
"title": "ONNX Detection Model Loader"
}
},
"344:329": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"344:333",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"344:330": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"344:340",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"344:331": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/ComfyUI",
"format": "auto",
"format.codec": "auto",
"video": [
"344:339",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"344:332": {
"class_type": "DrawMaskOnImage",
"inputs": {
"color": "0, 0, 0",
"device": "cpu",
"image": [
"344:338",
0
],
"mask": [
"344:325",
0
]
},
"_meta": {
"title": "Draw Mask On Image"
}
},
"344:333": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"314",
0
],
"images": [
"344:334",
1
]
},
"_meta": {
"title": "Create Video"
}
},
"344:334": {
"class_type": "PoseAndFaceDetection",
"inputs": {
"face_padding": 0,
"height": [
"344:348",
1
],
"images": [
"344:338",
0
],
"model": [
"344:328",
0
],
"width": [
"344:348",
0
]
},
"_meta": {
"title": "Pose and Face Detection"
}
},
"344:335": {
"class_type": "DrawViTPose",
"inputs": {
"body_stick_width": -1,
"draw_head": True,
"hand_stick_width": -1,
"height": [
"344:348",
1
],
"pose_data": [
"344:334",
0
],
"retarget_padding": 16,
"width": [
"344:348",
0
]
},
"_meta": {
"title": "Draw ViT Pose"
}
},
"344:338": {
"class_type": "ImageScale",
"inputs": {
"crop": "center",
"height": [
"160",
0
],
"image": [
"301",
0
],
"upscale_method": "lanczos",
"width": [
"159",
0
]
},
"_meta": {
"title": "Resize Input Video"
}
},
"344:339": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"314",
0
],
"images": [
"344:332",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"344:340": {
"class_type": "CreateVideo",
"inputs": {
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"314",
0
],
"images": [
"344:335",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"344:342": {
"class_type": "ImageScale",
"inputs": {
"crop": "center",
"height": [
"160",
0
],
"image": [
"10",
0
],
"upscale_method": "lanczos",
"width": [
"159",
0
]
},
"_meta": {
"title": "Resize Reference Image"
}
},
"344:348": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"344:338",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"344:4": {
"class_type": "CLIPVisionLoader",
"inputs": {
"clip_name": "clip_vision_h.safetensors"
},
"_meta": {
"title": "Load CLIP Vision"
}
},
"344:60": {
"class_type": "ModelSamplingSD3",
"inputs": {
"model": [
"344:99",
0
],
"shift": 8
},
"_meta": {
"title": "ModelSamplingSD3"
}
},
"344:9": {
"class_type": "CLIPVisionEncode",
"inputs": {
"clip_vision": [
"344:4",
0
],
"crop": "none",
"image": [
"344:342",
0
]
},
"_meta": {
"title": "CLIP Vision Encode"
}
},
"344:99": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "WanAnimate_relight_lora_fp16.safetensors",
"model": [
"344:18",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
}
})
workflow.set_input("10", "image", client.assets.from_url("https://comfy.org/catalog-media/c15207cf-eea0-4265-afa1-1f184889d1bb/8837ea56-961e-45d2-9f12-9a1e6671d461"))
workflow.set_input("301", "video", client.assets.from_url("https://comfy.org/catalog-media/75887865-03c0-4c13-ac9d-3ba726ac9737/d7153c54-caab-422e-8ed5-dd3349ee5243"))
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)
for output in job.get_outputs("19"):
output.to_file(output.name)Try an example
About this workflow
The 'Wan2.2 Animate: Automatic Character Replacement' workflow is designed to seamlessly replace a character in a video with a new character from an uploaded image. This is achieved using the Wan2.2 Animate model, which specializes in character animation and replacement. The workflow begins by loading your video and character image. It then processes these inputs through a series of nodes, including the ComfyUI-WanAnimatePreprocess for initial setup and the ComfyUI-segment-anything-2 for precise segmentation. This ensures that the character replacement is accurate and visually coherent.
Technically, the workflow leverages a combination of video processing nodes such as VHS_LoadVideo and VHS_VideoInfo to extract and manage video data. The b396d3e6-70cc-4a91-81db-6e0399a4edb6 node is crucial for handling complex data transformations required for character animation. By using these nodes in conjunction with the Wan2.2 Animate model, users can achieve high-quality character replacements that are both stable and realistic, especially when the reference image is a clear depiction of a human subject.
Questions & answers
Images of human subjects with clear faces and body outlines produce the most stable and convincing results.
While the workflow is optimized for human subjects, it may work with non-human characters, though results can vary.
The workflow supports standard video formats, but ensure your video is compatible with the VHS_LoadVideo node.
Processing time varies based on video length and complexity, but typically it completes within a few minutes for short clips.