How to create a contact sheet from a video
- Step 1Drop your video onto the tool — Drag an MP4, MOV, MKV, WebM, or AVI onto the upload zone, or click to browse. Processing is 100% local — the file is read into the in-browser FFmpeg.wasm engine and never sent to a server. One file at a time (this tool does not batch).
- Step 2Set Columns and Rows for the grid shape — Both default to 4 (a 4x4 = 16-frame sheet). Each accepts 1-10. The product
cols x rowsis the total number of frames sampled. A 6x6 gives 36 frames; a 1x10 gives a single horizontal strip of 10 frames; a 10x1 gives a vertical column. - Step 3Set Tile width (px) — Default 320, range 120-1280. This is the width of each individual frame in the grid; height is computed from the source aspect ratio. The final PNG width is roughly
cols x tileWidth(plus the tile filter's internal spacing). Bump it to 640-1280 when you need to read fine detail; keep it low for a lightweight shareable sheet. - Step 4Generate the sheet — Click to run. The tool probes the video duration, divides it into
(cols x rows) + 1slices, samples one frame per interval, scales each, and tiles them. A typical short clip finishes in a few seconds; multi-GB files take longer because FFmpeg.wasm decodes the sampled frames in-browser. - Step 5Download the PNG — The result is a single image named
<yourfile>-grid.png. There is no ZIP and no multi-page output — it is always one PNG regardless of grid size. - Step 6Need individual frames instead of a grid? — If you want separate frame files rather than one tiled image, use the thumbnail-extractor tool. If you want frames at scene cuts rather than at fixed time intervals, run scene-detector first to get cut timestamps.
Contact-sheet options and what they control
The three controls in the options panel. Values outside the listed range are clamped by the tool.
| Option | Range | Default | What it controls |
|---|---|---|---|
| Columns | 1-10 | 4 | Number of frames across each row of the grid. Multiplies with Rows to set total frames sampled |
| Rows | 1-10 | 4 | Number of grid rows. cols x rows is the total frame count; the duration is split into that many equal time slices |
| Tile width (px) | 120-1280 | 320 | Pixel width of each frame in the grid. Height auto-scales to keep the source aspect ratio (scale=W:-1) |
Common grid shapes and resulting frame count
Pick a shape by how dense a time map you need. Total frames = columns x rows.
| Columns x Rows | Total frames | Best for | Approx PNG width at 320px tiles |
|---|---|---|---|
| 4x4 | 16 | Default quick overview of a short clip | ~1280px |
| 6x6 | 36 | Classic contact sheet for a medium clip | ~1920px |
| 10x10 | 100 | Densest map — long footage you want to scan finely (max grid) | ~3200px |
| 1x10 | 10 | Horizontal scrubber strip (e.g. chapter art) | ~3200px wide, one row tall |
| 10x1 | 10 | Vertical filmstrip column | ~320px wide, one column |
Tier limits for video tools
Free covers most short-to-medium clips. Limits are file size and batch count only — there is no duration cap.
| Tier | Max file size | Files per batch |
|---|---|---|
| Free | 1 GB | 1 |
| Pro | 10 GB | 5 |
| Pro + Media | 100 GB | 50 |
| Developer | 100 GB | Unlimited |
Cookbook
Concrete recipes for the most common contact-sheet jobs. Each shows the option values and what the output looks like.
Default 4x4 overview of a 10-minute clip
The fastest way to see what is in an unfamiliar video. With a 10-minute clip and a 4x4 grid (16 frames), the tool spaces samples about every 35 seconds across the runtime.
Options: Columns = 4 Rows = 4 Tile width= 320 px Duration = 600 s Frames = 16 Interval = 600 / (16 + 1) = ~35.3 s between samples Output: clip-grid.png (one PNG, ~1280px wide)
High-detail 6x6 at 640px tiles
When you need to actually read text or faces in each frame, raise the tile width. A 6x6 (36 frames) at 640px produces a large, sharp sheet.
Options: Columns = 6 Rows = 6 Tile width= 640 px Frames = 36 PNG width ~ 6 x 640 = ~3840px Output: a large, detailed mosaic — heavier file, better for zooming into individual cells.
Single-row scrubber strip for chapter art
A 1xN grid gives a horizontal filmstrip — useful as a visual scrubber or chapter header. The tool's own example: a 1xN strip at 480px wide tiles reads like a scrubber.
Options: Columns = 10 Rows = 1 Tile width= 480 px Frames = 10 (one row) Output: a wide, one-row PNG — a clean timeline strip.
Lightweight shareable sheet
To keep the PNG small enough to drop into a chat or doc, keep the tile width low. A 5x5 at 240px is compact yet still readable as an overview.
Options: Columns = 5 Rows = 5 Tile width= 240 px Frames = 25 PNG width ~ 5 x 240 = ~1200px Output: a small, sharable contact sheet.
Frames at scene cuts instead of fixed intervals
This tool samples by time, not by content. If you want a frame per scene change, detect cuts first, then extract those exact frames separately — the grid maker cannot key on cuts.
1. scene-detector -> scenes.json (cut timestamps)
/video-tools/scene-detector
2. thumbnail-extractor at those timestamps
/video-tools/thumbnail-extractor
3. (optional) assemble those into a sheet manually
The frame-grid-maker itself always samples
evenly across the full duration.Edge cases and what actually happens
Video duration cannot be determined
ErrorThe tool probes the file for its duration first; if that comes back as zero or missing (corrupt header, fragmented stream with no duration metadata, or a malformed container), it throws "Could not determine video duration." and produces no sheet. Try remuxing the file first, or run it through a sibling tool that rewrites the container.
Columns or rows set above 10
ClampedBoth grid dimensions are clamped to 1-10 internally, so a request for 12 columns becomes 10. The maximum grid is 10x10 = 100 frames. If you need more than 100 frames, run the tool twice over halves of the clip, or use thumbnail-extractor for arbitrary frame counts.
Tile width set below 120
ClampedThe tool enforces a minimum tile width of 120px; smaller values are raised to 120. This keeps individual frames legible. The options panel caps the input at 1280px on the high end.
Very short clip with a large grid
By designIf you ask for a 10x10 (100 frames) on a 5-second clip, the interval shrinks to a fraction of a second. Adjacent cells will look nearly identical because there is so little change between samples. Match the grid density to the clip length for a useful spread.
Vertical (9:16) source footage
SupportedAspect ratio is preserved per tile via scale=W:-1, so vertical phone video tiles correctly — each cell is tall, the overall sheet is tall. No cropping or letterboxing is applied to fit a fixed cell shape.
Expecting timestamps or labels on each frame
Not supportedThe grid is a clean mosaic of frames with no burned-in timecode, filename, or per-cell caption. If you need timestamps overlaid, that is not part of this tool; you can infer approximate position from cell order since sampling is evenly spaced across the duration.
Wanting separate image files, not one sheet
Use thumbnail-extractorOutput is always a single PNG — there is no option to emit one file per frame and no ZIP. For individual frame exports use the thumbnail-extractor tool, which is built for that.
Multiple files dropped at once
Single file onlyThis tool processes one video at a time (it does not accept multiple). Drop one file, generate, then drop the next. Batch counts in the tier table apply to tools that accept multiple inputs.
Very large file on a low-memory device
PerformanceFFmpeg.wasm decodes in the browser tab's memory. A multi-GB file on a low-RAM laptop can be slow or hit a tab memory ceiling even within your tier's size limit. Closing other tabs and using a desktop browser helps; the sampling itself only decodes the frames it needs, not the whole stream.
Audio-only file
ErrorThere are no video frames to sample, so FFmpeg's tile step has nothing to work with and the run fails. This tool is for files with a video stream; audio extraction belongs to the audio-track tools, not here.
Frequently asked questions
What format is the output?
Always a single PNG named <yourfile>-grid.png. It is one image containing the whole grid — there is no JPEG option, no ZIP, and no multi-file export. PNG keeps the frames crisp with no compression artefacts.
How does it decide which frames to grab?
It samples evenly by time. With cols x rows total cells, the duration is divided into (cols x rows) + 1 equal slices and one frame is taken per slice. So the frames spread roughly uniformly from near the start to near the end — they are not chosen by scene change or 'interesting-ness'.
Can I get a frame at every scene cut instead?
Not directly — this tool samples by fixed time interval. To key on cuts, run scene-detector to get the cut timestamps, then pull those exact frames with thumbnail-extractor.
What is the biggest grid I can make?
10 columns by 10 rows = 100 frames. Columns and rows are each clamped to 1-10. For more frames, split the clip and run twice, or use thumbnail-extractor.
Does the tool add timestamps or labels to the frames?
No. The output is a plain mosaic of frames with nothing burned in — no timecode, no filename, no per-cell caption. Position can be inferred from grid order because sampling is evenly spaced.
Will my video be uploaded?
No. The entire process runs in your browser via FFmpeg.wasm. The video bytes are read locally and the PNG is generated on your device. Nothing is sent to a server — important for unreleased or confidential footage.
What input formats are supported?
MP4, MOV, MKV, WebM, and AVI. The tool reads the container, probes duration, and samples frames from the video stream; it does not re-encode or save the whole video.
How big a file can I process?
Free tier allows up to 1 GB per file. Pro is 10 GB, Pro + Media and Developer are 100 GB. There is no duration limit — only file size and batch count. This tool takes one file at a time.
How wide will the final PNG be?
Roughly columns x tile width pixels, plus a little internal spacing from the tile filter. A 6x6 at 320px tiles is about 1920px wide; the same grid at 640px is about 3840px wide.
Does it handle vertical or square video?
Yes. Each tile keeps the source aspect ratio (the tool scales by width and lets height follow), so 9:16, 1:1, and 4:3 footage all tile without stretching or cropping.
Why do my cells look almost identical?
That happens when the grid asks for many frames from a very short clip — the sampling interval becomes a fraction of a second so adjacent frames barely differ. Reduce columns/rows for short clips to get a meaningful spread.
Is this hardware-accelerated?
No. The contact sheet path runs through FFmpeg.wasm in the browser (it is not on the WebCodecs hardware path), so speed depends on your CPU and available tab memory. It still only decodes the frames it samples, not the entire stream.
Privacy first
Every JAD Video tool runs entirely in your browser via WebCodecs and FFmpeg (WebAssembly). Your video files never leave your device — verified by zero outbound network requests during processing.