YouTube Transkription i Node.js: Inbyggd fetch, ingen npm-installation

Du behöver inte ett paket för detta. Att hämta en YouTube-transkription i Node.js är ett HTTPS-anrop, fetch har varit globalt sedan nod 18, och slutpunkten talar ren JSON. Allt i det här inlägget körs i en tom katalog utan package.json — i slutet har du en transcribe()-funktion som returnerar titel, publiceringsdatum och fullständig transkriptionstext för valfri YouTube URL, med felhantering som inte gissar.
npm-registret har ett dussin transkriptionskrapare, och de delar ett öde: de hämtar från YouTube med hjälp av din servers IP, och YouTube blockerar datacenter-IP:ar. Ett hosted API förbigår det helt.
Allt tillsammans
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));
Spara som index.mjs (toppnivå-await vill ha ESM), kör node index.mjs. Parametern url tar valfri YouTube URL-variant eller ett enkelt 11-tecken video-id, och maxChars begränsar transkriptionslängden — 150000 är både standard och tak, så trimma det ned när texten är på väg in i en LLM-prompt.
Ingen nyckel ännu? Ta demo-nyckeln:
curl https://youtube2text.org/api/demo-key
Det returnerar {"success":true,"apiKey":"yt_..."}. Varning innan: det delas över alla anonyma användare och begränsas till 5 videor per månad per IP — en däckkicking-nyckel, inte en produktionnyckel.
Fel är JSON, så behandla dem som sådan
Varje misslyckande har ett stabilt code-fält. De värda att grena på:
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 är den ärliga begränsningen av hela tillvägagångssättet: transkriptioner kommer från Youtubes egna bildtextsspår, manuella eller automatiskt genererade, engelska föredraget med återgång till vilket språk som helst existerar. En video med bildtexter inaktiverad returnerar en 404 och det finns ingenting att omprövning. Hantera det som ett normalt fall, inte en undantagväg.
TypeScript, om det är din grej
Svarsformen är stabil, så ett par gränssnitt får dig full typsäkerhet utan beroenden:
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 som { result: TranscriptResult } | { error: ApiError } och trång på res.ok. Ingen any, ingen casting.
Vad detta anslutas till
De flesta som anropar detta från Node matar transkriptioner till en språkmodell eller en innehållspipeline — att förvandla samtal till utkast täcks i YouTube-video till blogginlägg, och om din agentramverk talar MCP kan du helt hoppa över HTTP-lagret med MCP-servern för Claude och Codex. Samma slutpunkt fungerar identiskt från Python om din stack är blandad — se Python-versionen.
Den fullständiga parameter- och felreferensen lever på youtube2text.org/api.md. Det är skrivet för maskiner att läsa, vilket som bieffekt gör det medvetet kort för människor också.