ytHeatmap — YouTube Attention & Multitmodal Heatmap Engine
Pricing
Pay per usage
ytHeatmap — YouTube Attention & Multitmodal Heatmap Engine
Extract YouTube engagement heatmaps & viral moments in sub-seconds. Dual-engine reliability, 90% LLM token reduction, zero GPU costs, anti-bill-shock guarantee.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Alessio Iacoviello
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 days ago
Last modified
Categories
Share
ytHeatmap
Extract the attention heatmap from any YouTube video. Native retention data when available. Multimodal signal analysis when it is not. One Actor. Two engines. Zero GPU.
Why Choose ytHeatmap
For LLM and RAG Builders
You need structured attention data inside your prompts without burning thousands of tokens on raw arrays.
made_for_llm: trueactivates Visvalingam-Whyatt geometric simplification, reducing 200+ raw buckets down to 15-40 semantically meaningful points.- Output arrives as a compact
{ schema, duration_total, average_attention, points }object -- ready to inject into any prompt template. - Time unit conversion (millis, seconds, minutes, hours) is handled server-side. No post-processing on your end.
- Average attention score is pre-computed as a 0-100 integer. One number for your retrieval ranking.
Token savings: A 60-minute video produces ~720 raw buckets. With LLM mode, you get ~40 points. That is a 94% reduction in prompt tokens.
For Webhook and Automation Engineers
You need deterministic, schema-stable payloads that never break your downstream pipelines.
- Fixed JSON contract: Every response contains
id,source_info,time_unit,made_for_llm,duration_ms, andheatmap. No optional fields. No surprises. source_info.causetells you exactly why a fallback engine was used -- log it, alert on it, branch on it.- Webhook-ready: Push results directly to Zapier, n8n, Make, or any HTTP endpoint via Apify's native webhook dispatch.
- Idempotent inputs: Same URL + same config = same output shape. Always.
- Response time: native heatmap extraction completes in under 3 seconds for most videos.
For Developers
You need clean code, no GPU tax, and a dual-engine SLA that does not silently degrade.
- Zero GPU cost: The multimodal engine runs pure-Python Savitzky-Golay smoothing and Visvalingam-Whyatt simplification. No PyTorch. No CUDA. No inference API calls.
- Dual-engine architecture with explicit fallback: If YouTube's native heatmap is unavailable (low retention, disabled graph), the multimodal engine (audio RMS delta + transcript text density) activates automatically. You control the behavior via
source_preference. - Proxy rotation built-in: Datacenter proxies fail fast. Residential proxies retry with fresh IPs. You never configure anything.
- Source code on the Actor page:
extract.py,transform.py,resolve.py,validate.py,signal.py. Read it. Fork it. Audit it. - Typed pipeline:
validate -> resolve -> extract -> transform. Each stage is a pure function. No hidden state.
For No-Code Users and Analysts
You want to paste a URL, click Start, and get a chart-ready dataset. No code. No terminal. No billing surprises.
- One input field: Paste any YouTube URL. That is it.
- Anti-Bill-Shock guarantee: A single run will never cost more than $1.00 USD. Period. See the guarantee section below.
- 7-day free tier: Try unlimited runs for a full week before any charge applies.
- Dataset export: Results land in an Apify dataset. Download as CSV, JSON, or Excel. Connect to Google Sheets or Airtable with one click.
- No technical knowledge required: The Actor handles video resolution, proxy rotation, format detection, and error recovery internally.
Us vs Others
| Feature | ytHeatmap | GPU-based transcription tools | Manual browser scraping |
|---|---|---|---|
| Native YouTube heatmap extraction | Yes | No | Fragile, breaks on UI change |
| Multimodal fallback (audio + transcript) | Yes, built-in | Requires separate pipeline | Not possible |
| GPU required | No | Yes ($$$) | No |
| Max cost per run | $1.00 (hard cap) | $2-$15+ | Free but unreliable |
| LLM-optimized compact output | Yes (15-40 points) | No | No |
| Savitzky-Golay denoising | Yes | Varies | No |
| Geometric simplification (Visvalingam-Whyatt) | Yes | No | No |
| Proxy rotation with residential fallback | Yes, automatic | Usually no | No |
| Webhook / API integration | Native (Apify) | Varies | No |
| Time unit conversion (ms/s/min/h) | Yes, server-side | Manual | Manual |
| Anti-bot / IP-block handling | Automatic retry + IP rotation | None | Manual |
| Free tier | 7 days | Rarely | N/A |
| Deterministic JSON schema | Yes | No | No |
Dual-Engine Architecture
flowchart TDA[User Input: URL + Config] --> B{Validate & Resolve}B -->|Invalid URL / Domain| ERR1[ValueError: Rejected]B -->|Valid| C{Source Preference}C -->|youtube_native| D[Engine 1: YouTube Native Heatmap]C -->|multimodal_attention_model| E[Engine 2: Multimodal Signal Analysis]C -->|auto| DD -->|Heatmap found| F[Raw Heatmap Data]D -->|No heatmap + AUTO| G{Duration check}D -->|No heatmap + NATIVE only| ERR2[RuntimeError: No native data]D -->|IP blocked / 429| PROXY[Proxy Rotation: DC -> Residential]PROXY --> DG -->|Under 3 hours| EG -->|Over 3 hours| ERR3[ValueError: Too long for fallback]E --> E1[Download audio via yt-dlp + FFmpeg pipe]E --> E2[Fetch transcript JSON3 subtitles]E1 --> E3[PCM Delta-RMS per 5s bucket]E2 --> E4[Text density per 5s bucket]E3 --> FE4 --> FF --> H{Output Type}H -->|raw| I[Return full bucket list as-is]H -->|processed| J[Savitzky-Golay Denoise]J --> K{made_for_llm?}K -->|true| L[Visvalingam-Whyatt Simplification]L --> M[Compact LLM Payload]K -->|false| N[Full processed array with time conversion]M --> O[Push to Dataset + Webhook]N --> OI --> O
Input Schema
{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ","type": "processed","source_preference": "auto","processing": {"time_unit": "seconds","make_for_llm": true}}
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Full YouTube video URL. Shorts are not supported. |
type | string | No | "raw" (default) or "processed". Raw skips all post-processing. |
source_preference | string | No | "auto" (default), "youtube_native", or "multimodal_attention_model". |
processing.time_unit | string | No | "millis" (default), "seconds", "minutes", or "hours". Ignored when type is raw. |
processing.make_for_llm | boolean | No | false (default). When true, applies geometric simplification and returns compact format. |
Output Schema
Standard Output (made_for_llm: false)
{"id": "dQw4w9WgXcQ","source_info": {"requested": "auto","used": "youtube_native","cause": null},"time_unit": "seconds","made_for_llm": false,"duration_ms": 212000,"heatmap": [{ "start": 0.0, "duration": 5.0, "value": 0.4521 },{ "start": 5.0, "duration": 5.0, "value": 0.6783 },{ "start": 10.0, "duration": 5.0, "value": 0.8912 }]}
LLM Compact Output (made_for_llm: true)
{"id": "dQw4w9WgXcQ","source_info": {"requested": "auto","used": "multimodal_attention_model","cause": "YouTube native heatmap unavailable (insufficient viewer retention data or disabled graph)."},"time_unit": "seconds","made_for_llm": true,"duration_ms": 212000,"heatmap": {"schema": ["time", "attention_score_0_to_100"],"duration_total": 212.0,"average_attention": 63,"points": [[0.0, 45],[15.0, 72],[45.0, 91],[120.0, 58],[195.0, 34],[212.0, 22]]}}
Webhook Payload Example
Configure an Apify webhook to POST to your endpoint on run completion. The payload your server receives:
{"eventType": "ACTOR.RUN.SUCCEEDED","eventData": {"actorId": "yt-heatmap-extractor","actorRunId": "abc123xyz","status": "SUCCEEDED"},"resource": {"defaultDatasetId": "ds_abc123","defaultKeyValueStoreId": "kvs_abc123"}}
Then fetch the dataset item (or configure a webhook dispatch transform to inline it):
{"id": "dQw4w9WgXcQ","source_info": { "requested": "auto", "used": "youtube_native", "cause": null },"time_unit": "seconds","made_for_llm": true,"duration_ms": 212000,"heatmap": {"schema": ["time", "attention_score_0_to_100"],"duration_total": 212.0,"average_attention": 63,"points": [[0.0, 45], [15.0, 72], [45.0, 91], [120.0, 58], [195.0, 34], [212.0, 22]]}}
This payload is deterministic. Same input produces the same structure. Your downstream parser never encounters missing keys or shape changes.
Anti-Bill-Shock System
Hard guarantee: a single run will never cost more than $1.00 USD.
Here is how the pricing works and why it is capped:
| Event | Cost | When charged |
|---|---|---|
youtube_native_heatmap | $0.012 | Native YouTube heatmap found and returned. |
mm_attention_model_base | $0.015 | Multimodal fallback activated (once per run). |
minute_processed | $0.007 per minute | Each minute of audio analyzed in multimodal mode. |
The cap: The multimodal engine processes at most 140 billable minutes per run (3 hours of video). At $0.007/minute, that is $0.98 + $0.015 base = $0.995. Under one dollar. Always.
The free tier: Your first 7 days are completely free. Unlimited runs. No credit card required to start.
No charge on failure: If the Actor fails to deliver a heatmap (video not found, private video, unsupported format), you are not charged. The run terminates with a clear error message and zero cost.
Worst-case cost calculation:Base: $0.015Minutes: 140 x $0.007 = $0.980Total: $0.995 < $1.00Best-case cost (native heatmap):Total: $0.012
Technical Specifications
| Property | Value |
|---|---|
| Runtime | Python 3.12 (Apify Actor) |
| GPU | Not required |
| Memory | 1024 MB |
| Timeout | 4 hours |
| Max video duration (multimodal) | 3 hours |
| Bucket resolution | 5 seconds |
| Denoising | Savitzky-Golay (window 5-51, polyorder 3) |
| Simplification | Visvalingam-Whyatt with monotonic area enforcement |
| Proxy strategy | Datacenter (fail-fast) then Residential (retry with fresh IP) |
| Anti-bot handling | Automatic IP rotation on 429 / CAPTCHA detection |
| Supported URLs | youtube.com, youtu.be, youtube-nocookie.com (no Shorts) |
Quick Start
# Via Apify CLIapify call yt-heatmap-extractor --input='{"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ","type":"processed","processing":{"time_unit":"seconds","make_for_llm":true}}'
# Via Apify Python SDKfrom apify_client import ApifyClientclient = ApifyClient("YOUR_API_TOKEN")run_input = {"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ","type": "processed","source_preference": "auto","processing": {"time_unit": "seconds","make_for_llm": True}}run = client.actor("yt-heatmap-extractor").call(run_input=run_input)for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["heatmap"])
Error Handling
All errors are returned as structured ValueError or RuntimeError messages. The Actor never fails silently.
| Error | Meaning | Retryable |
|---|---|---|
Invalid input: 'url' field is required... | Missing or empty URL | No |
Invalid domain: ... does not belong to YouTube | Non-YouTube URL | No |
YouTube video '...' not found (HTTP 404) | Video deleted or wrong ID | No |
Access forbidden ... (HTTP 403) | Private / age-restricted / geoblocked | No |
Unsupported content: YouTube Shorts | Shorts URL provided | No |
Video too long ... for multimodal fallback | Over 3 hours, no native data | No |
IP_BLOCKED_BY_YOUTUBE | Rate limited (auto-retried internally) | Yes (automatic) |
Failed to fetch YouTube page | Network failure after all retries | Yes (manual) |
License and Attribution
This Actor is provided as-is on the Apify platform. YouTube is a trademark of Google LLC. This Actor is not affiliated with, endorsed by, or sponsored by YouTube or Google.
Built with pure Python signal processing. No GPUs were harmed in the making of this Actor.