Video Frame Extractor: YouTube, TikTok & MP4 to Images avatar

Video Frame Extractor: YouTube, TikTok & MP4 to Images

Pricing

from $1.39 / 1,000 frames

Go to Apify Store
Video Frame Extractor: YouTube, TikTok & MP4 to Images

Video Frame Extractor: YouTube, TikTok & MP4 to Images

Extract frames from YouTube, TikTok, Instagram, Facebook, X and MP4 videos as JPG, PNG or WebP images: evenly spaced, every N seconds, at scene changes, keyframes or exact timestamps, plus contact sheets.

Pricing

from $1.39 / 1,000 frames

Rating

0.0

(0)

Developer

ParseBird

ParseBird

Maintained by Community

Actor stats

1

Bookmarked

6

Total users

1

Monthly active users

7 days ago

Last modified

Categories

Share

Video Frame Extractor

Video Frame Extractor turns YouTube, TikTok, Instagram, Facebook, X and MP4 videos into still images. Pick frames evenly spaced, every N seconds, at each scene change, at the video's keyframes or at exact timestamps, and get them as JPG, PNG or WebP files with a link and timestamp for every frame.

Paste up to 100 video links, choose how frames are picked, and download the images from Apify storage, with an optional contact sheet per video. No video download, no software to install: only the parts of the video needed for each frame are fetched.

Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

Use the Apify Actor "parsebird/video-frame-extractor" (call it via ApifyClient) to extract still frames from videos as images. Example (JavaScript): const { ApifyClient } = require('apify-client'); const client = new ApifyClient({ token: '<APIFY_TOKEN>' }); const run = await client.actor('parsebird/video-frame-extractor').call({ videoUrls: ['https://www.youtube.com/watch?v=aqz-KE-bpKQ'], mode: 'scenes', maxFramesPerVideo: 30, contactSheet: true }); const { items } = await client.dataset(run.defaultDatasetId).listItems(); Inputs: videoUrls (required array of links: YouTube videos and Shorts, TikTok, Instagram reels/posts, Facebook videos/reels, X posts, other yt-dlp sites, direct MP4/WebM/MOV/M3U8 files; max 100), mode (string, default "count"; count/interval/scenes/keyframes/timestamps), frameCount (integer 1-1000, default 10, count mode), intervalSeconds (number >= 0.1, default 5, interval mode), sceneThreshold (number 0.01-0.99, default 0.3, scenes mode), timestamps (array of times like "90", "1:30", "00:01:30.250", "1m30s"; timestamps mode), startTime and endTime (strings like "30", "0:30", "1m"; not used in timestamps mode), outputFormat (jpg/png/webp, default jpg), maxWidth (integer px, default 1280, 0 = original), maxFramesPerVideo (integer 1-1000, default 100), contactSheet (boolean, default false), contactSheetColumns (integer 1-12, default 5), proxyMode (auto/none/datacenter/residential, default auto), maxDownloadMbPerVideo (integer MB, default 500, 0 = no limit). The dataset has two row types: recordType "frame" (videoUrl, videoTitle, videoId, platform, mode, frameIndex, timestampSec, timestamp, sceneScore, width, height, imageFormat, kvKey, frameUrl, durationSec, proxyUsed) and recordType "video" (status ok/failed/skipped, videoUrl, videoTitle, videoId, platform, mode, durationSec, framesExtracted, contactSheetUrl, transferredMb, minutesScanned, proxyUsed, error). Images are in the run's default key-value store under kvKey; frameUrl links to them. API docs: https://apify.com/parsebird/video-frame-extractor/api. Get a token at https://console.apify.com/settings/integrations.

What is Video Frame Extractor?

Video Frame Extractor is an Apify Actor that extracts frames from online videos and saves them as images. It works with YouTube (videos and Shorts), TikTok, Instagram reels and posts, Facebook videos and reels, X (Twitter) posts, many other sites supported by yt-dlp, and direct video files such as MP4, WebM, MOV and M3U8 (HLS) streams.

You don't need ffmpeg, a video editor or an API key. Paste links, pick a mode, click Start, and each frame lands in Apify storage with its timestamp and a download link. It's a quick way to make thumbnails, storyboards and image datasets from video, or to grab a screenshot from a YouTube video at an exact time.

What can Video Frame Extractor do?

  • 🎞️ Five extraction modes: a fixed number of frames, one frame every N seconds, one frame per shot change, the video's keyframes, or a list of exact timestamps.
  • 🌐 Many sources: YouTube, YouTube Shorts, TikTok, Instagram, Facebook, X, other yt-dlp sites and direct video links, mixed in one run (up to 100 links).
  • ⚡ Fetches only what it needs: for single frames it seeks inside the video instead of downloading it, and it uses the smallest stream that reaches your chosen width. HLS streams are cut to the one segment holding each frame.
  • 🖼️ JPG, PNG or WebP, scaled down to a maximum width (or kept at the original resolution).
  • 🗂️ Contact sheets: one grid image per video with up to 100 frames, each stamped with its timestamp.
  • ⏱️ Start and end times: limit any mode to part of the video, for example 1:00 to 5:00.
  • 🛡️ Proxy only when needed: Auto mode tries a direct connection first, then datacenter proxies, and uses a residential proxy only when a site blocks the others.
  • 🔌 Platform features: schedule runs, call the Actor from the Apify API, get webhooks when a run finishes, and connect it to Make, Zapier, n8n, Google Drive and more. Export the frame list as JSON, CSV, Excel or HTML.

Extraction modes

ModeWhat it doesGood for
CountN frames spread evenly; each one comes from the middle of an equal slice of the video, which avoids black lead-in and fade-out framesThumbnails, previews, quick visual summaries
IntervalOne frame every N seconds (every 5 s, or every 0.5 s)Image datasets, monitoring footage, step-by-step tutorials
ScenesThe opening frame plus one frame at each shot change, with a sensitivity threshold and a score per frameStoryboards, ad and trailer breakdowns, video indexing
KeyframesThe video's own keyframes (I-frames)Fast sampling that follows the encoder's own cuts
TimestampsThe exact times you list (90, 1:30, 00:02:15.5, 1m30s)Grabbing moments you already know

Every mode respects Max frames per video. In scenes mode the strongest scene changes are kept, in keyframes mode the keyframes are sampled evenly, and in interval mode the first frames are kept.

What data do you get?

Each frame is saved as an image in the run's key-value store, and the dataset gets one row per frame plus one summary row per video.

FieldDescription
recordTypeframe for a frame, video for a video summary
frameUrl, kvKeyLink to the image and its key in the key-value store
timestampSec, timestampWhere the frame is in the video, in seconds and as 00:01:08.200
frameIndexPosition of the frame within its video
sceneScoreHow strong the shot change was (scenes mode, 0–1)
width, height, imageFormatSize and format of the saved image
videoTitle, videoId, platform, durationSecThe source video
status, errorVideo row: ok, failed or skipped, and why
framesExtracted, contactSheetUrlVideo row: frame count and the contact sheet link
transferredMb, minutesScanned, proxyUsedVideo row: data fetched, minutes scanned in scenes mode, and the network route used

Filter on recordType to keep only frames when you export to CSV, Excel or Google Sheets.

How to extract frames from a video

  1. Open Video Frame Extractor in Apify Console and create a free Apify account if you don't have one.
  2. Paste one or more video links into Video URLs.
  3. Choose an Extraction mode and its setting, for example 10 frames, a 5-second interval or a scene sensitivity of 0.3.
  4. Optionally set a start and end time, the image format, the max width and a contact sheet.
  5. Click Start. When the run finishes, open the Output tab to see every frame, or open the key-value store to download the images.

Input examples

10 evenly spaced frames from a direct MP4

{
"videoUrls": ["https://media.w3.org/2010/05/sintel/trailer.mp4"],
"mode": "count",
"frameCount": 10
}

A storyboard of a YouTube video, with a contact sheet

{
"videoUrls": ["https://www.youtube.com/watch?v=aqz-KE-bpKQ"],
"mode": "scenes",
"sceneThreshold": 0.3,
"maxFramesPerVideo": 30,
"contactSheet": true
}

Two frames per second from part of a video, as WebP

{
"videoUrls": ["https://www.tiktok.com/@scout2015/video/6718335390845095173"],
"mode": "interval",
"intervalSeconds": 0.5,
"startTime": "0:02",
"endTime": "0:08",
"outputFormat": "webp"
}

Screenshots at exact times

{
"videoUrls": ["https://youtu.be/dQw4w9WgXcQ"],
"mode": "timestamps",
"timestamps": ["0:43", "1m30s", "00:02:15.500"],
"maxWidth": 0,
"outputFormat": "png"
}

Output example

Real rows from a keyframes run on Big Buck Bunny (YouTube, 1:00 to 2:00, October 17, 2026). A frame row:

{
"recordType": "frame",
"videoUrl": "https://www.youtube.com/watch?v=aqz-KE-bpKQ",
"videoTitle": "Big Buck Bunny 60fps 4K - Official Blender Foundation Short Film",
"videoId": "aqz-KE-bpKQ",
"platform": "youtube",
"mode": "keyframes",
"frameIndex": 4,
"timestampSec": 68.2,
"timestamp": "00:01:08.200",
"sceneScore": null,
"width": 1280,
"height": 720,
"imageFormat": "jpg",
"kvKey": "v1-aqz-KE-bpKQ-frame-0004.jpg",
"frameUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/v1-aqz-KE-bpKQ-frame-0004.jpg",
"durationSec": 635,
"proxyUsed": "residential"
}

The video summary row:

{
"recordType": "video",
"status": "ok",
"videoUrl": "https://www.youtube.com/watch?v=aqz-KE-bpKQ",
"videoTitle": "Big Buck Bunny 60fps 4K - Official Blender Foundation Short Film",
"videoId": "aqz-KE-bpKQ",
"platform": "youtube",
"mode": "keyframes",
"durationSec": 635,
"framesExtracted": 18,
"contactSheetUrl": null,
"transferredMb": 37.8,
"minutesScanned": 0,
"proxyUsed": "residential",
"error": null
}

Download the dataset in JSON, HTML, CSV or Excel from the Output tab, or set the input on the Input tab.

Use Video Frame Extractor from Python or JavaScript

Install the Apify client (pip install apify-client or npm install apify-client) and use your API token.

Python

from apify_client import ApifyClient
client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("parsebird/video-frame-extractor").call(run_input={
"videoUrls": ["https://www.youtube.com/watch?v=aqz-KE-bpKQ"],
"mode": "interval",
"intervalSeconds": 10,
"maxWidth": 640,
})
store = client.key_value_store(run["defaultKeyValueStoreId"])
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row["recordType"] == "frame":
image = store.get_record(row["kvKey"])["value"]
with open(row["kvKey"], "wb") as fh:
fh.write(image)
print(row["timestamp"], row["kvKey"])

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<APIFY_TOKEN>' });
const run = await client.actor('parsebird/video-frame-extractor').call({
videoUrls: ['https://www.tiktok.com/@scout2015/video/6718335390845095173'],
mode: 'count',
frameCount: 6,
contactSheet: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.filter((r) => r.recordType === 'frame').forEach((f) => console.log(f.timestamp, f.frameUrl));
console.log('Contact sheet:', items.find((r) => r.recordType === 'video')?.contactSheetUrl);

Use cases

  • Thumbnails and previews: pull a handful of clean frames from each video for a catalog, CMS or social post.
  • Storyboards and ad breakdowns: scenes mode gives one frame per shot of a trailer, commercial or music video.
  • Image datasets for AI: interval mode turns video into evenly spaced training or evaluation images, ready for captioning or labeling.
  • Visual search and indexing: store keyframes or scene frames next to a transcript to make a video library searchable.
  • Content review and moderation: check what appears in a batch of TikToks or Reels without watching each one.
  • Tutorials and documentation: grab the exact moments of a screen recording at the timestamps you already know.

How it works

The Actor reads each link with yt-dlp or, for Instagram and Facebook, with its own logged-out page reader, and picks the smallest video stream that is at least as wide as Max frame width. ffmpeg then seeks to each frame's time and decodes only from the nearest keyframe, so a frame usually needs one short piece of the video rather than the whole file. When frames are 3 seconds apart or closer, one pass through the chosen part of the video is cheaper and is used instead. Scenes and keyframes modes read the whole chosen time range at the lowest available quality, then fetch each selected frame at your chosen width.

How much does it cost to extract frames from a video?

Video Frame Extractor uses pay-per-event pricing. Platform usage (compute and storage) is included in the event prices; you only pay for the events below.

EventWhat it countsFreeBronzeSilverGold
FrameOne still frame saved as an image$0.00199$0.00179$0.00159$0.00139
Video processedEach video opened and processed$0.00999$0.00949$0.00899$0.00849
Minute scannedEach started minute of video scanned in scenes mode$0.00499$0.00479$0.00459$0.00439
Megabyte downloadedEach megabyte fetched through a residential proxy, when a site blocks the faster routes$0.049$0.047$0.045$0.043

Videos that fail, or that are skipped for going over the download limit, are not charged.

Examples on the Free plan:

  • 10 frames from one video over a direct or datacenter connection: $0.00999 + 10 × $0.00199 = about $0.03.
  • Scenes mode on a 10-minute video, 30 frames kept: $0.00999 + 10 × $0.00499 + 30 × $0.00199 = about $0.12.
  • Residential traffic adds up: in our October 17, 2026 tests, YouTube sometimes refused the direct and datacenter routes. One run of 10 frames at 1280 px from a 4K, 60 fps YouTube video then fetched 28.7 MB through the residential proxy, about $1.42 in megabyte charges. Interval and count runs with frames close together are much cheaper (40 frames at 640 px, one per second over 40 seconds, fetched 2.3 MB through the residential proxy).

To keep costs down, lower Max frame width (fewer megabytes per frame), set Proxy mode to Direct or Datacenter if you'd rather have a blocked video fail than pay for residential traffic, and use Max download per video as a hard cap. The run also stops at the maximum cost per run you set in Apify Console; frames are cut to fit the remaining budget.

This Actor only reads videos that are publicly available without logging in, the same way a viewer's browser does, and saves stills from them. Extracting frames is generally fine for analysis, indexing and personal use, but the frames remain part of the original work: you are responsible for following each platform's terms of service and copyright law, especially if you republish frames. If you aren't sure, consult a lawyer. Read more on the Apify blog about web scraping legality.

This Actor is unofficial and isn't affiliated with, endorsed by or sponsored by YouTube, TikTok, Meta or X.

Other video tools from ParseBird

FAQ

Which links work? YouTube videos and Shorts, TikTok videos, Instagram reels and video posts, Facebook videos, reels and fb.watch links, X posts with video, other sites that yt-dlp supports, and direct links to video files and HLS (.m3u8) streams. Content has to be public: private, members-only, age-restricted and login-only videos fail with a clear error and are not charged. Live streams aren't supported.

Does it download the whole video? Not for count, interval and timestamps modes: it seeks to each frame and fetches only the nearby part of the video. Scenes and keyframes modes read the whole time range you pick, at the lowest quality the site offers.

Why does a frame look a little earlier or later than I expected? Videos are made of individual frames, so each time is matched to the frame shown at that moment. In scenes mode the frame is taken right at the cut, so it shows the first frame of the new shot.

Why is the first frame in scenes mode missing a score? Scenes mode always includes the opening frame of the chosen range so the storyboard starts at the beginning. It isn't a shot change, so its sceneScore is empty.

Why was a video skipped? Either the run reached your maximum cost, or the video needed more data than Max download per video. Skipped videos are free. Raise the limit, lower Max frame width, or shorten the time range.

Where are the images? In the run's default key-value store. Each frame row has frameUrl (a direct link) and kvKey (the record key). You can also list all keys in the Storage tab of the run.

Can I use it through the API? Yes. Use the API tab or the Python and JavaScript examples above. You can also run it from Make, Zapier or n8n.

Something is missing or broken? Open an issue on the Issues tab.