Nodes/VACE Automation/VACE Join Prep
ComfyUI Node

VACE Join Prep

Build the seam control window for two clips

By EnviralDesign·Created 7 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_images → VACE 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—