Extract video frames
Pull out one frame every N seconds as a sequence of PNGs, in the browser only, like pdf-to-image (src/tools/pdf-to-image.ts), because decoding frames needs WebCodecs, which Node has no equivalent of. Nothing is uploaded.
Runs on your device. The file is never uploaded.
Extract video frames samples one PNG every intervalSec seconds of a clip, one second apart by default, stopping at maxFrames, which is 60. Files are named after the video with a three-digit counter, such as clip-001.png, so they sort in time order. Decoding frames calls WebCodecs, which Node lacks, so the CLI and MCP surfaces refuse this one.
Questions
How many frames will I get?
One every intervalSec seconds, which defaults to 1, stopping at maxFrames, which defaults to 60. So the default settings give you at most a minute of one frame per second. Raise maxFrames if you need more, but remember every frame is a separate PNG held in memory until you download it.
What are the files called?
Your video name with a three digit counter and a .png ending, for example clip-001.png, clip-002.png and so on, in time order, so they sort correctly in any file manager. PNG is the only output format here. For a single frame in PNG or JPEG, use Video thumbnail instead.
Why is there a maxFrames cap at all?
So a long video cannot silently produce thousands of files. Sampling an hour long recording once a second would mean 3600 PNGs built in your browser memory at the same time. The cap stops early instead, and you can raise it deliberately when you know what you are asking for.
Why did it say my video is shorter than the interval?
Because no sample time fell inside the file. The tool builds the list of timestamps by stepping from zero to the video duration by intervalSec, and if that list is empty it refuses with the duration and the interval both named. Lower intervalSec so that at least one sample lands inside the clip.
Why will it not run on the command line?
Because decoding frames needs WebCodecs, which Node does not implement. The CLI and MCP surfaces refuse it with "video-extract-frames needs a browser (OffscreenCanvas). Use it at /video/video-extract-frames instead." The web page runs the same code in a Web Worker. Everything still stays on your device, since that worker runs inside the page you have open.
Is my video uploaded?
No. The file is decoded in your own tab and the PNGs are built there too. Nothing reaches a server. Both the source video and every extracted frame are held in memory at once, so a long video with a high maxFrames is the case most likely to run a tab out of room.