Video Frame Extractor
This extractor reads every frame's timestamp from the video file itself before it decodes a single picture, so each time you ask for is matched to a frame the video really contains, and the page shows which frame that is and how many milliseconds away before you extract anything. A request goes to the nearest frame start, a tie to the earlier frame, and nothing is made up between two frames. You can take a frame at a steady interval between two points, spread a number of frames evenly across the video, or type the exact times you want, and Add this moment types the preview's current time for you. Frames come out as JPEG at quality 90 or as lossless PNG, at the video's full display size and the right way up, in a ZIP with a manifest that lists, for every request, the frame number, the time asked, the time decoded and the shift between them. A contact sheet puts every frame on one labelled PNG. Everything runs in your browser tab with your browser's own video decoder, for files up to 250 MB and up to 300 requested times a run, and nothing is uploaded.
Open a video to take frames from
· or drop one anywhere on the stage
- Take
- everys froms to
- Format
- Frames
- none yet
- Largest shift
- none yet
- Source
- no video open
Ready. Choose a video, or drop one on the stage.
Before anything is decoded, the page lists every frame's timestamp from the video file itself, so each requested time can be matched to a real frame and the shift shown. Every takes one time per interval from the start you give, up to the end, which is where the last frame stops and is never itself a frame. Spread puts each time in the middle of an equal slice of the video. At times takes the times you type, as seconds (12.5) or minutes and seconds (1:02.5), separated by commas or spaces, and sorts them into playing order; Add this moment pauses the preview and types its time for you. Each request goes to the nearest frame start, a tie to the earlier frame, and the manifest keeps both times. JPEG is written at quality 90, PNG without loss, both at the video's full display size and the right way up. The ZIP holds the frames and manifest.csv; the contact sheet is one PNG with every frame labelled.
Common questions
- How do I extract a frame from a video at a specific time?
- Open the video, choose At times, and type the time as seconds, such as 62.5, or as minutes and seconds, such as 1:02.5. Several times can go in the same box, separated by commas or spaces, and they are sorted into playing order. You can also play the preview, and at the moment you want press Add this moment, which pauses it and types its time into the box. The stage then shows which frame each time lands on before anything is decoded. Press Extract frames, and download the ZIP, the CSV or the contact sheet.
- Why is the actual time different from the time I asked for?
- A video is a run of still frames at fixed moments, so most times fall between two of them: at 30 frames a second they are 33.3 ms apart. Each requested time is matched to the nearest frame start, and a time exactly halfway between two frames goes to the earlier one. In a 29.97 fps video, asking for 20 s gives frame 600 at 19.987 s, 13 ms early, because the next frame starts at 20.020 s, 20 ms late. The manifest lists the time you asked for and the frame's own time side by side, so you always know which one you got, and nothing is blended or invented between two frames.
- How do I extract one frame every second, or every few seconds?
- Choose Every, type the interval in seconds, and if you like a From and a To. The requests are the start time plus each whole interval, and they stop before the end of the video, which is where the last frame stops being shown and is never itself a frame: every 1 s over a 3 second clip gives 0, 1 and 2 s. A run takes up to 300 requests. If an interval would need more, the message says how many it would be and names an interval that fits, with a button that applies it: every 0.1 s over a 48.048 s video is 481 requests, and every 0.161 s fits. Spread is the other way to cover a whole video: it puts each of the number of frames you ask for in the middle of an equal slice.
- What is in the ZIP and the CSV manifest?
- The ZIP holds one image per distinct frame and a file called manifest.csv. Each image is named after its frame number in the video, padded to at least four digits, such as frame-0301.jpg, so a folder sorts into playing order. The manifest has one row for every request, with the columns frame, requested_s, actual_s, shift_ms and file, times to the millisecond and the shift to a tenth of a millisecond. Two requests that land on the same frame get two rows that point at one image. The same CSV can be downloaded on its own or copied, and the contact sheet is a separate download.
- What is the contact sheet?
- One PNG with every extracted frame laid out in a grid on a white page, each tile labelled with its frame number, its decoded time and the time you asked for. The header gives the file name, the picture size and the frame rate. Tiles keep the video's shape and are never drawn larger than the frame itself; with many frames they shrink so the whole sheet stays within 16,777,216 pixels, the area of a 4096 x 4096 canvas, and 16,384 pixels a side, a size every current browser can draw and save. A video so tall and narrow that even 1 pixel wide tiles would not fit gets no sheet, and the page says so; the frames and the CSV are still made. It is useful as a storyboard, for picking a thumbnail, or for checking a clip at a glance.
- Does it work with phone videos and a variable frame rate?
- Yes. The frame times are read from the file rather than worked out from a frame rate, so when a phone records frames unevenly the actual times in the manifest are uneven too, and the source line says the rate is variable and how far apart the frames are. The rows still rise in playing order. A phone that stores a portrait video on its side marks which way to turn it, and each frame is turned upright before it is saved, at the size the video is shown.
- Is my video uploaded anywhere?
- No. The file is read in this tab, the frames are decoded by the WebCodecs decoder built into your browser, and the images, the ZIP and the contact sheet are made here and handed to your browser's download. Nothing is sent to a server and no account is needed. The page remembers only its own settings in this browser: the mode, the interval, From and To, the number of frames, the typed times and the format. The Start over button at the top of the page forgets them. The video itself is never stored.
- Which video files and codecs does it read?
- MP4, MOV, WebM, MKV and MPEG-TS files up to 250 MB, as long as your browser can decode the video inside them. The container is recognised from the file's first bytes rather than its name, so an AVI, FLV, WMV or MPEG program stream is refused straight away with a message naming it, and an animated GIF is pointed to the GIF Frame Extractor. The codec is then checked with your browser before any frame is listed. H.264 and VP9 decode in current versions of the major browsers, while whether HEVC, which many phones record, can be decoded depends on the browser and the computer; if yours cannot, the page names the codec and says so.
- Should I choose JPEG or PNG?
- JPEG is written at quality 90: the files are much smaller and usually look the same to the eye, which suits thumbnails, storyboards and sharing. PNG is lossless, so the picture is saved without any further compression loss, at the cost of larger files; it suits analysis, editing and anything you will compress again later. Both are saved at the video's full display size.
Each requested time is matched to the nearest frame the video actually contains, a tie going to the earlier one, and the manifest gives both the requested time and the decoded frame's own time to the millisecond, so nothing is invented between two frames and a variable frame rate shows as uneven times. Frames are exported at full size in the video's display orientation, and two requests that land on one frame export it once. Which codecs can be decoded depends on your browser, an unsupported one is refused before extraction, and videos up to 250 MB and 300 requested times a run are read on your device and never uploaded.