Contact Sheet
The whole clip, on one image
- video
- image
Reviewing a video clip in a node graph is usually painful - you scrub, you squint, you re-render previews. Contact Sheet solves it the old-school way: it samples frames evenly across a COMFYTV_VIDEO and tiles them into a single grid image. With the default 4×4 that's sixteen frames from across the clip's duration, stamped with timecodes, on one COMFYTV_IMAGE you can actually look at. It's the "scan the whole thing at a glance" node - for approval, for comparing framing across a scene, or as a quick storyboard-style sheet of your footage.
How it works
Unlike the browser-instant image tools, this one does real work: a ▶ Run triggers an ffmpeg pass on the server (the pack's contact_sheet_image runner), which decodes the clip, samples cols × rows frames evenly across its full duration, and assembles the grid. That's why it lives in the Video lane rather than the instant-tool lane. COMFYTV_VIDEO in, COMFYTV_IMAGE out.
The inputs that matter
- cols / rows - grid dimensions, each 1–12, defaults 4×4. Tiles = cols × rows, sampled evenly across the clip.
- sheet_width - output image width in pixels, 320–8192, default 1920. Tile size follows from this and the column count.
- timecode - boolean, default on. Stamps each tile with its source timecode, which is what makes the sheet actually reviewable.
Output is image (COMFYTV_IMAGE). The usual internal trio (force_run_token, project_id, parent_output_id) is there and ignored.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/jtydhr88/ComfyTV
Restart the ComfyUI backend (a real restart, not a tab refresh); nodes appear under the ComfyTV category. ComfyUI Manager finds the pack by searching "ComfyTV". The README's two recurring gotchas: on Desktop/macOS/multi-install setups the relative cd can clone into the wrong instance - read the startup log for the base path it loaded and clone into that absolute path, quoted - and the first level of custom_nodes/ComfyTV/ must contain __init__.py, not a nested ComfyTV/ComfyTV/ folder. No Python dependencies to install - the ffmpeg pass rides on ComfyUI's own.
Troubleshooting and tips
- Thumbnails too small to read. Raise
sheet_width, or drop the tile count. More tiles means finer coverage but smaller cells - that's the one trade-off to manage. - "Video required" if nothing happens. The
videoinput is unwired or the upstream clip hasn't rendered a snapshot yet. Run the video stage first. - Want one frame per shot, not even sampling? The docs point to Scene Detect for shot-based thumbnails, then sheet those. Contact Sheet is honest about being even sampling across the full duration.
- Keep timecode on. The whole point of a contact sheet is jumping back to the exact moment in the source; without the stamps you're just squinting at a grid.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| force_run_token | INT | 00–2147483647 | Internal — bumped on Run to invalidate ComfyUI's input cache. |
| project_id | STRING | Internal — populated by the projectStore on the frontend. | |
| parent_output_id | INT | 00–2147483647 | Internal — lineage parent set by spawn handlers on the frontend. |
| cols | INT | 41–12 | — |
| rows | INT | 41–12 | — |
| sheet_width | INT | 1920320–8192 | — |
| timecode | BOOLEAN | true | — |
| videoopt | COMFYTV_VIDEO | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | COMFYTV_IMAGE | — |