Nodes/VACE Automation/VACE Join Prep
ComfyUI Node

VACE Join Prep

Build the seam control window for two clips

By EnviralDesign·Created 6 months ago·Updated 3 months ago· 0
VACE Join Prep
  • video_1
  • video_2
  • control_video
  • control_mask
  • width
  • height
  • length
  • start_images
  • end_images
  • context_frames
  • replace_frames
  • new_frames
context_frames8
replace_frames8
new_frames0
debugfalse
is_final_loop_passfalse

This is the workhorse of the pack. VACE doesn't join clips by itself - it needs a control window: a few frames of context from the end of clip A, a few from the start of clip B, and a mask telling it "regenerate everything between." VACE Join Prep builds exactly that from two explicit clips, no loop and no manifest logic. It's the standalone, dead-simple version of the seam, and the loop workflow wraps around it.

How it works

You give it two IMAGE batches (video_1, video_2). It slices the tail context of video_1 and the head context of video_2, fills the middle with a neutral gray block, and returns:

  • control_video = tail context + gray filler + head context
  • control_mask = ones across the filler, zeros elsewhere - so VACE knows precisely which frames to regenerate

Three numbers shape the window:

  • context_frames (default 8) - real frames on each side that anchor the generation
  • replace_frames (default 8) - how many frames of each clip get replaced by generated content
  • new_frames (default 0) - extra generated frames to add on top

The filler is 2 × replace_frames + new_frames + 1 frames long. Why the +1? That extra gray frame is what forces the model to actually invent a transition rather than just morph between the two real sides - it's the bit that turns a blend into a join. Alongside the control pair, the node trims the two source clips down to start_images (clip A's kept body) and end_images (clip B's kept body), which VACE Join Assemble later stitches around the generated transition.

Inputs and outputs that matter

Inputs: video_1, video_2 (IMAGE), the three numbers above, debug, and an optional is_final_loop_pass boolean (default false) that switches the prep into tail-to-head mode so it can serve the loop path.

Outputs you'll wire:

  • control_video + control_mask → your VACE control nodes
  • start_images + end_imagesVACE Join Assemble
  • length (the control window's frame count) → handy for the sampler, so you know what you're generating
  • width/height → keep your decode consistent
  • context_frames/replace_frames/new_frames echoed back out → wire to the assemble node

Installing it

Part of the comfy-vace-automation pack, no extra pip dependencies:

cd ComfyUI/custom_nodes
git clone https://github.com/EnviralDesign/comfy-vace-automation

Restart ComfyUI, or install via ComfyUI Manager (search "comfy-vace-automation").

When it bites you

  • Dimensions must be divisible by 16. VACE control wants that, and the node enforces it with an explicit error. Resize first.
  • Resolution mismatch between the two clips - the error names both sizes, so it's easy to spot which clip is off.
  • Clips too short for the trim. If a clip has fewer than context_frames + replace_frames frames (when replacing), the slice fails. Feed longer clips or shrink the numbers.
  • is_final_loop_pass needs a longer video_1. In loop mode the node keeps more of clip A as the retained body, so a very short first clip errors with a "needs more than N frames" message.

A note on the wider workflow: this pack expects the VACE control/inference nodes themselves to come from elsewhere - the README points at packs like KJNodes for extras such as WanVideoNAG and ColorMatch. VACE Join Prep produces the standard control video + mask format, so it plugs into whatever Wan VACE setup you already run.

Categoryvideo/VACE

Inputs (7)

NameTypeDefaultDescription
video_1IMAGE
video_2IMAGE
context_framesINT81–4096
replace_framesINT80–4096
new_framesINT00–4096
debugBOOLEANfalse
is_final_loop_passoptBOOLEANfalse

Outputs (10)

NameTypeDescription
control_videoIMAGE
control_maskMASK
widthINT
heightINT
lengthINT
start_imagesIMAGE
end_imagesIMAGE
context_framesINT
replace_framesINT
new_framesINT