Nodes/comfyui-svdint4/Video Motion Contact Sheet
ComfyUI Node

Video Motion Contact Sheet

The storyboard that tells a model what happened

By wjie98·Created 2 months ago·Updated about 10 hours ago· 2
Video Motion Contact Sheet
  • video
  • frames
  • contact_sheet
  • sampled_frames
  • prompt_hint
grid_size3
samplinguniform
width0
height0
resize_modefit
gap0
film_bordertrue
annotationindex
image_frame_rate24.00

Every so often someone on r/comfyui asks "how do I show a video's motion in one image?" - and the answer used to be: decode frames manually, grid them with an image node, and hope the timing survives. Video Motion Contact Sheet (Experimental) is that idea, done properly: it samples an N×N chronological storyboard from a video or a frame batch, arranges it as a contact sheet, and - the genuinely clever part - can weight the sampling toward the frames where things actually move.

The name is the summary. This is a motion contact sheet, not a uniform one: leave sampling on uniform and you get evenly spaced frames preserving timing; switch to motion_weighted and the panels concentrate where visual change is strongest, which is what you want when the interesting action happens in one burst and the rest of the clip is two people standing still.

How it works

It decodes exactly grid_size² frames in chronological row-major order, measures per-interval visual change to build motion scores, and renders each panel with an optional "film strip" treatment - rails, perforations, and labels on the lower rail. There's a prompt_hint output that's a ready-made instruction string telling an image model to "read its frames from left to right, then top to bottom... do not reproduce frame numbers, timestamps, film borders, perforations." That's the trick that makes this more than a debug view: the contact sheet is designed to be fed back into an image or video model as reference conditioning.

The inputs that matter

  • video or frames - exactly one. video takes a loaded ComfyUI VIDEO; frames takes an already-decoded IMAGE batch. Connect both and it errors on purpose.
  • grid_size - 2 to 8, default 3. That's 4 to 64 panels.
  • sampling - uniform (default) or motion_weighted.
  • width / height - 0 derives from the source aspect and the other dimension. These are for the sheet, not the panels.
  • film_border - default on: film rails and perforations with labels on the lower rail. Off uses a narrow caption rail for labels instead.
  • annotation - none, index, timestamp, or index_timestamp. Timestamps derive from image_frame_rate (default 24) when the source is a frame batch.
  • gap - black pixels between panels; resize_mode - fit, crop, stretch for how each frame fills its panel.

Outputs: contact_sheet (the rendered grid), sampled_frames (the raw selected frames, if you want them separately), and prompt_hint (the instruction string).

How to install

Ships with ComfyUI Turing Utils ("comfyui-svdint4" in Manager):

cd ComfyUI/custom_nodes
git clone https://github.com/wjie98/comfyui-svdint4
cd comfyui-svdint4
python -m pip install -v --no-build-isolation -e ./kernel

Pure Python and image work - no kernel dependency for this node, but the pack installs as a unit.

The honest take

This is the one node in the pack you'd reach for even on a modern card, because it's not about performance - it's about seeing. Use uniform when you're eyeballing timing, motion_weighted when you want the story of the action, and feed the sheet plus prompt_hint into a reference-conditioned model when you want a continuation to understand what already happened. It's marked experimental, and it is - the film-border look is optional taste, not quality. But for "what actually happened in this clip, at a glance," it's the best answer in this pack.

CategoryTuring Utils/video

Inputs (11)

NameTypeDefaultDescription
grid_sizeINT32–8Sample exactly grid_size squared frames in chronological row-major order.
samplingCOMBOuniformUniform preserves timing. Motion weighted allocates more panels to intervals with stronger visual change.
widthINT00–8192Final sheet width. 0 derives it from the source aspect and the height setting.
heightINT00–8192Final sheet height. 0 derives it from the source aspect and the width setting.
resize_modeCOMBOfitHow each sampled frame is fitted into its panel.
gapINT00–64Black pixels between adjacent panels.
film_borderBOOLEANtrueWrap every panel in film rails and perforations. Labels are printed on the lower rail.
annotationCOMBOindexOptional chronological label. Without the film border, labels use a narrow caption rail outside the frame.
image_frame_rateFLOAT24.000.01–1000Used only to derive timestamps when the source is an IMAGE batch.
videooptVIDEOA loaded ComfyUI VIDEO. Connect either video or frames, not both.
framesoptIMAGEAn already decoded video frame batch. Connect either frames or video, not both.

Outputs (3)

NameTypeDescription
contact_sheetIMAGE
sampled_framesIMAGE
prompt_hintSTRING