Nodes/ComfyUI-VideoFrameTools/Video Frame Reorder & Skip
ComfyUI Node

Video Frame Reorder & Skip

Swap your video's halves and drop frames without ever leaving the graph

By zhaocaiji·Created 8 months ago·Updated 8 months ago· 1
Video Frame Reorder & Skip
  • image_sequence
  • processed_images
skip_interval0

One node, two jobs nobody gives you a built-in for

Once your ComfyUI video is out of the VAE decode, it's just a big tensor of frames - and the core toolset gives you surprisingly few ways to rearrange them. You can encode them, save them, combine them, but "change the order" or "keep every other one" isn't a button anywhere. VideoFrameReorderAndSkip (class VideoFrameReorderAndSkip, from the tiny zhaocaiji/ComfyUI-VideoFrameTools pack) is a two-in-one utility for exactly that. It does two things: swaps the two halves of your sequence, and decimates it by an interval. That's it. No weights, no models, no hidden pipeline - just a couple of tensor slices.

The pack is almost absurdly small - one Python file, zero dependencies beyond torch, which ComfyUI already ships. That's the right size for this job, and it means there's no install drama beyond dropping it in.

What it actually does under the hood

The mechanism is worth knowing because it explains the quirks. Your image_sequence arrives as a tensor shaped [frames, height, width, channels], and the node only touches that first (frame) dimension.

First, it always reorders: it cuts the sequence in half and concatenates the halves back in swapped order. For 16 frames you get [8..15, 0..7], not a true reversal. Second, it skips frames: skip_interval of N keeps 1 frame every N frames, implemented as a stride of N+1. Set 0 and the stride is 1, so nothing is dropped.

Read the source (video_tools.py in the repo) and one gotcha jumps out: the half-swap runs unconditionally. There is no toggle to disable it. If you only wanted frame skipping, you still get the halves swapped first. There's also a guard - if your sequence has fewer than 2 frames, the swap is skipped entirely and only the skip applies.

The two inputs that matter

  • image_sequence (IMAGE) - wire this to a VAE Decode output, or an image sequence/loader node. The README says it plainly: batch frames in, batch frames out.
  • skip_interval (INT, default 0, range 0–120) - 0 keeps everything; 1 keeps 1 frame in every 2 (halves the frame count); 2 keeps 1 in 3, and so on.

The single output, processed_images (IMAGE), feeds straight into VideoCombine or SaveImage - same slot the decoded frames would have gone into.

Installing it

ComfyUI Manager is the easy path - search for "VideoFrameTools" and install. Otherwise, from your ComfyUI/custom_nodes directory:

git clone https://github.com/zhaocaiji/ComfyUI-VideoFrameTools

Then restart ComfyUI. No model files, no pip installs, no heavy dependencies - the whole thing is one video_tools.py plus a mapping in __init__.py. It appears under My Custom Nodes → Video Tools in the node menu.

Where it earns its keep, and where it burns you

Frame skipping is the genuinely useful half. It's how you fit long generations into short context windows, turn a 60fps render into 30fps, or cut a 121-frame LTX clip down to something your VRAM can re-encode in one pass. The half-swap is more situational - it's handy when you're splicing two halves of a clip back together in a different order, or pairing first-half/last-half frames for interpolation-style work.

The burn: beginners reach for this expecting a "reverse" button and get a split-and-swap instead. If you want a true reversed playback, this won't give it to you. And because the swap can't be turned off, it's not a clean "just decimate" node either - feed it a sequence and check that the swapped order is actually what you want before you commit frames to a render. The naming in the code comments ("first half", "second half") matches the behavior exactly, so a quick look at the source saves you a wasted encode.

CategoryMy Custom Nodes/Video Tools

Inputs (2)

NameTypeDefaultDescription
image_sequenceIMAGE
skip_intervalINT00–120

Outputs (1)

NameTypeDescription
processed_imagesIMAGE