Video Frame Extractor: Keyframes & Thumbnails
Pricing
from $1.50 / 1,000 frames
Video Frame Extractor: Keyframes & Thumbnails
Extract frames from video files, uploads and video podcast feeds: a set number, one every N seconds, scene changes, keyframes or listed times, plus a contact sheet. Skips blank and repeated frames. JPG, PNG or WebP with links. Pay per frame stored.
Pricing
from $1.50 / 1,000 frames
Rating
0.0
(0)
Developer
Enis Bodlli
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Turn videos into images: a set number of frames, one every few seconds, a frame at each scene change, the video's own keyframes, or frames at the times you list, plus an optional contact sheet that shows the whole video on one image. Give it links to video files, web pages that embed a video, video podcast RSS feeds, or upload your own files. Every frame comes back as a JPG, PNG or WebP with a link and its exact timestamp. It is built for people who make thumbnails and previews, teams that feed video into AI vision models, researchers who code footage, and AI agents that need to see what is in a video.
- Only useful frames, and only those are charged. Black, white and faded frames, and frames that repeat the one before (a slide that stays on screen), are skipped for free.
- Scenes with their scores, or keyframes for speed. Scene mode gives each cut's strength; keyframe mode reads a long video in a fraction of the time.
- Pay per frame, $2 per 1,000 frames ($1.50 on Gold), with nothing to pay for failed links, skipped frames or platform usage.
The easiest way to try it: keep the example input and press Start. You get up to six frames and a contact sheet from each of two short films in about 10 seconds.
What you get for each frame
{"status": "extracted","type": "frame","videoUrl": "https://media.w3.org/2010/05/sintel/trailer.mp4","videoTitle": "trailer.mp4","mode": "count","frameIndex": 1,"timestampSeconds": 4.375,"timecode": "00:00:04.375","imageUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/frame-aed5bc55391c5011-00001.jpg","imageWidth": 854,"imageHeight": 480,"contactSheetUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/contact-sheet-aed5bc55391c5011.jpg","durationSeconds": 52.208,"fps": 24,"videoCodec": "h264","billedCount": 1}
What you can do with it
- Thumbnails and preview strips for a video library, a course or a podcast's video episodes.
- Frames for AI vision models: send the frames to GPT, Claude or Gemini to describe, tag, moderate or search what is in a video, without sending the whole file.
- Scene and shot lists for editing, research or archive work, with a timecode per cut.
- Slide capture from recorded talks and webinars: one image per slide, repeats left out.
- Training data for computer vision: frames at a fixed rate, at the size and format you need.
- A new video podcast episode, as pictures: point it at the feed and schedule it.
How to use it
- Paste one or more links in Video links, or upload files in Upload video files. A direct file link (MP4, MOV, WEBM, MKV, AVI, FLV, MPEG-TS and more), a page that embeds a video file, and a video podcast RSS or Atom feed all work.
- Choose How frames are chosen:
count: a set number of frames spread evenly over the video (default 10).interval: one frame every few seconds, from 0.1 s upwards.scenes: a frame at each cut or scene change, with its score; lower Scene change sensitivity finds softer cuts.keyframes: the frames the video was encoded around, the fastest way through a long video.timestamps: frames at the times you list, as seconds (90), clock times (1:30) or a share of the video (50%).
- Optionally set Start at and End at to work on part of each video, a Maximum width, the Image format and quality, and switch on Make a contact sheet.
- Press Start. Frames appear in the dataset as they are stored; open the Overview tab to see them as images, or download the dataset as JSON, CSV or Excel.
How long it takes
Measured on Apify at the default 512 MB on 2026-10-20, with a 10-minute 720p film:
| What | Images | Time |
|---|---|---|
| One frame every 10 seconds | 56 | 10 s |
| Scene changes, with a contact sheet | 123 | 17 s |
| One frame every 0.6 seconds | 784 | 2 min 17 s |
Each video is downloaded once, so a large file adds its download time. Videos are processed one after another; more memory gives the run more CPU, which shortens long videos.
Pricing
You pay per image stored, a frame or a contact sheet, plus Apify's run start of $0.00005 per GB of memory ($0.00005 at the default 512 MB). Platform usage is included, so there is nothing else to pay.
| Apify plan tier | Per frame | Per 1,000 frames |
|---|---|---|
| Free, Bronze | $0.002 | $2.00 |
| Silver | $0.00176 | $1.76 |
| Gold and above | $0.0015 | $1.50 |
Worked examples at the Free and Bronze price:
- The example input, 11 frames and 2 contact sheets: 13 x $0.002 = $0.026.
- 1,000 frames: $2.00, or $1.76 on Silver and $1.50 on Gold.
- One frame every 10 seconds from an hour of video: 360 frames, $0.72.
- Ten thumbnails and a contact sheet for each of 100 videos: 1,100 images, $2.20.
- A blank or repeated frame, a link that fails, or a video with no usable frame: nothing.
On the Apify free plan, the monthly $5 of credit pays for about 2,500 frames.
Maximum frames per video caps what each video can cost, and you can set a maximum charge per run: the Actor then stores only as many frames as that amount pays for, keeps a place for the contact sheet, and finishes as succeeded with a message that says the limit stopped it. A run that Apify restarts on another server carries on where it stopped and charges no frame twice.
Input
{"videoUrls": ["https://media.w3.org/2010/05/sintel/trailer.mp4","https://feeds.twit.tv/twit_video_hd.xml"],"maxVideosPerFeed": 1,"mode": "scenes","sceneThreshold": 0.3,"maxFramesPerVideo": 50,"startTime": "0:30","imageFormat": "webp","maxWidth": 1280,"contactSheet": true,"contactSheetColumns": 5}
| Field | What it does | Default |
|---|---|---|
videoUrls | Links to video files, pages that embed one, or video podcast feeds | example films |
videoFiles | Uploaded files, or links to records in an Apify key-value store | none |
maxVideosPerFeed | How many of a feed's newest videos are processed | 3 |
mode | count, interval, scenes, keyframes or timestamps | count |
frameCount | Frames per video in count mode | 10 |
intervalSeconds | Seconds between frames in interval mode | 10 |
sceneThreshold | Scene change sensitivity, 0.01 to 0.99 | 0.3 |
timestamps | Times for timestamps mode | none |
maxFramesPerVideo | At most this many frames per video in interval, scenes and keyframes | 100 |
startTime, endTime | The part of each video to work on | whole video |
skipBlankFrames | Leave out black, white and faded frames, free | on |
skipDuplicateFrames | Leave out a frame that looks the same as the last one kept, free | on |
imageFormat | jpg, png or webp | jpg |
maxWidth | Scale wider frames down to this width; 0 keeps the video's size | 1280 |
imageQuality | JPG and WebP quality, 1 to 100 | 85 |
contactSheet | One grid image per video with every frame and its time | off |
contactSheetColumns | Frames per row on the contact sheet | 4 |
Output
One dataset row per image: type is frame or contact-sheet. Every row also carries the video's
duration, size, frame rate, codec and whether it has sound, and for a feed the feed's and episode's
title and date. A link that fails gives one row with status failed and the reason.
[{"status": "extracted","type": "frame","inputUrl": "https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_1MB.mp4","sourceType": "file","videoIndex": 2,"videoTitle": "Big_Buck_Bunny_360_10s_1MB.mp4","mode": "count","frameIndex": 3,"timestampSeconds": 4.167,"timecode": "00:00:04.167","sceneScore": null,"imageUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/frame-822a3b8b2647449b-00003.jpg","imageKey": "frame-822a3b8b2647449b-00003.jpg","imageFormat": "jpg","imageWidth": 640,"imageHeight": 360,"imageBytes": 37086,"framesInVideo": 6,"durationSeconds": 10,"width": 640,"height": 360,"fps": 30,"videoCodec": "h264","hasAudio": false,"billedEvent": "frame","billedCount": 1,"error": null,"errorKind": null},{"status": "extracted","type": "contact-sheet","videoIndex": 2,"videoTitle": "Big_Buck_Bunny_360_10s_1MB.mp4","imageUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/contact-sheet-822a3b8b2647449b.jpg","imageWidth": 1308,"imageHeight": 380,"framesInVideo": 6,"billedEvent": "frame","billedCount": 1},{"status": "failed","type": null,"inputUrl": "https://www.youtube.com/watch?v=abc","imageUrl": null,"billedCount": 0,"error": "YouTube links are not supported: this Actor takes frames from video files, web pages that embed a video file, and video podcast feeds. Use a direct link to a video file you may use, or upload it in \"videoFiles\".","errorKind": "unsupported-platform"}]
The images themselves are in the run's key-value store, named frame-<video>-<number> and
contact-sheet-<video>. The RUN_SUMMARY record there counts the videos, frames stored, frames
skipped as blank or repeated, failed inputs and what was charged.
Limits
- No YouTube, TikTok, Instagram, Vimeo, Facebook, X or other platform pages, and no Google
Drive or Dropbox share pages. Those links fail with
unsupported-platformbefore any download and cost nothing. Use a direct link to a file you may use, or upload it. - No streaming playlists. HLS (
.m3u8) and DASH (.mpd) streams are not read; a page whose only video is a stream fails withnot-mediaand costs nothing. - Only videos that open without a login. Private, members-only and paywalled videos are not supported.
- File size follows memory. Up to about 600 MB per video at the default 512 MB, 1.2 GB at 1 GB, and more with more memory.
countmode can return fewer frames than asked. A frame that falls on a blank or repeated picture is skipped, not replaced, so the frames stay evenly spread. Theinterval,scenesandkeyframesmodes read on past skipped frames to reach their maximum.- The whole file is downloaded, even when only part of it is used.
- No text recognition, captions or AI descriptions. The Actor returns images and timestamps; send the images to the model of your choice.
FAQ
Is it legal to extract frames from a video?
The Actor reads only public files, pages and feeds that open without a login, and it does not get around any blocking. Copyright in a video stays with its owner: frames for analysis, research, search, previews of your own videos or quoting are common, while republishing someone else's frames can need permission. Check the terms of the source and the laws that apply to you; this is not legal advice.
Why did a link fail?
The error field says why in plain words and errorKind gives the cause. The usual ones: the link
is a platform page (unsupported-platform), the server answered 404 (not-found) or refused the
download (refused), the link is an image, text or a page without a video file (not-media), the
file is audio only (no-video), or the file is over the size limit (too-large). A failed link is
never charged, and the other links in the run carry on.
Why did I get fewer frames than I asked for?
Blank and repeated frames are skipped for free. A video that is mostly black, a still image or a
slide that stays on screen gives fewer frames; switch off Skip blank frames or Skip repeated
frames to keep them all. In scenes mode, a calm video has few cuts: lower the sensitivity.
Which mode is fastest for a long video?
keyframes decodes only the keyframes, and count or interval with frames 15 seconds or more
apart jumps straight to each time. scenes and dense interval runs read every frame of the
chosen range.
Can I use the frames with an AI model?
Yes. Each imageUrl opens without an Apify login, so you can pass it straight to a vision model,
or run the Actor from an AI agent through the Apify MCP server and read the dataset back.
Can I use it through the API or on a schedule?
Yes. Start it through the Apify API, the Python or JavaScript client, Make, Zapier or n8n, and save an input as a task to run it on a schedule. Every result has the same fields.
More Actors from this developer
- Podcast & Audio Transcriber: podcasts, MP3s and videos to text with Whisper, with timed segments and subtitles.
- ATS Job Postings: Workday, Greenhouse, Lever & Ashby: every open job of the companies you choose.
- Website Contact Scraper: emails, phones and social profiles from company websites.
- Email Validator & List Cleaner: syntax and domain checks for a mailing list.
- Handelsregister Scraper and European Company Registry Search: company records from official registers.