HomeBlogTranscribePlansAPI Keys

YouTube-Transkript in Node.js: Native fetch, Keine npm-Installation

Node.js-Code, der ein YouTube-Transkript mit der eingebauten fetch API abruft

Du brauchst keine Verpackung dafür. Ein YouTube-Transkript in Node.js abzurufen ist ein HTTPS-Aufruf, fetch ist global seit Node 18, und der Endpunkt spricht reines JSON. Alles in diesem Beitrag läuft in einem leeren Verzeichnis ohne package.json — am Ende hast du eine transcribe()-Funktion, die Titel, Veröffentlichungsdatum und vollständigen Transkript-Text für jede YouTube-URL zurückgibt, mit Fehlerbehandlung, die nicht rät.

Die npm-Registry hat ein Dutzend Transkript-Scraper, und sie teilen ein Schicksal: sie holen von YouTube mit deiner Server-IP, und YouTube blockiert Rechenzentrum-IPs. Eine gehostete API umgeht das völlig.

Die Ganze Sache

const KEY = process.env.YT2TEXT_KEY;

async function transcribe(videoUrl, maxChars = 150000) {
  const qs = new URLSearchParams({ url: videoUrl, maxChars: String(maxChars) });
  const res = await fetch(`https://youtube2text.org/api/transcribe?${qs}`, {
    headers: { "x-api-key": KEY },
  });
  const body = await res.json();
  if (!res.ok) {
    const err = new Error(`${body.error.code}: ${body.error.message}`);
    err.code = body.error.code;
    err.retryAfterSeconds = body.error.retryAfterSeconds;
    throw err;
  }
  return body.result;
}

const t = await transcribe("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
console.log(`${t.title} — ${t.contentSize} chars`);
console.log(t.content.slice(0, 300));

Speichern als index.mjs (Top-Level-Await möchte ESM), führe node index.mjs aus. Der url-Parameter nimmt jede YouTube-URL-Variante oder eine nackte 11-stellige Video-ID, und maxChars begrenzt die Transkript-Länge — 150000 ist sowohl der Standard als auch die Obergrenze, daher trim it down, wenn der Text in einen LLM-Prompt geht.

Noch keinen Schlüssel? Grab den Demo:

curl https://youtube2text.org/api/demo-key

Es gibt {"success":true,"apiKey":"yt_..."} zurück. Sei gewarnt, dass er über alle anonymen Benutzer geteilt wird und auf 5 Videos pro Monat pro IP begrenzt ist — ein Reifen-Kicken-Schlüssel, nicht einer Produktion.

Fehler sind JSON, daher behandle sie so

Jeder Fehler hat ein stabiles code-Feld. Die, die es wert sind, zu branchen:

try {
  await transcribe("https://youtu.be/xxxxxxxxxxx");
} catch (err) {
  switch (err.code) {
    case "RATE_LIMIT_EXCEEDED":
      console.log(`Back off for ${err.retryAfterSeconds}s, then retry`);
      break;
    case "TRANSCRIPT_UNAVAILABLE":
      console.log("Video has no captions — nothing to fetch, skip it");
      break;
    case "VIDEO_NOT_FOUND":
    case "INVALID_URL":
      console.log("Bad input, fix the URL");
      break;
    default:
      throw err; // UNAUTHORIZED, YOUTUBE_ERROR — genuinely unexpected
  }
}

TRANSCRIPT_UNAVAILABLE ist die ehrliche Begrenzung des ganzen Ansatzes: Transkripte stammen von YouTubes eigenen Untertitelspuren, manuell oder automatisch generiert, Englisch bevorzugt mit Fallback zu welche Sprache auch immer vorhanden ist. Ein Video mit deaktivierten Untertiteln gibt einen 404 zurück und es gibt nichts zu retry. Handhabe es als ein normaler Fall, nicht ein Exception-Pfad.

TypeScript, wenn das deine Sache ist

Die Response-Form ist stabil, daher ein Paar Interfaces kriegen dir volle Type-Sicherheit mit Null-Abhängigkeiten:

interface TranscriptResult {
  videoId: string;
  title: string;
  pubDate: string;
  content: string;
  contentSize: number;
  truncated: boolean;
}

interface ApiError {
  code: string;
  message: string;
  status: number;
  retryAfterSeconds?: number;
}

Typ body als { result: TranscriptResult } | { error: ApiError } und engpass auf res.ok. Kein any, keine Casting.

Was das einstöpselt

Die meisten Menschen, die das von Node anrufen, füttern Transkripte ein einer Sprachmodell oder einer Content-Pipeline — Vorträge in Entwürfe umzuwandeln ist covered in YouTube-Video zu Blog-Beitrag, und wenn dein Agent-Framework MCP spricht, kannst du die HTTP-Ebene völlig mit dem MCP-Server für Claude und Codex überspringen. Der gleiche Endpunkt funktioniert identisch von Python, wenn dein Stack gemischt ist — siehe die Python-Version.

Die vollständige Parameter- und Fehler-Referenz lebt bei youtube2text.org/api.md. Es wird geschrieben für Maschinen zum Lesen, das als Seiteneffekt es barmherzig kurz für Menschen auch macht.