Replace First & Last Frames
Swap the bookends of any AI video — without touching the middle
- image_sequence
- start_frames
- last_frames
- image_sequence
Every serious AI-video project ends the same way: with a clip whose first frame drifted a pixel away from the image you actually wanted to start on. Replace First & Last Frames is the surgical answer - it takes an image sequence, pops the opening and/or closing frames out, and splices in frames you supply. The middle stays untouched. That's the whole job, and it does it well.
Why you'd reach for it
If you've spent any time with Wan, LTX, or AnimateDiff, you know first-frame/last-frame conditioning (FLF) is how the community keeps long videos consistent - anchor clip 1's last frame, chain it into clip 2's first frame, repeat. This node is the mechanical version of that idea. You're not conditioning the model on a bookend; you're literally replacing frames after generation, when you want the output to end on an exact frame, not just start there.
The classic use: you generated a Wan clip with a strong start image, but the model decided the last frame should be blurry mush. You re-run the tail with a better keyframe, extract the good frame, and swap it in here. Or you're stitching a multi-clip sequence and want every segment to start and end on exact match points. It's also handy when a generation came out N frames short - you can bookend it with your intended start/end frames and let the rest of the pipeline (interpolation, VACE joining) work from there.
How it works
Under the hood it's plain tensor surgery. An image sequence in ComfyUI is a [batch, height, width, channels] tensor, so "replace the first two frames" means slicing, substituting, and re-concatenating along the batch axis. Two details do the actual work:
- Auto-resize. Whatever resolution or channel count your
start_frames/last_framescome in at, the node resizes them (bilinear) to match the sequence, and even handles RGB↔RGBA↔grayscale mismatches by dropping or padding alpha. - Frame-count arithmetic. Ask for more replacement frames than you provide and it repeats or cycles the ones you gave; ask for more total than the sequence holds and it scales both counts down proportionally, keeping at least one middle frame alive. The author wrote this thing to be "pretty robust," and it mostly is.
There's no model download, no GPU-heavy pass - this is a wire-time edit. Feed it a batch, get a batch of the same size back.
The inputs that matter
You'll set a handful of things:
- image_sequence - your video as frames (a
Load Video/VHS_VideoInfo/ batch of frames). - num_start_frames and num_last_frames - how many frames to replace at each end. Default 1 each. Set one to 0 to touch only one end.
- start_frames / last_frames (optional) - the replacement images. Leave one unconnected and the node just keeps the original frames for that end, so you can do start-only or end-only swaps.
Output is image_sequence, one IMAGE tensor that wires straight into whatever was consuming the original - VAE encode, a sampler, WanVideoWrapper, an AnimateDiff batch, whatever.
Installing it
The pack is a single Python file with zero dependencies - no requirements.txt, no model files to fetch.
cd ComfyUI/custom_nodes
git clone https://github.com/lovisdotio/ComfyUI-Replace-First-Frame-Last-Frame
Restart ComfyUI and it shows up under image/animation as "Replace First & Last Frames." Or skip all that and search "Replace First & Last Frames" in ComfyUI Manager - same result, and Manager's fine here since there's nothing to conflict with.
Gotchas
- It's a cut, not a blend. Replacing frames gives you a hard splice at the join. If your replacement frame doesn't match the adjacent middle frames, you'll see a jump - run the result through a light interpolation or VACE join for smoothness. That's expected, not a bug.
- Pixel-perfect means same resolution. Auto-resize is convenient, but bilinear upscaling softens a low-res bookend. If the exact frame matters, feed frames at the sequence's native resolution and the resize path is a no-op.
- One frame repeats. Feed a single start image with
num_start_frames: 5and it becomes five copies of that frame - which is exactly what you want for locking a still, but surprising if you expected distinct frames. Feed five frames for five distinct ones. - Over-booking scales down. Request 10+10 on a 16-frame clip and the node quietly shrinks both to fit. It won't error; it'll just do something slightly different than you asked.
For a niche nobody else bothered to fill cleanly (WanVideoWrapper has a comparable node if you're already living in that ecosystem), this one is refreshingly small and honest about what it does. When you need exact bookends, it's the tool.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image_sequence | IMAGE | — | |
| num_start_frames | INT | 10–10000 | — |
| num_last_frames | INT | 10–10000 | — |
| start_framesopt | IMAGE | — | |
| last_framesopt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image_sequence | IMAGE | — |