vcsi: building video contact sheets from the command line
Create video contact sheets, thumbnails
At a glance
- What is it?
- vcsi is a Python tool that takes a video file and lays its capture thumbnails out on a grid as a single contact sheet image, with timestamps, metadata fonts and colours under your control. It drives ffmpeg for the frame grabbing and can output a standalone thumbnail as well as a sheet.
- Who is it for?
- Adopt vcsi if you need a visual index of a video, for review, editing or archiving, and you want the layout, timestamps and typography to be scriptable rather than fixed. Do not adopt it if you need batch keyframe extraction to individual files, because that is a different tool, and note that the documented default font path points at a Windows font, so a first run on Linux needs the font option set.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 94 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What a contact sheet is, and why it is a grid
vcsi creates video contact sheets, and the README defines the term in a sentence: a video contact sheet is an image composed of video capture thumbnails arranged on a grid. That is the whole output. The tool takes a video, captures frames from it, and composes those captures into a single image, which is the format people use to review a long recording, to pick shots from a source clip, or to leave a visual index next to a file. The repository description mentions contact sheet, thumbnails, screenshots and thumbnail grids, and the primary language is Python with an MIT licence, the default branch is master, the last push was on 2026-07-21, and the recent release tags are v7.0.17 from 2026-03-22, v7.0.16 from 2023-09-22 and v7 from 2017-11-22. The version numbering is worth noting, because a v7 tag from 2017 next to a v7.0.17 tag from 2026 tells you the project went a long time between minor releases.
$ vcsi bbb_sunflower_2160p_60fps_normal.mp4 \
-t \
-w 830 \
-g 4x4 \
--background-color 000000 \
--metadata-font-color ffffff \
--end-delay-percent 20 \
--metadata-font /usr/share/fonts/TTF/DejaVuSans-Bold.ttfThat is the README's first example, and it reads as a spec: a sheet 830 pixels wide, a four by four grid, black background, white metadata text, no captures in the last 20 percent of the video, and a specific TrueType font for the labels.
The second example, and what the grid and delay options really do
The second example in the README changes the grid to three by five, points at a different font for the timestamp overlay rather than the metadata font, and writes the result to a named file with -o. Both examples were generated from the same source, the Big Buck Bunny film, and the README says so. The option list explains the mechanics. The grid is written as a column by row expression, 4x5 for example, and the special value of zero, as in 2x0 or 0x5 or 0x0, is only allowed when combined with --interval or with --manual, where zero means the layout should be deduced automatically from the other arguments. The default is 4x4, and there is a separate sample count option with no default. The delay options are what stop a contact sheet from being full of black frames: start-delay-percent and end-delay-percent skip the first and last n percent of the total time, each defaulting to 7, and a combined delay-percent option covers both ends at once.
$ vcsi bbb_sunflower_2160p_60fps_normal.mp4 \
-t \
-w 830 \
-g 3x5 \
--end-delay-percent 20 \
--timestamp-font /usr/share/fonts/TTF/DejaVuSans.ttf \
-o output.pngThe timestamps and the metadata are separately configurable, which is what makes the tool usable as a review artefact rather than a quick preview.
Installing with uv, pip, or a distribution package
The README asks you to install uv first, then gives four ways to get the tool. From PyPI, the recommended form is a uv tool install, and the same tool installs from a local source tree or straight from a URL.
$ uv tool install vcsi$ uv tool install .uv tool install git+https://github.com/amietn/vcsiIf you would rather use pip, that is one command too.
pip install vcsiDistribution packages exist for a few systems, with the README listing the Arch AUR page for vcsi, a separate AUR package for the git master version, and a Gentoo package under media-video. For a system that is not listed, the README's advice is to install ffmpeg and then use the uv route above, which is the practical shape of this tool on a Debian or Ubuntu machine.
$ apt-get install ffmpegWhat vcsi needs at runtime, and the Windows caveat
The requirements are split in two. The Python modules are numpy, pillow, jinja2, texttable and parsedatetime, and the pyproject.toml pins pillow at 12.2.0, numpy at 2.2.6, jinja2 above 3.1.6 and below 4, texttable above 1.6.7 and below 2, and parsedatetime at about 2.6. The executables are ffmpeg and ffprobe, and both must be in your PATH. The Windows note in the README is the part to read before you install there, because it is not a pip problem. It says to download a binary build of ffmpeg from Zeranoe, for example the 64 bit static one, extract the archive and add the bin directory to your PATH so that ffmpeg and ffprobe can be invoked from the command line. It also notes that if you have trouble installing numpy with pip, you can download an already built version of numpy from a SourceForge page. The theme running through all of this is that the tool is a thin Python layer over ffmpeg, and the ffmpeg setup is the part that actually requires attention.
The option surface, and the defaults that will surprise you
The help output in the README is long, and reading it is the fastest way to understand the tool's defaults. The sheet width defaults to 1500 pixels, the grid to 4x4, the grid spacing to 5 pixels both horizontally and vertically, the metadata font size to 16, and the metadata font to a Windows path, C:/Windows/Fonts/msgothic.ttc, which is a genuine portability wart given the sample commands use a Linux TTF path instead. Timestamps are off by default and enabled with the -t flag, which the README describes as showing the timestamp for each frame. There are separate colours for metadata font and timestamp font, plus timestamp background and border colours, and the metadata position and timestamp position options decide where the labels sit. The template option takes a metadata template path, there is a manual timestamps mode, an accurate delay seconds option, and quality and image format options for the output. For a scriptable tool, this surface is what matters, and the defaults tell you what you get before you change anything.
$ vcsi -hTwo other details in the help output are worth knowing about. The config option loads defaults from a configuration file, and the default path shown in the help text is a Windows user path, C:\Users\zacke\.config/vcsi.conf, which tells you the project is developed on Windows. And the filenames argument is positional, so a contact sheet is produced by naming the input video and letting the tool work out the output.
Where the tool stops, and what to compare it with
The limits follow from the design rather than from missing work. A contact sheet composites frames into one image, so it is the wrong tool for extracting individual keyframes to files, which is what a batch thumbnailer does, and the repository's own topic list shows both contact-sheet and thumbnail usage, but the output described in the README is the composed sheet. The second limit is the dependency on ffmpeg being present and correct, and the README's Windows section is really a warning about that, since a missing or mismatched ffmpeg is the most likely reason a first run fails on a machine that did not come with it. Third, the compositing is bound to a fixed grid and a fixed set of overlays, so if you need per shot labels, a timecode burn-in across a different aspect ratio, or a specific brand palette, you are writing your own ffmpeg filter graph and a Pillow composition step rather than configuring vcsi. The alternative to weigh is doing it by hand with ffmpeg's tile filter, which gives you the frames without the labels, the grid logic or the font handling, and which you would then have to script yourself.
Editorial conclusion
Adopt vcsi if you need a visual index of a video, for review, editing or archiving, and you want the layout, timestamps and typography to be scriptable rather than fixed. Do not adopt it if you need batch keyframe extraction to individual files, because that is a different tool, and note that the documented default font path points at a Windows font, so a first run on Linux needs the font option set. Before you run it, install ffmpeg and ffprobe and put them on your PATH, and check the grid options, since a zero value in either dimension has a specific meaning.
Frequently asked questions
What is vcsi and what does it produce?
It is a Python tool that creates video contact sheets, which the README defines as an image composed of video capture thumbnails arranged on a grid. It captures frames from a video with ffmpeg and composites them into a single sheet image, with optional timestamps and metadata labels.
How do I install vcsi?
The README asks you to install uv first, then offers uv tool install vcsi from PyPI, uv tool install . for a local source tree, uv tool install git+https://github.com/amietn/vcsi for a URL, and pip install vcsi. Packages also exist for Arch, Arch git master and Gentoo, and on other systems the README suggests installing ffmpeg and using the uv route.
What does vcsi need besides Python?
ffmpeg and ffprobe must both be in your PATH. The Python requirements are numpy, pillow, jinja2, texttable and parsedatetime. The README also has a specific note for Windows users about downloading a binary ffmpeg build from Zeranoe and adding its bin directory to PATH.
How do I control the contact sheet layout?
The grid option takes a column by row value such as 4x5, defaulting to 4x4, and a zero in either dimension is only allowed with --interval or --manual, where it means the layout is deduced automatically. The sheet width defaults to 1500, grid spacing to 5 pixels in both directions, and separate options control the timestamp and metadata fonts, sizes and colours.
What do the delay options in vcsi do?
They keep blank or uninteresting frames out of the sheet. start-delay-percent and end-delay-percent skip the first and last n percent of the total time, each defaulting to 7, and a combined delay-percent option skips both ends. There is also an accurate delay seconds option and a manual timestamps mode.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/amietn-vcsi)Was this useful?