Video Frame Extractor — Thumbnails & Stills from Any Video
Pricing
from $1.50 / 1,000 frame extracteds
Video Frame Extractor — Thumbnails & Stills from Any Video
Extract frames and thumbnails from any direct video file URL (MP4, WebM, MOV, MKV) with ffmpeg running inside the Actor. Evenly spaced frames, one every N seconds, or exact timestamps; JPG, PNG or WebP, optional resize. $1.50 per 1,000 frames; failed files are free.
Pricing
from $1.50 / 1,000 frame extracteds
Rating
0.0
(0)
Developer
KeyMan98
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Video Frame & Thumbnail Extractor
Pull frames or thumbnails out of any video file you can link to directly — pick a fixed number of equally spaced frames, one frame every X seconds, or exact timestamps you choose. Extraction runs with ffmpeg inside this Actor's own container: no third-party video API, no watching the video yourself to grab a screenshot.
What you get (output fields)
One dataset row per extracted frame:
videoUrl— the video URL you requested.frameIndex— 0-based index of this frame among the frames requested for that video.timestampSec— the timestamp (in seconds) this frame was taken at.imageUrl— public link to the extracted frame image in the key-value store.format—jpg,png, orwebp, whichever you asked for.width/height— pixel size of the saved frame, after resizing if you set one.sizeBytes— size of the saved frame file.videoDurationSec/videoWidth/videoHeight/videoCodec— the source video's own metadata, from ffprobe, repeated on every row from that video.error— null on success, or a message explaining why this frame (or the whole video) failed.
Who it's for
- Anyone who needs a thumbnail for a video they host themselves (a product demo, a webinar recording, a CCTV clip) without opening a video editor.
- Developers building a pipeline that needs frames for a preview grid, a content moderation check, or a computer-vision step, without standing up ffmpeg themselves.
- Anyone who wants a specific still moment from a video — "the frame at 1:32:07" — without downloading and scrubbing the whole file by hand.
What this Actor is not
It only reads a direct link to a video file. Give it a URL that, when fetched, returns video bytes (.mp4, .webm, .mov, .mkv, and anything else ffmpeg can demux) — not a page that merely embeds or links to one. It does not log into YouTube, Vimeo, TikTok, Instagram, or any other video platform to pull a stream out of a player page, and it never will: those platforms' own terms restrict scraping their video streams, and this Actor deliberately stays out of that. If you point it at a web page instead of a file, you get a clear, free error row telling you so — see "If a video or frame fails" below.
How to use
- List your video URLs — direct links to
.mp4,.webm,.mov,.mkv, or any other ffmpeg-readable container. - Pick a mode:
count(default) — N frames spread evenly across the video (set Frame count, default 5).interval— one frame every X seconds, starting at 0 (set Interval seconds).timestamps— frames at exact seconds you list (set Timestamps, e.g.[0, 12.5, 30]).
- Run the Actor. Each frame becomes one row with a link to the saved image.
- Optionally set Output format (JPEG/PNG/WebP), Quality, a Resize width (aspect ratio kept automatically), Max frames per video (a hard cap regardless of mode), and Max video size (skip anything bigger, as a free error row).
Input example (JSON)
{"videoUrls": ["https://example.com/my-video.mp4"],"mode": "interval","intervalSeconds": 10,"outputFormat": "jpg","jpegQuality": 85,"maxFramesPerVideo": 50}
Output example (JSON)
{"videoUrl": "https://example.com/my-video.mp4","frameIndex": 2,"timestampSec": 20.0,"imageUrl": "https://api.apify.com/v2/key-value-stores/.../records/....jpg","format": "jpg","width": 1920,"height": 1080,"sizeBytes": 184213,"videoDurationSec": 83.87,"videoWidth": 1920,"videoHeight": 1080,"videoCodec": "vp9","error": null}
If a video or frame fails
- A video that can't be downloaded, isn't reachable within the time/size limits, or turns out to be an HTML page instead of a video file gets one error row (
frameIndex/timestampSec/imageUrlnull) — the rest of your list still runs. - A video that downloads fine but ffprobe can't find a video stream in it (corrupted file, audio-only file, unsupported container) also gets one error row, with a message pointing you back at "use a direct video file URL".
- In
timestampsmode, a value past the end of the video is skipped with its own error row (videoDurationSectells you how long the video actually is). - If ffmpeg itself fails to extract one specific timestamp (rare — usually a badly corrupted section of an otherwise fine video), only that frame gets an error row; the rest of the video's frames are unaffected.
No row with error set is ever charged.
Pricing
Pay only for frames actually extracted and saved — nothing charged for a failed video, a skipped out-of-range timestamp, or a frame ffmpeg couldn't produce. Pricing model: pay-per-event.
| Event | When it's charged | Price |
|---|---|---|
frame-extracted | a frame was successfully extracted and saved | 0.0015 USD |
Limitations
- Direct video file links only. No YouTube/Vimeo/TikTok/social-platform pages, no HLS/DASH streaming manifests — a URL that returns a
.m3u8or.mpdplaylist instead of a single video file will fail to probe and come back as an error row. - Seeking is fast, not frame-exact. This Actor seeks with
ffmpeg -ssbefore-i(input seeking), which jumps to the nearest keyframe instead of decoding the whole video up to that point — much faster for videos with many requested frames, but the frame you get back can land a little off the exact timestamp you asked for on a video with sparse keyframes (long GOPs). Frame-exact seeking would mean decoding from the start every time, which does not scale tomaxFramesPerVideoup to 500. maxFramesPerVideoandmaxVideoSizeMbare hard cutoffs, not smart sampling: a 3-hour video with the default 50-frame cap incountmode still only returns 50 frames, spread across the whole 3 hours.- No audio, no scene detection, no deduplication. This Actor pulls frames at the timestamps you ask for — it does not detect scene changes, skip near-identical frames, or read audio at all.
- Very large videos take proportionally longer to download and probe;
maxVideoSizeMb(default 500 MB) exists precisely to keep run time predictable.
FAQ
Can it extract frames from YouTube, Vimeo, or TikTok?
No. This Actor only fetches a direct URL to a video file's bytes. It cannot log into or scrape any video platform's player — see "What this Actor is not" above.
What video formats are supported?
Anything ffmpeg can demux: MP4, WebM, MOV, MKV, AVI, and more. The format is detected by ffprobe from the file's actual content, not the URL's extension.
How much does it cost?
$0.0015 per frame actually extracted. A failed video, a skipped timestamp, or a frame ffmpeg couldn't produce costs nothing.
What happens if my timestamp is past the end of the video?
In timestamps mode, that timestamp is skipped and reported as a free error row telling you the video's actual duration. count and interval mode never generate an out-of-range timestamp in the first place.
Can I resize the frames?
Yes — set Resize width and every frame is scaled to that width, keeping the original aspect ratio (height computed automatically).
Why did I get an error row for my whole video instead of one per frame?
That happens for problems that affect the whole file, not one moment in it: the URL couldn't be downloaded, returned something that isn't a video (e.g. an HTML page), or ffprobe couldn't find a video stream in it at all.
Can I use this through the Apify API or an MCP server?
Yes, like any Apify Actor — through the standard Apify API, or through the Apify MCP server if you use Claude, Cursor, or another MCP-enabled client.
Default example video
The input's prefilled example video is "Launching the Future of Flight, The National Advisory Committee for Aeronautics (Prelude)" by NASA Ames Research Center, from Wikimedia Commons: commons.wikimedia.org/wiki/File:Launching_the_Future_of_Flight,_The_National_Advisory_Committee_for_Aeronautics_(Prelude)_(20250220-AAV3550-NACA-Series-Prelude-v1).webm — public domain (NASA work), no attribution required.
Export
Results can be downloaded from the Apify dataset as JSON, CSV, or Excel, or accessed via the Apify API.