Video Transcript & Subtitle Extractor
Pricing
from $5.00 / 1,000 transcript extracteds
Video Transcript & Subtitle Extractor
Extract transcripts, subtitles and captions from video URLs on 1,000+ platforms, including YouTube, Vimeo, TikTok, Instagram, X, Facebook, Twitch and TED. Native captions first, Whisper AI when none exist; output JSON, SRT, VTT, text or Markdown.
Pricing
from $5.00 / 1,000 transcript extracteds
Rating
0.0
(0)
Developer
Khadin Akbar
Maintained by CommunityActor stats
0
Bookmarked
113
Total users
12
Monthly active users
8 days ago
Last modified
Categories
Share
What is Video Transcript & Subtitle Extractor?
Extract transcripts, subtitles and captions from public video URLs across 1,000+ platforms, including YouTube, Vimeo, TikTok, Instagram, X, Facebook, Twitch, TED, Bilibili, SoundCloud, and Reddit. Each accepted URL produces one dataset record with the original URL, inferred platform, transcript content, and useful metadata such as title, channel, duration, language, transcript source, segment count, character count, and subtitle file keys when available. YouTube playlist and channel URLs are expanded into individual videos. Native captions come first; Whisper AI transcribes videos without captions when you opt in. This Actor is usable through Apify and Apify MCP, and it returns one record per video.
Cost at a glance: one Transcript extracted event per video with a transcript, plus Whisper minute events only for platform-funded Whisper audio (none when you bring your own OpenAI key), plus Apify platform usage. Only videos that return a transcript are billed as transcripts. See the Pricing tab for current prices.
Best fit and connected workflows
This Actor fits workflows that start with a known public video URL and need structured transcript output. It routes naturally into:
- transcript indexing for search, embeddings, and knowledge bases
- content repurposing from talks, interviews, webinars, and podcasts
- accessibility file generation with SRT or VTT
- multilingual caption review for YouTube videos with captions
- AI agents that need one transcript record per input URL through Apify MCP
- metadata plus transcript extraction in one dataset row
Practical scenario
Maya, a content analyst, has three public video URLs from YouTube and Vimeo. She wants the title, channel, duration, transcript source, language, and transcript text for each one. She runs this Actor with outputFormat: "json" and includeMetadata: true. In the dataset, she reviews the transcript segments, sees whether each record came from manual captions, auto captions, translated captions, or Whisper fallback, and then decides which videos to turn into an internal summary and which ones to archive with subtitle files.
Input
| Field | Type | Description |
|---|---|---|
videoUrls (required) | array of objects | Public video URLs. Each item is one video, or a YouTube playlist/channel URL that is expanded into videos. |
maxVideosPerPlaylist | integer | For YouTube playlist or channel URLs, the number of newest listed videos to process. Default 20; 0 disables expansion. |
preferredLanguages | array of strings | ISO 639-1 codes in priority order. The first available match is returned. Use auto to accept any language. |
outputFormat | string | Transcript format in each result: json, srt, vtt, text, or markdown. |
useWhisperFallback | boolean | Optional fallback when native captions are unavailable. Defaults to false; enable it only with an OpenAI key or when Whisper coverage and its cost are explicitly desired. |
whisperModel | string | Whisper model used for fallback transcription. |
openaiApiKey | string (secret) | Optional BYOK OpenAI API key for Whisper fallback billing through your OpenAI account. |
translateTo | string | Optional ISO 639-1 code for YouTube caption translation. |
includeAutoCaptions | boolean | Accept YouTube auto-generated captions. |
maxDurationMinutes | integer | Set the maximum video length sent to Whisper. Native captions from longer videos are still extracted. |
perVideoTimeoutSecs | integer | Time limit for one video (default 900 s). A slower video is skipped with a video_timeout note and the run moves on. |
includeMetadata | boolean | Include title, channel, duration, view count, upload date, and thumbnail in each result. |
proxyConfiguration | object | Optional proxy settings. |
Focused JSON input example
{"videoUrls": [{"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"}],"preferredLanguages": ["en","es"],"outputFormat": "json","useWhisperFallback": false,"whisperModel": "whisper-1","openaiApiKey": "","translateTo": "","includeAutoCaptions": true,"maxDurationMinutes": 120,"perVideoTimeoutSecs": 900,"maxVideosPerPlaylist": 20,"includeMetadata": true,"proxyConfiguration": {"useApifyProxy": false}}
Output
Each successfully extracted video produces one validated dataset record. Raw SRT and VTT files are also saved to the default key-value store. The output schema also exposes terminal run records for summary and downstream automation.
| Field | Type | Description |
|---|---|---|
videoUrl | string | Original URL processed. |
platform | string | Platform inferred from the URL. |
title | string or null | Video title from platform metadata. |
channel | string or null | Uploader or channel name. |
channelUrl | string or null | URL of the uploader or channel page. |
durationSeconds | number or null | Video duration in seconds. |
viewCount | number or null | View count at extraction time. |
likeCount | number or null | Like count at extraction time. |
uploadDate | string or null | Upload date in YYYYMMDD format. |
thumbnail | string or null | Thumbnail image URL. |
description | string or null | Video description, truncated to 1000 characters. |
transcript | array or string | Transcript in the requested format. JSON returns {start, end, text} segments. |
transcriptFormat | string or null | Format used for the transcript field. |
transcriptSource | string or null | Source of the transcript: manual, auto, translated, or whisper. |
language | string or null | ISO 639-1 code of the returned transcript. |
isAutoGenerated | boolean or null | Indicates whether captions were auto-generated or Whisper-transcribed. |
segmentCount | number or null | Number of timestamped segments in the transcript. |
characterCount | number or null | Total transcript character count. |
whisperMinutesCharged | number or null | Whisper minutes billed for the record. |
srtKey | string or null | Key for the saved SRT file in the default key-value store. |
vttKey | string or null | Key for the saved VTT file in the default key-value store. |
playlistUrl | string or null | Playlist or channel URL the video was expanded from, when the input was a YouTube playlist or channel. |
diagnostics | string or null | Issue detail recorded for a specific URL. |
Sample output record (real run, transcript shortened)
The input was the TED channel URL with maxVideosPerPlaylist: 2, so the row carries playlistUrl.
{"videoUrl": "https://www.youtube.com/watch?v=ohpIw6iGXNA","platform": "youtube","title": "Why I’m Building Libraries Inside Prisons | Reginald Dwayne Betts | TED","channel": "TED","channelUrl": "https://www.youtube.com/@TED","durationSeconds": 749,"viewCount": 41793,"likeCount": 175,"uploadDate": "20261015","thumbnail": "https://i.ytimg.com/vi_webp/ohpIw6iGXNA/maxresdefault.webp","transcript": [{"start": 4.201,"end": 7.538,"text": "I ate my first mango in a hole."},{"start": 8.506,"end": 10.307,"text": "What some called a shoe,"}],"transcriptFormat": "json","transcriptSource": "manual","language": "en","isAutoGenerated": false,"segmentCount": 215,"characterCount": 8323,"whisperMinutesCharged": 0,"srtKey": "srt-youtube-ohpIw6iGXNA.srt","vttKey": null,"playlistUrl": "https://www.youtube.com/@TED"}
How it works
The Actor expands YouTube playlist and channel URLs into individual videos, probes each video, and prefers native captions first. If a probe is refused or times out, it retries once on a fresh residential session and then directly before recording the video in FAILURES. When multiple preferred languages are listed, it uses the first available match from the ordered list. When captions are available, it returns a validated transcript record and saves raw SRT and VTT files to the default key-value store—even when the video is longer than maxDurationMinutes. That cap applies only when no native captions are usable and Whisper fallback would incur per-minute transcription cost. The run also persists terminal outcome records such as COMPLETE, PARTIAL, CONFIG_ERROR, or UPSTREAM_FAILED, and stores per-URL diagnostics (for example no_transcript_available, invalid_video_url, video_timeout, probe_failed) in the FAILURES key-value record rather than the result dataset. Each video has its own time limit (perVideoTimeoutSecs), and the run stops cleanly before the platform timeout with a PARTIAL outcome that keeps every transcript already saved.
Pricing
This Actor uses Apify Pay per event plus Apify platform usage. Open the live Pricing tab on the Actor page for the current charges and platform usage details.
| Job | Events charged |
|---|---|
| 10 videos, all with native captions | 10 × Transcript extracted + 1 × Actor start |
| 100 videos, 10 of them need Whisper (10 min each), platform-funded | 100 × Transcript extracted + 100 × Whisper minute + 1 × Actor start |
Same job with your own openaiApiKey | 100 × Transcript extracted + 1 × Actor start (Whisper is billed by OpenAI to your key) |
A playlist URL with maxVideosPerPlaylist: 20 | up to 20 × Transcript extracted (only videos with a transcript) |
Videos that end without a transcript (no captions, private, removed, refused by the site or timed out) are not charged as Transcript extracted. Apify platform usage is charged on top of the events; check the Pricing tab for current prices before large runs.
Use with AI agents (MCP)
This Actor is available as an Apify Actor usable through Apify MCP. The exact Actor identity is khadinakbar/video-subtitle-extractor.
Tool description: extract subtitles, captions, and AI transcripts from a supplied public video URL, then return one structured dataset record per video with transcript text, metadata, transcript source, and subtitle file references when available.
Extract transcripts from these public video URLs and return one dataset row per URL. Prefer native captions first, then Whisper fallback when needed. Include transcript source, language, and subtitle file keys in the output.
Output interpretation:
transcriptis the primary content field.transcriptSourceshows whether the record came from manual captions, auto captions, translated captions, or Whisper.segmentCountandcharacterCounthelp estimate transcript size.srtKeyandvttKeypoint to subtitle files in the default key-value store.diagnosticsis available when a URL produces a record with an issue detail.
Provenance and scope:
- The dataset contains one record per processed video URL.
- The transcript record keeps the original
videoUrland inferredplatform. - Raw subtitle files are stored separately in the key-value store.
- The output schema also exposes run summary records for terminal outcome handling.
Pagination and cost guidance:
- For multiple videos, pass each video as its own URL, or pass a YouTube playlist/channel URL with
maxVideosPerPlaylist. - The primary event is
Transcript extracted. - Whisper-minute billing applies only when platform-funded Whisper transcription is used.
- Check the live Pricing tab for the current Pay per event and platform usage details before large runs.
JavaScript API example
const { ApifyClient } = require("apify-client");const client = new ApifyClient({token: process.env.APIFY_TOKEN,});(async () => {const run = await client.actor("khadinakbar/video-subtitle-extractor").call({videoUrls: [{ url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }],preferredLanguages: ["en"],outputFormat: "json",useWhisperFallback: false,includeMetadata: true});const dataset = client.dataset(run.defaultDatasetId);const { items } = await dataset.listItems();console.log("First record:", items[0]);})();
Best results and outcome guidance
Use one public URL per item. Put preferred caption languages in priority order so the Actor can return the first matching transcript. Keep outputFormat: "json" when you need segment-level timestamps for AI processing, and switch to srt or vtt when you need subtitle files for editing tools. Leave includeMetadata on when you want title and channel context alongside the transcript. Use useWhisperFallback: true when you want coverage for videos without native captions and have supplied openaiApiKey (or explicitly accept the platform Whisper cost). The default false keeps prefilled and native-caption runs credential-free; set maxDurationMinutes to control Whisper cost for longer videos.
Continue the workflow
- Then use Vimeo Video Downloader to extend Video Transcript & Subtitle Extractor with a neighboring creator and media research source when the brief calls for Vimeo data.
- Use YouTube Transcript and Subtitle Data Scraper when every URL is a YouTube video and you only need YouTube caption data.
- Then use YouTube Comments Scraper to add audience comments and replies for the same YouTube videos.
Design note
I found that the live output contract centers on a single transcript record per video URL, with videoUrl and platform required in every dataset item. That makes the dataset shape straightforward for batch processing and agent workflows.
FAQ
Can I pass a playlist or channel URL?
Yes, for YouTube. A youtube.com/playlist?list=… URL or a channel URL (youtube.com/@handle, /channel/…, or its /videos or /shorts tab) is expanded into up to maxVideosPerPlaylist newest videos (default 20). Each output row carries playlistUrl. For other sites, pass individual video URLs.
Why is a video missing from the results, and was I charged?
Open the FAILURES key-value record. Each entry names the video and a reason such as no_transcript_available, no_captions_and_no_whisper_key, invalid_video_url, probe_failed or video_timeout. Videos without a transcript are not charged as Transcript extracted.
What happens with very long videos?
Native captions are extracted at any length. Whisper is only used up to maxDurationMinutes, and each video has a perVideoTimeoutSecs limit so the run keeps moving past one slow video.
Which transcript sources can appear in the dataset?
The dataset contract includes manual, auto, translated, and whisper as transcript sources.
What file formats are saved outside the dataset?
Raw SRT and VTT files are saved to the default key-value store, and the output schema exposes links for subtitle files and run summary records.
Can I use it with Apify MCP?
Yes. This Actor is built as an Apify Actor usable through Apify MCP, and the exact Actor identity is khadinakbar/video-subtitle-extractor.
How does it handle multiple caption languages?
Use preferredLanguages as a priority list. The Actor falls through the ordered list and returns the first available match.
Responsible use
Use this Actor only with public video URLs and in ways that respect the source platform's terms, applicable rights, and local law. Review the transcript source and metadata before reusing content, especially when captions are auto-generated or when Whisper fallback is used.