The problem: you asked for the frame at 3.1 seconds, you got the frame at 2.4 seconds
A video is a sequence of frames. To extract one, you ask the decoder for the frame at a specific timestamp, the decoder seeks to that timestamp, and you capture what it shows you. The catch is in the seek. Browsers do not seek to the exact frame you asked for. They seek to the nearest keyframe before the requested timestamp, decode forward from there, and display whatever frame they land on.
A keyframe is a full image stored in the video. The frames between keyframes are stored as diffs — only the pixels that changed. For a video with keyframes every 2 seconds (a common setting for web video), a request for the frame at 3.1 seconds seeks to the keyframe at 2.0 seconds, decodes through the next 1.1 seconds of diffs, and lands on the frame at 3.1. That is the happy case. For a request at 1.9 seconds on the same video, the decoder might seek to the keyframe at 0.0, decode forward through 1.9 seconds, and land correctly — or it might round to the keyframe at 2.0 and give you a frame from the future. The behavior is browser-dependent and codec-dependent, and no browser exposes a "seek to the exact frame" option through the video element.
The consequence is that browser-based frame extractors are not frame-accurate. They are timestamp-accurate to within a keyframe interval, which is usually within a second or two. For most uses — a thumbnail, a still for a blog post, a frame to print — that is fine. For uses that need a specific frame — a sports play, a scientific measurement, a stop-motion source — it is not fine, and you need a different tool.
The Video Frame Extractor uses the canvas-capture approach: a hidden video element, a seek, a draw to canvas, an export to PNG or JPEG. It runs in your browser, handles files up to the memory limit, and is capped at 50 frames per session. It is the right tool for thumbnails, summaries, and rough grabs. It is the wrong tool for anything that needs frame accuracy.
Fastest path
Open the Video Frame Extractor. Drag a video onto the dropzone, or click to pick a file. Pick an extraction mode (interval, timestamps, or nth-frame). Set the interval in seconds, or type a comma-separated list of timestamps, or set the frame skip. Pick PNG or JPEG, and the JPEG quality if relevant. Click Extract. The tool captures up to 50 frames and shows them in a grid. Click any frame to download it, or click Download All as ZIP.
The three extraction strategies, and when each is right
The three modes are not interchangeable. Each solves a different problem.
Interval mode captures a frame every N seconds. It is the right choice for a time-lapse summary, a contact sheet, or a storyboard view of the whole video. Set the interval to whatever spread you want — 1 second for a fast summary, 10 seconds for a slow one. The output is evenly spaced across the duration, which is what makes it useful for getting a sense of what is in the video without watching it. The weakness is that interesting moments are averaged out — a 3-second event in a 30-second video with a 5-second interval might be missed entirely.
Timestamps mode captures frames at specific moments you name. It is the right choice when you know which frames you want — a speaker's gesture at 12.4 seconds, a title card at 1:30, a product reveal at 3:05. Type the timestamps as a comma-separated list. The tool parses the list, drops any timestamps outside the video duration, and captures each one. The weakness is that you have to know the timestamps in advance, which usually means watching the video first and noting them down.
Nth-frame mode captures every Nth frame of the video. It is the right choice for stop-motion analysis, for building a flipbook, or for sampling the video at a uniform frame rate. The catch is the fps assumption. The tool takes a frame number, divides by 30, and seeks to that timestamp. If the video is 30fps, this is correct. If the video is 24, 25, 60, or 120 fps, the timestamps are wrong — a 60fps video will yield half the frames you asked for, and a 24fps video will yield more than you asked for. Most web video is 30fps, but cinema is 24, European broadcast is 25, and modern phones shoot 60 or 120. Check the frame rate before using nth-frame mode.
Why the 30fps assumption is wrong for most cinema and phone video
The nth-frame mode uses a hard-coded 30fps to convert frame numbers to timestamps. The math is timestamp = frameNumber / 30. For a 30fps video, requesting every 30th frame gives you one frame per second — correct. For a 60fps video, the same request gives you one frame every 0.5 seconds — you get twice the frames you expected, but at the wrong interval. For a 24fps cinema video, every 30th frame gives you one frame every 1.25 seconds — you get fewer frames than you expected.
The browser does not expose the video's frame rate through the video element reliably. The requestVideoFrameCallback API gives you per-frame metadata including the present timestamp, but most extractors do not use it. The fix for nth-frame mode is to know your video's frame rate and divide the frame skip by that rate to get the right interval. For a 24fps video where you want every 24th frame (one per second), set the nth-frame slider to 24 and accept that the displayed "every X seconds" hint will be wrong — the tool will still seek to the timestamps it computes, and those will be at one-second intervals for a 24fps video.
If the frame rate matters and the tool does not detect it, use ffmpeg. The ffprobe command reports the frame rate exactly, and ffmpeg -i input.mp4 -vf "select='not(mod(n,24))'" selects every 24th frame with frame accuracy regardless of the video's frame rate.
PNG vs JPEG, and why it matters for frames
The choice between PNG and JPEG for frame extraction is not about quality in the abstract — it is about what is in the frame.
PNG is lossless. Every pixel is preserved exactly. The file is larger, but the frame is identical to what the decoder produced. PNG is the right choice for frames with text, sharp lines, flat colors, or anything where compression artifacts would be visible — a title card, a screen recording, a chart, a logo. PNG also supports transparency, which JPEG does not, though extracted video frames are unlikely to have an alpha channel.
JPEG is lossy. It compresses by discarding high-frequency detail that the eye is less sensitive to, and it introduces block artifacts around sharp edges at any quality setting. The file is 5 to 10 times smaller than PNG at a quality the eye cannot distinguish from the source. JPEG is the right choice for frames with gradients, photographs, or natural video — a landscape, a face, a frame from a movie. The quality slider on the tool maps to the JPEG quality setting; 0.85 is a reasonable default that produces files 5 to 8 times smaller than PNG with no visible degradation on most content.
The wrong choice is visible. A JPEG of a title card has block artifacts around the text that are obvious when you zoom in. A PNG of a sunset is 10 times larger than it needs to be. Match the format to the content.
The 50-frame cap, and what to do about it
The tool caps extraction at 50 frames per session. The cap is a memory limit. Each frame is held in two forms: a data URL for the preview thumbnail, and a blob for the download and the ZIP. A 1080p JPEG is 100 to 300 KB; 50 of them plus the blobs is 10 to 30 MB held in browser memory. Past that, the tab gets sluggish, the UI stutters, and eventually the browser kills the page for exceeding its memory budget.
For most uses, 50 frames is enough. A 2-minute video at 1 frame per second is 120 frames — too many. At 1 frame per 5 seconds, it is 24 frames — fine. A 30-minute video at 1 frame per 30 seconds is 60 frames — just over the cap. Adjust the interval to land under 50, and you stay within the cap.
For larger batches, use ffmpeg. The command ffmpeg -i input.mp4 -vf "fps=1" frame_%04d.png extracts one frame per second into a directory of PNGs, with no cap and no browser memory limit. For 1000 frames, ffmpeg finishes in seconds; the browser tool would crash. The browser tool is for browsing and grabbing a few frames; ffmpeg is for batch extraction.
The 5-second seek timeout, and what causes it
The tool waits up to 5 seconds for each seek to complete. If the seeked event does not fire within 5 seconds, the extraction aborts with a "frame extraction failed" error. The causes are usually one of three.
The video format is not supported by the browser. The dropzone says "MP4, WebM, MOV," but the actual support depends on the browser and the codec inside the container. Safari supports H.265 in MP4; Chrome does not. Chrome supports VP9 in WebM; Safari does not. AV1 is supported in latest Chrome and Firefox but not in older Safari. If the browser cannot decode the video, the seek never completes, and the timeout fires. Try a different format, or convert the video with ffmpeg or Handbrake first.
The video is very large or very long. A 4K video at 60 minutes has a lot of data to seek through. The browser's seek is not optimized for this; it can take longer than 5 seconds on a slow machine. The fix is to extract from a smaller proxy of the video, or to use ffmpeg.
The video has sparse keyframes. A video optimized for streaming might have keyframes only every 10 seconds. A seek to a timestamp far from any keyframe requires decoding a long run of diff frames, which takes time. The fix is the same — use a proxy or use ffmpeg.
If the timeout fires on a specific frame but not others, it is usually a sparse-keyframe issue at that timestamp. Skip that frame and try the next.
What the tool does not do
A browser-based frame extractor has a specific scope. It does not:
Detect the frame rate. The nth-frame mode assumes 30fps. For any other frame rate, the displayed interval is wrong and the extracted frames are at the wrong cadence.
Trim to a range. The tool always extracts across the entire video duration. There is no start or end control. To extract from a specific range, set the timestamps manually, or trim the video first with ffmpeg (ffmpeg -i input.mp4 -ss 00:01:00 -to 00:02:00 -c copy cut.mp4).
Resize or crop. Frames are captured at the video's native resolution and aspect ratio. A 4K video yields 4K frames. To resize, use the Image Resizer on the extracted frames, or use ffmpeg with the -vf scale=1280:-1 filter.
Produce a GIF or a contact sheet. The output is individual frames or a ZIP of frames. To make a GIF, use the Video to GIF Converter. To make a contact sheet, use ffmpeg with the tile filter or a dedicated tool.
Handle audio. The tool extracts video frames only. Audio is ignored entirely. To extract audio, use ffmpeg (ffmpeg -i input.mp4 -vn audio.mp3).
Be frame-accurate. The canvas-capture approach is timestamp-accurate to within a keyframe interval. For frame accuracy, use ffmpeg or the WebCodecs API.
Gotchas
- The result is not frame-accurate. The browser's video element seeks to the nearest keyframe, not the exact frame. For a video with 2-second keyframes, a request for the frame at 3.1 seconds lands somewhere between 2 and 4. For thumbnails and summaries, this is fine. For sports, science, or stop-motion, it is not. Use ffmpeg for frame accuracy.
- The nth-frame mode assumes 30fps. The displayed "every X seconds" hint and the actual seek timestamps are computed with a hard-coded 30fps. For 24, 25, 60, or 120fps video, the cadence is wrong. Check the frame rate (with ffprobe, or by checking the file metadata) before using nth-frame mode.
- Timestamps outside the duration are silently dropped. If you type
100on a 30-second video, the timestamp is discarded with no warning. The "Will extract" badge shows the reduced count, but nothing tells you a value was invalid. Check the badge against your input length. - PNG is lossless, JPEG is lossy. Match the format to the content. PNG for text, lines, flat colors, and anything where compression artifacts would be visible. JPEG for photographs, gradients, and natural video. The wrong choice is visible up close.
- The 50-frame cap is a memory limit. Each frame is held as both a data URL and a blob; 50 frames at 1080p is tens of megabytes. Past that, the tab gets sluggish. Adjust the interval to land under 50, or use ffmpeg for larger batches.
- No file-type validation. The dropzone says "MP4, WebM, MOV," but any file is accepted. If the browser cannot decode it, the duration never appears and extraction fails silently. Try a different format, or convert with ffmpeg first.
- No start or end trim. The tool always extracts across the entire video. To extract from a range, set timestamps manually, or trim the video first.
- No resize or crop. Frames are captured at native resolution. A 4K video yields 4K frames, which are large and slow to handle. Resize the frames afterward with an image tool, or use ffmpeg with a scale filter.
- ZIP entry names use the frame index, not the timestamp. Per-frame downloads include the timestamp in the filename; ZIP entries do not. Re-running with a different mode overwrites identically-named ZIP entries if you do not rename the file first.
- The 5-second seek timeout aborts on large or sparse-keyframe videos. If extraction fails on a specific frame, it is usually a sparse-keyframe issue. Skip the frame, use a proxy, or use ffmpeg.
Summary
- Browser-based frame extraction is not frame-accurate. The video element seeks to the nearest keyframe, not the exact frame. For thumbnails and summaries, this is fine. For sports, science, or stop-motion, use ffmpeg, which decodes to the exact frame.
- The three extraction strategies are interval (every N seconds, for a time-lapse summary), timestamps (specific moments you name, for known frames), and nth-frame (every Nth frame, for stop-motion or uniform sampling). The nth-frame mode assumes 30fps, which is wrong for 24, 25, 60, or 120fps video. Check the frame rate before using it.
- PNG is lossless and right for text, lines, and flat colors. JPEG is lossy and 5 to 10 times smaller, right for photographs and gradients. The wrong choice is visible. The quality slider maps to JPEG quality; 0.85 is a reasonable default.
- The 50-frame cap is a memory limit. Each frame is held as both a data URL and a blob; 50 frames at 1080p is tens of megabytes. Adjust the interval to land under 50, or use ffmpeg for larger batches (
ffmpeg -i input.mp4 -vf "fps=1" frame_%04d.png). - The Video Frame Extractor runs in your browser, supports interval, timestamp, and nth-frame modes, and outputs PNG or JPEG. It does not detect frame rate, trim to a range, resize, produce a GIF, handle audio, or be frame-accurate. For those, use ffmpeg. Use the Video to GIF Converter for animated output, the Audio Compressor for the audio track, and the Image Resizer to resize the extracted frames.