WanVideo Looper
Long Wan 2.2 video without the hand-stitching
- model_high
- model_low
- clip
- vae
- start_image
- positive_prompts
- clip_vision
- model_clip_sequence
- color_match_ref
- images
- last_frame
Wan 2.2 has a 5-second wall. Its native context is 81 frames at 16fps, and one generation falls apart much past that. The community's workaround has always been the same: generate a clip, take its last frame, feed it back in as the start image for the next clip, and repeat - by hand, 40 minutes per 81-frame render on a 4090. WanVideo Looper is that loop, collapsed into one node. You give it a list of prompts, one per segment, and it chains them together with overlap and optional color correction so the result reads as one continuous take instead of a cut-up sequence.
It's built around Wan 2.2's two-expert MoE architecture, so it expects the split this family is famous for: a high-noise model for motion and structure, a low-noise model for detail. You feed both, plus the CLIP and VAE, and the node handles the two-pass sampling internally. The model_switch_point timestep (0.9 for I2V, 0.875 for T2V) decides where the high-noise pass hands off, and sigma_shift (8.0 default) applies to both models.
The inputs that actually matter
The five required model/image inputs are straightforward: model_high, model_low, clip, vae, and start_image (the seed image the first loop animates from). positive_prompts and negative_prompt come from the WanVideo Looper Prompts helper - the looper expects positive_prompts to be a list, one prompt per segment, which is exactly what that node outputs.
After that, the knobs a beginner should touch:
duration_sec- length of each segment in seconds (5 is recommended; each segment isduration × 16 + 1frames, so 5s is exactly 81 frames, Wan's native window).frame_merge- how many overlapping frames stitch each segment into the next. The lastframe_mergeframes of a segment seed the next one's start image. Start at 1-2.steps,cfg_noise,sampler_name,scheduler- normal sampling settings, applied per segment.cfg_motion_noiseis the Wan-specific one: a separate CFG for the first step only, which nudges initial motion; set it to 1.0 to disable.seed- a single seed used for every segment, so the whole sequence is reproducible.
Color matching is where this node earns its keep. color_match_method offers Disabled, Reinhard (GPU), or MKL (GPU), and color_match_reference_frame picks the anchor: Sequential matches each segment to the previous segment's last frame (the drift fixer), while First/Last/Reference matches the whole video to a single frame. color_match_strength blends it in. One caveat: the color math runs on the GPU, but the node still refuses to run it without the color-matcher library installed - it just logs a warning and silently disables the feature.
Outputs are images (the full concatenated batch of frames, ready for a video save node) and last_frame (a single frame, handy for keeping the chain going). There's also an optional clip_vision input to guide the start image, and model_clip_sequence for the Lora Sequencer sibling.
Install
ComfyUI Manager is the easy path: search "WanVideoLooper" and install. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/SquirrelRat/WanVideoLooper
cd WanVideoLooper
pip install color-matcher
Restart ComfyUI, then Add Node > WanVideoLooper. The pack itself ships no model files - the heavy lifting is the Wan 2.2 checkpoint you already need, running on ComfyUI's native Wan support (or Kijai's WanVideoWrapper).
Troubleshooting
- Color match does nothing. Check the console for the
color-matcherwarning. The node'srequirements.txtlistscolor-match, but the code importscolor_matcher- those are not the same package, so let Manager install what it wants and then runpip install color-matcheranyway. - Test with dry run first.
enable_dry_runskips sampling and decoding and just logs the setup and per-segment model choices. On a node that renders 20+ minutes per segment, that's the difference between a 5-second debug cycle and waiting an hour to find a wrong wire. - It's slow, and speed LoRAs are a trap. Full-quality Wan 2.2 at 1280x720 runs about 25 minutes per clip on a 5090; chain five segments and you've booked your evening. The community consensus is that lightx2v/CausVid speed LoRAs degrade motion and detail - if you must, apply them to the low-noise pass only, and keep
cfg_noiseat 1.0. - The node returns a black frame.
positive_promptsisn't a list - the looper validates it and bails with a dummy tensor. Wire the output of the Prompts node, not a raw string. - Dimensions snap down to multiples of 16 regardless of what you type, so set them in multiples of 16 and stop worrying.
This is a niche utility that shows up in real "MoE video" ComfyUI environments (next to WanVideoWrapper and WanVideoAutoResize), and it does one thing properly: it makes long Wan video a set-and-wait operation instead of a babysitting job. If you're chaining clips by hand today, you'll feel it on the first run.
Inputs (27)
| Name | Type | Default | Description |
|---|---|---|---|
| model_high | MODEL | The BASE high-noise model (can be pre-patched with global LoRAs). | |
| model_low | MODEL | The BASE low-noise model (can be pre-patched with global LoRAs). | |
| clip | CLIP | The BASE CLIP model (can be pre-patched with global LoRAs). | |
| vae | VAE | The VAE model used for decoding the final image. | |
| start_image | IMAGE | The seed image that the first loop will start from. | |
| positive_prompts | * | Connect the 'prompt_list' output from the WanVideo Multi-Prompt node. | |
| negative_prompt | STRING | A single, global negative prompt applied to all loops. | |
| seed | INT | 00–18446744073709550000 | The random seed. This will be used for all loops. |
| steps | INT | 61–10000 | The total number of sampling steps for each loop. |
| cfg_motion_noise | FLOAT | 1.00–100 | CFG for the first step ONLY. A value > 1.0 will engage the negative prompt for initial motion guidance. Set to 1.0 to disable motion guidance. |
| cfg_noise | FLOAT | 1.00–100 | Classifier-Free Guidance scale for both high and low noise models. 1.0 disables guidance. |
| sampler_name | COMBO | The sampling algorithm (e.g., dpmpp_2m_sde_gpu). | |
| scheduler | COMBO | The noise scheduler (e.g., karras). | |
| model_switch_point | FLOAT | 0.9000–1 | Timestep to switch from high-noise to low-noise model. 0.9 (I2V) or 0.875 (T2V) recommended. |
| sigma_shift | FLOAT | 8.000–100 | Applies sigma shift to both models. 8.0 is a good default. |
| denoise | FLOAT | 1.000–1 | Denoise amount. 1.0 means generate a full new image. |
| width | INT | 83264–8192 | The width of the output video. |
| height | INT | 48064–8192 | The height of the output video. |
| frame_merge | INT | 10–8 | Number of frames to overlap/merge between loops for smooth transitions. |
| duration_sec | INT | 51–10 | Duration of each segment in seconds. 5s is recommended, max 10. |
| color_match_method | COMBO | Disabled | 'Disabled': No color matching is applied. 'Reinhard (GPU)': Applies Reinhard color transfer. 'MKL (GPU)': Applies MKL color transfer. |
| color_match_reference_frame | COMBO | First Frame | 'First Frame': Matches all frames to the very first frame of the entire sequence. 'Last Frame': Matches all frames to the very last frame of the entire sequence. 'Sequential': Matches each segment to the last frame of the previous segment. 'Reference': Matches all frames to the optional 'color_match_ref' image. |
| color_match_strength | FLOAT | 1.000–1 | Strength of the internal color matching (1.0 = full match). |
| enable_dry_run | BOOLEAN | false | If enabled, skips sampling and decoding to quickly check setup and logs. |
| clip_visionopt | CLIP_VISION | (Optional) A CLIP Vision model for guiding the start image. | |
| model_clip_sequenceopt | ANY | (Optional) Connect a WanVideo Lora Sequencer to use different pre-patched models/clips per segment. | |
| color_match_refopt | IMAGE | (Optional) Static reference image for internal color matching. If omitted, uses last frame of previous segment. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| last_frame | IMAGE | — |