Video → LLM Analyzer avatar

Video → LLM Analyzer

Pricing

from $0.008 / analysis completed

Go to Apify Store
Video → LLM Analyzer

Video → LLM Analyzer

Drop a video, give it a prompt, and have an LLM analyze it. Results land in your Notion page so Claude Code can pick up where you left off. Uses Apify MCP Connectors to write to Notion on your behalf — no Notion API key required.

Pricing

from $0.008 / analysis completed

Rating

0.0

(0)

Developer

Griffin Trent

Griffin Trent

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

13 minutes ago

Last modified

Categories

Share

Let an LLM watch your video

You give it a video. You tell it what you want. It watches and writes back.

🟢 New here? No setup needed for your first run. On the Input tab: paste a YouTube / TikTok / X / Instagram link (or drop a video file) → keep the example prompt → turn on "Just give me the analysis" (so you don't have to connect anything) → click Start. Your analysis comes back on the Output tab in ~30 seconds.

The "destination" and "Connector" fields are optional — they auto-write results into an app like Notion or Slack. (An MCP Connector is just a one-time, secure link to such an app; Apify never sees its password or token.) You don't need one to try this — that's exactly what "Just give me the analysis" is for.

That's it. Drop in a video file or paste a link from one of the most popular video platforms (YouTube, TikTok, X, Instagram), tell Claude or GPT what to look for, and get a structured analysis — with timestamps and quotes — back in seconds. The result lands in your dataset (or Notion / Slack / Google Sheets if you connect one), so you or any downstream LLM can keep working with it.

A 4-minute captioned YouTube run costs a few cents — about a penny of LLM, plus Apify compute and a flat $0.015 per-run fee. Real example below.

Why use it

  • Make any LLM video-aware. Claude, GPT, and Gemini can't watch video natively — this Actor is the bridge. Frames + transcript get fed to the model so it actually has something to reason about.
  • Skip the manual loop. No more "watch the video → take notes → paste into Notion." One run handles the whole pipe.
  • Built for agents. Set skipDestination: true and the full analysis comes back in the run's OUTPUT — perfect for Claude Code or any agentic workflow that wants to keep going.
  • No LLM API keys needed. Routes through Apify's hosted OpenRouter integration (OpenRouter is a unified API that proxies Anthropic, OpenAI, and Google models behind a single endpoint). You pay Apify at passthrough rates (~$0.01–$0.10 per video). Bring your own Anthropic key only if you want direct billing or Anthropic-specific features.

How to use it

  1. Drop in a video. Either upload a file (MP4/MOV/WebM, ≤1 GB, ≤10 min) or paste a URL from a supported platform.
  2. Write a prompt. "Summarize this in 5 bullets with timestamps." "List every product mentioned." "Describe each scene and who's speaking."
  3. Pick where the result goes — or skip connecting. No connection yet? Turn on "Just give me the analysis" and the result comes back in the dataset row + OUTPUT — no destination needed. Or pick a Notion / Slack / Google Sheets MCP Connector to auto-write the result. Notion is fully tested; Slack and Sheets are functional but lighter-tested — file any rough edges in the Issues tab. GitHub and Supabase are candidates for future support — file a +1 on the Issues tab if you'd use them.
  4. Click Start. A 4-min YouTube video finishes in ~30 seconds. A 10-min file upload takes 1–2 minutes.

Run this more than once? Save the filled-in input as a Task — keys and destinations carry over, you only swap in the new video URL each time. Tasks also support scheduling and webhooks.

Supported video sources

InputWhat works
File uploadAny MP4/MOV/WebM video file, regardless of which platform it came from. ≤1 GB, ≤10 min.
URLThe most popular video platforms: YouTube + Shorts, TikTok, X (Twitter), Instagram.

Anything else — Vimeo, Facebook, Reddit, Twitch, Dailymotion, Bilibili, VK, and other sites — needs to be downloaded first and uploaded as a file. The Actor detects unsupported URLs in about a second and fails fast with a clear message, so you're not charged for compute that was never going to work.

Why the short URL list? Generic yt-dlp downloaders are unreliable on cloud infrastructure. We dispatch to platform-specific Actors that actually work. We'll add more platforms as we find reliable backends for them.

Input

FieldRequiredDescription
VideoYesFile upload OR URL from a supported platform.
PromptYesPlain-English instructions. The more specific, the better.
LLM providerNoClaude (Anthropic, default), GPT (OpenAI), or Gemini (Google).
ModelNoDefault picks the standard model for the provider above, or pick a specific SKU (Sonnet 4.5, Opus 4, Haiku 4.5, GPT-4o, GPT-5, Gemini 2.5 Pro, etc.). ⚠️ If the model's family doesn't match the LLM provider above, the model wins — e.g. provider=Claude + model=openai/gpt-4o bills through the OpenAI route, not Claude. Keep them matching, or just leave on Default.
Anthropic API keyNoOnly used if Provider=Claude. When set, calls Anthropic directly with your key (instead of Apify's OpenRouter passthrough) — useful for prompt caching, extended thinking, or billing your own account.
Whisper API keyNoOpenAI key for audio transcription. Skip unless the analysis genuinely depends on what people said — frames + metadata cover most prompts. ~$0.006/min of audio.
DestinationNoMCP Connector — pick Notion (fully tested), Slack (functional, lighter-tested), or Google Sheets (functional, lighter-tested). Leave empty + set skipDestination: true to just get the analysis back in the dataset.
Destination targetConditionalPage URL (Notion), channel (Slack), or spreadsheet URL (Sheets).
Skip destinationNoWhen true, returns the analysis in the dataset row + OUTPUT and writes nowhere. Best for agentic callers.
Frames to extractNo0 = adaptive (~1 frame per 5s, 4–12 frames). Override only if you have a specific reason.
Force fresh runNoBy default, identical inputs replay the prior result instead of re-paying for the LLM call. Set true to force a fresh analysis.
Maximum cost for this run (USD)NoHard ceiling on what this run can cost you. After ingest, the Actor computes a worst-case cost and refuses the LLM call (no LLM cost incurred) if it would exceed this number. Leave at 0 for no cap. Anchor against the Pricing table below — most YouTube runs cost under $0.05; a 10-min upload tops out around $0.17. Set $0.20 for headroom, $0.50 for long uploads.

Output

Every run produces one dataset row + one OUTPUT key-value-store record with the same full payload (documented below), plus a separate ANALYSIS record holding just the clean Markdown analysis ({ "analysis": "<markdown>" }) for when you only want the text. The run's Output tab in Console surfaces these as quick links — Read your analysis (the ANALYSIS record), Full result record (the OUTPUT record), the run + history table, and the run log. Use whichever fits how you're calling the Actor.

Output schema

FieldTypeDescription
statusstringsucceeded, succeeded_no_url, succeeded_skipped_destination, succeeded_idempotent_replay, or failed_*.
completionTimestampstringISO-8601 timestamp of when the run finished.
writeBehaviorstringappend or nested — the behavior the Actor used for this run.
writeModestringThe literal action performed: notion_append, notion_child_page, slack_message, sheets_row, or unknown (when destination skipped).
routingTriggerstring | nullIf the write behavior was decided from your prompt, the phrase that matched (e.g. "new notion page"). null when behavior came from the input or default.
destinationUrlstringURL of the page/channel/sheet the analysis was written to. Empty when skipDestination: true.
destinationServicestringnotion, slack, sheets, or skipped.
analysisModestringHow the video was read: transcript+thumbnail (YouTube captions path — cheapest, one still image), frames (multi-frame visual, no spoken-word transcript), frames+transcript (multi-frame visual plus captions — e.g. a captioned YouTube video analyzed with a visual prompt), or frames+audio (multi-frame visual plus a Whisper audio transcript).
sourceUrlstring | nullOriginal URL if you pasted one, else null.
youtubeTitlestring | nullVideo title, populated for YouTube inputs.
youtubeChannelstring | nullChannel name, populated for YouTube inputs.
framesUsedintegerNumber of frames the LLM analyzed. 1 in transcript+thumbnail mode (the thumbnail).
durationSecnumber | nullVideo length in seconds, when known (file mode + download fallback).
providerstringanthropic, openai, or gemini.
modelstringSpecific model SKU used (e.g. anthropic/claude-sonnet-4.5).
whisperUsedbooleanWhether audio was transcribed via Whisper (vs. native captions or no audio).
transcriptCharsintegerLength of the transcript fed to the LLM.
tokensInintegerLLM input tokens.
tokensOutintegerLLM output tokens.
estimatedCostUsdnumberActual LLM + Whisper cost based on tokens used. Excludes Apify compute.
estimatedCostUsdMaxnumberWorst-case cost computed before the LLM call (used by the budget ceiling).
idempotencyKeystringHash of prompt + source + destinationTarget + writeBehavior + provider + frames. Used to short-circuit duplicate runs. Note: destinationTarget (the page URL / channel / sheet) IS in the hash; the chosen Connector ID is NOT. Two runs with the same destinationTarget but different Connectors will share an idempotency key — a replay returns the prior destinationUrl without re-checking the new Connector. Set forceFreshRun: true after swapping Connectors.
analysisPreviewstringFirst 500 characters of the LLM analysis.
analysisFullstringFull LLM analysis text.
softErrorsobject | nullnull on clean runs. When any ingest step degraded, this field is a small object with keys whisper, youtubeTranscript, youtubeDownloaderFallback, and youtubeVisualFallback — each a human-readable sentence if it tripped, else null. youtubeVisualFallback is set when a visual prompt on a YouTube video couldn't get real frames (the clip was over the 10-minute download cap, or its length couldn't be confirmed) and the run used the transcript + thumbnail instead — so even a succeeded run tells you why a "describe the scenes" prompt came back transcript-based. Agent callers can check softErrors != null to detect partial- or degraded-analysis cases.
timingsobject | nullPer-stage durations in milliseconds — youtubeFetchMs, downloadMs, frameExtractMs, whisperMs, llmMs, mcpWriteMs. Each key is null if the stage didn't run on this path (e.g. whisperMs: null when no Whisper key was set; downloadMs: null on YouTube-with-captions runs that skip the file pipeline). Whole field is null on idempotent-replay runs. mcpWriteMs is total-elapsed across all retry attempts (including backoff sleeps), not last-attempt time — useful for detecting retry storms, not for measuring proxy latency. Pipeline operators can alert on timings.whisperMs > 30000 or timings.llmMs p95 > 15000 without parsing logs. Stage timings are captured on both success AND failure paths, so a Whisper call that runs for 28s and then raises still shows whisperMs: 28000.
errorCategorystring | absentOnly present on failed runs. Canonical, closed enum — agent callers should branch on this instead of status_message. Recoverable categories (safe to retry as-is): download_failed_infra, download_no_url, pipeline_failed, llm_failed, write_failed. Permanent categories (require input change): invalid_input, unsupported_platform, unsupported_destination, download_video_gone, budget_exceeded, internal_error.
errorRecoverableboolean | absentOnly present on failed runs. true if a retry of the same input might succeed; false if the user must change the input first.
errorRetryAfterSecinteger | absentOnly present when errorRecoverable: true and the failure is rate-limited or otherwise time-sensitive. Number of seconds to wait before retrying. Today this is populated only for write_failed (30s) and download_failed_infra (60s) — other recoverable categories don't have a meaningful retry-after.
destinationFailureKindstring | absentOnly present on errorCategory: "unsupported_destination" runs. One of "unsupported" (the picked Connector exposes no matching writers) or "auth_or_dead" (the proxy returned a non-retryable 4xx). Lets agent callers route the two recovery actions (re-pick Connector vs. re-authorize) without parsing status_message.
destinationFailureHttpCodeinteger | null | absentOnly present on errorCategory: "unsupported_destination" runs. null when destinationFailureKind == "unsupported" (no HTTP call was made — the Connector responded but with no matching tools). A 4xx integer (e.g. 401, 403) when destinationFailureKind == "auth_or_dead". Type as Optional[int] in Pydantic models.
destinationToolsExposedstring[] | absentOnly present on errorCategory: "unsupported_destination" runs. The tools the picked Connector actually exposed, sorted alphabetically — useful for diagnostic logging (detect new Connector types proliferating on Apify's marketplace) or for synthesizing a "did you mean Notion?" suggestion without making a second MCP round-trip.

Note on status vs errorCategory: status (open string, e.g. "failed_invalid_input") is the legacy classifier kept for backward compatibility. errorCategory is the canonical closed enum going forward. New agent integrations should branch on errorCategory; treat status as informational.

Retry-policy example for agent callers:

result = await run_actor(...) # one dataset row per run
if result.get("status") == "succeeded":
return result["analysisFull"]
# Failed. Branch deterministically on errorCategory:
if not result.get("errorRecoverable"):
raise PermanentError(f"{result['errorCategory']}: {result['statusMessage']}")
# Recoverable. Honor the retry-after hint when present.
wait_sec = result.get("errorRetryAfterSec") or 10
await sleep(wait_sec)
return await run_actor(...) # retry with same input

Example output

Real output from this Actor running on Build on Apify (Part 1): From Idea to Solution (4:06, Apify channel) with the prompt "Summarize this video in 5 bullets. For each bullet, include a rough timestamp (e.g. 0:42) and quote any spoken line that matters."

{
"status": "succeeded_skipped_destination",
"completionTimestamp": "2026-05-28T14:45:45.607228+00:00",
"writeBehavior": "append",
"writeMode": "unknown",
"routingTrigger": null,
"destinationUrl": "",
"destinationService": "skipped",
"analysisMode": "transcript+thumbnail",
"sourceUrl": "https://www.youtube.com/watch?v=_f5VEaR-F2k",
"youtubeTitle": "Build on Apify (Part 1): From Idea to Solution",
"youtubeChannel": "Apify",
"framesUsed": 1,
"durationSec": null,
"provider": "anthropic",
"model": "anthropic/claude-sonnet-4.5",
"whisperUsed": false,
"transcriptChars": 1373,
"tokensIn": 1903,
"tokensOut": 299,
"estimatedCostUsd": 0.0102,
"estimatedCostUsdMax": 0.0358,
"idempotencyKey": "ff0dfcc9d6795d85",
"analysisPreview": "# Video Summary: Build on Apify (Part 1): From Idea to Solution\n\nBased on the transcript and timestamps provided, here are 5 key bullets summarizing this video:\n\n• **0:00 - Introduction to the series**: This is Part 1 of a 5-part series...",
"analysisFull": "# Video Summary: Build on Apify (Part 1): From Idea to Solution\n\nBased on the transcript and timestamps provided, here are 5 key bullets summarizing this video:\n\n• **0:00 - Introduction to the series**: This is Part 1 of a 5-part series that guides developers through creating web automation tools on Apify, from initial concept to publishing on the Apify Store for passive income.\n\n• **0:59 - What you can build**: The video explains Apify's use cases, including \"Web Scrapers: Collect product, price, or lead data from any website\" and \"Monitoring tools: Watch for changes in job listings, hotel prices, or real estate offers.\"\n\n• **2:00 - From idea to Actor**: This section covers the process of developing an Actor (Apify's term for automation tools), walking through how to transform a simple idea into a working solution.\n\n• **3:20 - Managing your tools**: The video discusses how to manage and maintain your Actors once they're built, including running and scaling them in the cloud.\n\n• **3:40 - Conclusion and next steps**: The video wraps up Part 1 and promotes the Apify $1M Challenge where developers can \"get rewards for building Actors,\" encouraging viewers to start building and monetizing their automation tools."
}

The LLM portion of this run was $0.0102 — just over a penny — because the video had native YouTube captions, so the Actor skipped frame extraction and Whisper entirely and ran the cheapest path. Your full bill adds Apify compute (~$0.01) and the flat $0.015 per-run fee, landing around $0.035 total.

Pricing

Total per-run cost — three things land on your Apify bill: Apify compute + LLM passthrough + this Actor's per-run fee (a flat $0.015: $0.005 to start + $0.008 per analysis + $0.002 per destination write). Defaults use Claude Sonnet 4.5, so figures below assume Claude; Gemini Flash or GPT-4o-mini run noticeably cheaper on the LLM line.

InputTotalBreakdown
YouTube with captions (any length ≤10 min)~$0.03–$0.07LLM ($0.01–$0.03 — captions skip Whisper and frame extraction) + Apify compute (~$0.01–$0.02) + Actor fee ($0.015)
YouTube no-captions, 2 min~$0.12compute + download + Whisper + LLM + Actor fee
TikTok / X / Instagram, 1 min~$0.08compute + download + Whisper + LLM + Actor fee
30-sec file upload~$0.06compute + Whisper + LLM + Actor fee
10-min file upload (worst case)~$0.19compute ($0.02) + Whisper for 10 min ($0.06) + LLM for full transcript + 12 frames on Claude Sonnet ($0.09) + Actor fee ($0.015)

Skipping the destination (agentic/API callers) drops the Actor fee to $0.013. Re-running an identical prompt+video replays from cache and charges the $0.005 start only — no LLM cost.

The Actor logs an estimated total in the run's status line before any LLM call fires, so you see the number before any cost is committed. To hard-cap a run, set a budget ceiling — there are two surfaces and whichever is tighter wins:

  • Input form — fill in Maximum cost for this run (USD). More discoverable on a per-run basis.
  • Apify Run dialog — set Maximum total charge in USD. Platform-standard, applies to any Actor.

If the worst-case estimate would exceed either cap, the Actor refuses to start the LLM call and the run ends with no LLM cost incurred.

Why three charge lines on your Apify invoice? Apify charges you (a) compute units for the container time, (b) pass-through events for the LLM tokens consumed via OpenRouter, and (c) this Actor's per-run fee ($0.005 start + $0.008 per analysis + $0.002 per destination write). All land on your Apify account — there's no separate Anthropic / OpenAI bill (unless you opt in to the Anthropic API key field for direct billing). Note the Maximum cost cap below limits the LLM portion the Actor controls before firing; compute and the per-run fee are billed on top.

Troubleshooting

SymptomWhat's going onFix
"Unsupported platform" at the start of a runURL platform isn't in the supported list (Vimeo, Facebook, Reddit, Twitch, Dailymotion, Bilibili, VK, etc.).Download the video locally first, then upload the MP4 to the file field.
"Video exceeds 1 GB"Hard cap to bound LLM cost.Re-encode at lower bitrate (HandBrake, ffmpeg -crf 28) or trim to the relevant section.
"Video exceeds 10 minutes"Hard cap. Whisper + frame budgets grow fast past this.Chunk into ≤10-min pieces and run separately. Combine results manually.
Analysis is empty or vagueLLM didn't have enough signal — likely silent video with no captions and no Whisper key.Add a Whisper key so the audio gets transcribed.
Visual prompt on a YouTube video came back describing speech, not scenesThe video was longer than 10 minutes (or its length couldn't be confirmed), so real frames couldn't be downloaded — the run used the transcript + thumbnail. The OUTPUT softErrors.youtubeVisualFallback field and the run log say so.Download the video and upload it as a file — the file path always extracts real frames. Or shorten the clip to ≤10 minutes.
"Destination write failed"MCP Connector lost permissions or the target URL is wrong.Re-open the input form, re-pick the Connector, confirm the page/channel/sheet URL still resolves, re-run. Your LLM cost from the prior run is cached — the retry only pays for the destination write.
"The Connector you picked doesn't expose the tools this Actor needs"You selected a Connector the Apify Console marks 'Not eligible' — usually GitHub / Supabase / Sentry / another non-supported MCP server. We catch this before the LLM call so no LLM cost is incurred. (The fixed actor-start compute fee — ~$0.02 per run at 4 GB memory — still applies, as on any run that reaches the Actor.)Re-pick a Notion, Slack, or Google Sheets Connector — or toggle Skip destination if you just want the analysis back in the dataset row.
"Before any LLM work: couldn't reach the Connector you picked"The Connector you picked exists, but its authorization expired or the underlying resource was deleted. We caught it at the gate — no LLM cost is incurred. (The fixed actor-start compute fee still applies as above.)Re-authorize the Connector in Apify Console → Settings → Integrations → MCP Connectors, then re-run.
Run succeeded but nothing appeared in NotionProbably ran with skipDestination: true.Open the run, click OUTPUT — the analysis is in the analysisFull field.
"Idempotent replay" in the statusIdentical inputs to a previous successful run — the prior result was replayed instead of re-paying for the LLM.Set forceFreshRun: true in the input to force a fresh analysis. Replays return the prior destinationUrl even if you've since revoked the original Connector — the URL is historical, not re-verified. Agent callers building user-facing surfaces should treat the URL's freshness as best-effort and HEAD-check it before exposing to end users.
"API key rejected" within seconds of startingBad/expired Anthropic key.Regenerate at console.anthropic.com/settings/keys, paste the new one.

Tips

  • YouTube with captions is by far the cheapest path — it skips video download, Whisper, and frame extraction entirely. The example above ran for about a penny.
  • For best fidelity, upload the file directly. The file pipeline always extracts real frames + Whisper transcript — the highest-quality "watch" path.
  • Skip the Whisper key if the video has no useful audio (silent screen recording, B-roll). Saves time and money.
  • Set frames to 4–8 for short talking-head clips. Adaptive mode picks 4–12 frames; pinning to a low number for stable-scene videos cuts LLM cost 50–80% with no quality loss.
  • Reuse the same Notion page across runs — each one appends a new section, so the page becomes a running video-analysis log you can scroll back through.

FAQ

Who sees my video frames and transcript? The Actor extracts frames + (optionally) a Whisper transcript and sends them to the LLM provider you pick. By default that's OpenRouter (which routes to Anthropic, OpenAI, or Google depending on the model). If you set a Whisper key, audio is sent to OpenAI for transcription. Both Apify and the LLM/Whisper provider may retain operational logs per their privacy policies — don't submit confidential or regulated data. Apify's destination MCP proxy injects your Notion/Slack/Sheets token server-side; the Actor itself never sees that token.

Why a 10-minute cap? Whisper costs and frame budgets scale linearly with length. The cap keeps per-run cost predictable and within the pricing table above. If you need longer videos, chunk and stitch manually.

Can I use my own LLM key instead of Apify's OpenRouter? Yes — paste an Anthropic key in the optional field. It only applies when Provider=Claude. GPT and Gemini always go through OpenRouter (no BYO key path for them yet).

Bug or feature request? Open an issue on the Actor's Issues tab in Apify Console.

You are responsible for ensuring you have the right to analyze any video you submit. Submitting copyrighted material, content depicting identifiable individuals without their consent, or content prohibited by the source platform's Terms of Service is your responsibility — not Apify's, and not this Actor's authors'. Apify reserves the right to suspend accounts that use this Actor in ways that violate the Apify Acceptable Use Policy.

No automated content moderation. Frames and audio are passed to the LLM provider you select (Anthropic, OpenAI via OpenRouter, or Google). Do not submit illegal content, CSAM, or content prohibited by your LLM provider's usage policy — your provider's safety filter may refuse the response, and any violation is logged against your account.

Trademarks & affiliations. This Actor is not affiliated with, endorsed by, or sponsored by Anthropic, OpenAI, OpenRouter, Google, Google Sheets, Whisper, Notion, or Slack. Product names and trademarks are referenced for technical compatibility only.