🎥 Video Interval Auto-Calc
This Node Does the Contact-Sheet Math for You
- select_every_nth
- frame_load_cap
- skip_first_frames
- total_count
You've got a two-minute clip and you want a tidy 4x5 grid of frames from it. So… what's select_every_nth? That's the whole reason this node exists. Video Interval Auto-Calc (class VideoIntervalCalculator) is a pure-math utility: you tell it how many rows and columns you want, it tells you exactly which frames to grab. It's the "how many frames should I skip" problem, automated.
What it actually does
The node opens your video with OpenCV and reads the FPS and total frame count - metadata only, no decoding, so it's fast even on big files. The README calls it resource-efficient, and that part is genuinely true: cv2.VideoCapture gives you the numbers without ever touching pixel data. Then it does the arithmetic: (end_frame - start_frame) // (rows * cols), clamped to a minimum of 1, and hands you four numbers to plug into the rest of your workflow.
The inputs you'll actually touch:
video_path- the path to your video. Use an absolute path; the README says so, and relative paths are the classic way to get "Cannot open video file" and go hunting.rowsandcols- your target grid. Default 4x4, capped at 100 each.start_time/end_time- both default to 0, which means "whole video." Set them in seconds if you only want a section.
The outputs are the point:
select_every_nth- the frame skip interval (wire this into VHS).frame_load_cap- rows × cols, i.e. how many frames to load.skip_first_frames- where to start, in frames (useful if you setstart_time).total_count- same as the cap, kept around for other calculations.
The workflow it's built for
This pack is designed to feed Video Helper Suite (VHS) - the README is upfront that it calculates values but VHS is what actually loads frames. Set it up like this:
- Add Video Interval Auto-Calc, enter your path, rows, and cols.
- Add a VHS Load Video (Path) node.
- Right-click the VHS node → Convert Widget to Input for
frame_load_cap,select_every_nth, andskip_first_frames. - Wire the matching outputs from Auto-Calc into those inputs.
Then the IMAGE output from VHS goes into the pack's other node, Batch to Grid Image, and you've got a one-click contact sheet for any video. This is exactly the kind of fiddly-but-common step that eats a workflow - the kind of thing you end up hand-calculating every time you change the video or the grid, which is why people reach for a calculator node at all.
Installing it
Either way, same result:
cd ComfyUI/custom_nodes
git clone https://github.com/NexusEast/ComfyUI_ContactSheet_Auto
# restart ComfyUI
Or skip the terminal: open ComfyUI Manager → Custom Nodes Manager, search ComfyUI_ContactSheet_Auto, and install. The requirements file is just opencv-python and numpy - no model downloads, nothing heavy. OpenCV is usually already in a ComfyUI environment, and you do want VHS installed too, or the main node has nothing useful to talk to. (One heads-up: the README's manual-install block has YOUR_USERNAME in the clone URL - a copy-paste typo. Use the real repo above.)
Where people trip
- Video won't open - almost always a path problem. Absolute path, and note the node strips surrounding quotes for you, so pasting from a Windows explorer copy that includes them still works.
end_timeat 0 means "to the end" - the code treats 0 (or anything past the video's length) as "use everything." Easy to misread as "load nothing."- Grid comes out with extra frames - the interval is integer division, so a short video with a big grid can produce more frames than rows × cols. That's fine: the grid node computes its rows as
ceil(batch / cols)and handles leftovers. - Start after end - if
start_time >= end_time, the node quietly resets to the full video and warns in the console. It's a safety fallback, not a bug.
One honest caveat: this is a tiny, single-commit utility pack - "do one math thing, do it well" is the vibe, not "actively maintained toolkit." For the price of a custom-node install, though, it kills a recurring bit of friction, and the logic is simple enough to trust. That's the whole pitch, and it holds.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| video_path | STRING | input.mp4 | — |
| rows | INT | 41–100 | — |
| cols | INT | 41–100 | — |
| start_time | FLOAT | 0.0 | — |
| end_time | FLOAT | 0.0 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| select_every_nth | INT | — |
| frame_load_cap | INT | — |
| skip_first_frames | INT | — |
| total_count | INT | — |