Nimbryxo Studio

Use YouTube Caption & Whisper AI Transcript Extractor with Python

Get timestamped transcripts from YouTube videos in your preferred language, with optional AI transcription for videos that have no captions at all. Returns full text, timed segments, and core video metadata.

1. Choose the data you need

Review the published README for supported collection modes, examples, and limits. The recipe below uses the current published input definition.

2. Prepare a source-based input

This JSON contains published prefills and required-field defaults. Review every value for your task before running it; it is not a promise of successful collection.

{
  "includeAutoGenerated": true,
  "includeWordTimings": false,
  "mode": "videos",
  "proxyCountry": "GB",
  "useWhisper": true,
  "videoUrls": [
    "https://www.youtube.com/watch?v=jNQXAC9IVRw"
  ],
  "whisperModel": "tiny"
}

Download input.example.json and save your reviewed copy as input.json.

FieldTypeRequiredDescription
modestringoptionalWhat to scrape: specific videos, a channel's uploads, or a playlist.
videoUrlsarrayoptionalYouTube watch URLs, youtu.be short links, Shorts/embed URLs, or plain 11-character video IDs (mode=videos). Duplicate IDs are processed once.
channelUrlsarrayoptionalChannel URLs or handles (mode=channel), e.g. https://www.youtube.com/@TED, https://www.youtube.com/channel/UC..., or @TED. Each channel's latest uploads are enumerated and every video is transcribed.
maxVideosPerChannelintegeroptionalMaximum number of videos to enumerate from each channel (mode=channel). 1-1,000.
playlistUrlsarrayoptionalPlaylist URLs or IDs (mode=playlist), e.g. https://www.youtube.com/playlist?list=PL... or PL.... Every video in the playlist is transcribed.
maxVideosPerPlaylistintegeroptionalMaximum number of videos to enumerate from each playlist (mode=playlist). 1-1,000.
languagestringoptionalCaption language to fetch. Leave Auto-detect to use the video's original language.
includeAutoGeneratedbooleanoptionalWhether to include auto-generated captions when manual captions are not available.
useWhisperbooleanoptionalWhen YouTube has no transcript (disabled captions, music-only, or blocked), download the audio and transcribe with Whisper AI (faster-whisper, CPU). Adds ~30-180 s per video. Enabled by default to guarantee transcript output even when YouTube captions are unavailable.
whisperModelstringoptionalWhisper model size to use when `useWhisper` is enabled. Larger = more accurate but slower and more RAM. 'base' is balanced.
includeWordTimingsbooleanoptionalAdd a wordTimings array with word-level start/end times. Only auto-generated YouTube captions expose word timings; manual captions and AI transcripts do not.
maxWhisperMinutesintegeroptionalLeave unset for the legacy behavior (AI enabled with no length limit). Set to 0 explicitly to disable AI transcription. A positive value only sends videos of that length or shorter to AI. AI still requires Use Whisper AI fallback.
proxyCountrystringoptionalCountry/region for the proxy IP. Useful if transcripts are geo-blocked in the default US region.
outputFormatstringoptionalHow transcript data is included. 'full' = segments and full_text; 'text_only' = full_text only; 'segments_only' = segments only; 'srt' / 'vtt' = ready-to-use subtitle text derived from the segments.

3. Start an Actor run

Set APIFY_TOKEN in your environment. Python 3.10 or newer is sufficient; this recipe uses no third-party packages.

Execution may incur charges. Review current pricing on Apify. The request asks for a 120-second timeout and a charge limit; these settings are subject to Apify’s pricing and do not guarantee an all-inclusive spending cap.

import json
import os
import urllib.request

# Save the schema-derived example as input.json; review and edit it first.
with open("input.json", encoding="utf-8") as stream:
    actor_input = json.load(stream)

token = os.environ["APIFY_TOKEN"]
request = urllib.request.Request(
    "https://api.apify.com/v2/acts/yNFXZ2tJKz5wBMxDw/runs?timeout=120&maxTotalChargeUsd=0.50",
    data=json.dumps(actor_input).encode("utf-8"),
    headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
    method="POST",
)
# This starts a potentially billable run. Do not automatically retry this POST.
with urllib.request.urlopen(request, timeout=40) as response:
    run = json.load(response)["data"]
print("Run ID:", run["id"])
print("Status:", run["status"])
# Inspect and download results in Apify Console once the run succeeds.

4. Inspect the actual results

Open the run in Apify Console and wait for a successful completion. Use the published output schema to locate results and the dataset schema to understand declared views. Missing or optional record fields must not be treated as guaranteed values.

One record per video with its transcript (segments, full text, SRT/VTT, optional word timings), caption/translation metadata, chapters, heatmap, and channel identity.

Questions before you run

Which inputs are required?

No top-level fields are marked required in the published schema. Conditional requirements can still apply; check the README.

What does this guide verify?

The fields, prefills, and schema links are rendered from the published build. This is a usage recipe, not a paid live extraction test. Source availability and collection results can vary.

What if the run request times out?

Check Apify Console before retrying. The first request may already have created a run. Do not automatically repeat a run-creation POST.

Generated from source build mm7zKNeWAnPZWiEHh and its README and schemas. Source changes regenerate this guide; no third-party editorial claims are inferred.