Video Timeline
See every video frame at once with a contact sheet
- images
- timeline
- frames
Video models are a pain to review. AnimateDiff, LTX, Wan - they all hand you a batch of frames as one tensor, and the preview window shows you one frame at a time while you scroll and try to hold 30 of them in your head. NNVideoTimeline fixes the "oh god, which frame has the melted face" problem by laying every frame out on a single contact sheet, so the whole animation is one image you can eyeball in a second.
It's from ComfyUI-NN-custom-nodes, a small one-author utility pack (bandifiu) that's basically a grab bag of image, resolution, and IO helpers. This is the node you'd reach for when a video workflow starts being a debug session: paste it between your video sampler and a preview, and you get the story of the whole animation at a glance instead of a wall of individual frames.
How it works
You feed it the frame batch (images), and it builds a grid of rows × columns cells. The mechanism is straightforward, but two details are worth knowing:
- It samples, it doesn't show all. If your batch has more frames than grid slots, it picks evenly spaced ones using linear interpolation across the sequence - so 40 frames into a 2×2 grid gives you frames ~0, 13, 27, 40, not the first four. That's actually the right call for judging motion and pacing. If you want every single frame, set rows × columns high enough to hold the whole batch.
- It only ever shrinks.
max_resolution(default 2048) caps the sheet's longest side, and the scale factor never goes above 1.0 - so a 16-frame grid stays tiny, but you can't use this to blow frames up. Empty cells just fill with white.
The inputs that matter
Only three widgets, and honestly only two of them matter on day one:
columns/rows- the grid shape. Rows × columns is how many frames you'll actually see. Default 2×2 is a smoke test; for real review you'll want 4×4 or wider. Both go up to 99, which is plenty.max_resolution- the cap on the sheet's longest side (64 to 8192, in steps of 2). You almost never need to touch it.images- the actual frame batch from your video model's output.
The timeline output is the one contact-sheet image: wire it to a Preview or Save node. The second output, frames, is the exact subset of frames that landed in the grid, as a fresh batch - handy if you want to save just those, or run them through an upscaler before saving them off individually.
Installing it
Same routine as every custom node:
cd ComfyUI/custom_nodes
git clone https://github.com/bandifiu/ComfyUI-NN-custom-nodes
then restart ComfyUI. Or just search "ComfyUI-NN-custom-nodes" in ComfyUI Manager and click install. No model downloads, and the dependencies (torch, numpy, pillow, tomli) are all things ComfyUI already has - this pack ships no heavy extras.
Where people get burned
Two things trip people up. First, the white fill: if your animation is shorter than the grid, you get blank white cells at the end of the sheet, and it's easy to misread one as "a missing frame." It's just padding. Second, don't expect this to replace a proper video player - it's a timeline, a stills contact sheet, not motion preview. For judging actual motion you still want to save the frames out as a video. But for "did every frame keep its subject's face together" sanity checks, this is the quickest glance you'll get.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| columns | INT | 21–99 | — |
| rows | INT | 21–99 | — |
| max_resolution | INT | 204864–8192 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| timeline | IMAGE | — |
| frames | IMAGE | — |