YouTube Transcript i Node.js: Innebygd fetch, ingen npm install

Du trenger ikke en pakke for dette. Å hente en YouTube-transkripsjon i Node.js er ett HTTPS-kall, fetch har vært globalt siden Node 18, og endepunktet snakker vanlig JSON. Alt i denne posten kjører i en tom katalog uten package.json — på slutten får du en transcribe()-funksjon som returnerer tittel, publiserings-dato, og full transkripsjon-tekst for noen YouTube-URL, med feilhåndtering som ikke gjetter.
npm-registeret har et dusin transkripsjon-skrapere, og de deler et skjebne: de henter fra YouTube ved bruk av serveren din IP, og YouTube blokkerer datasenter-IP-er. En hostet API omgår det helt.
Det hele
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));
Lagre som index.mjs (topp-nivå venter ønsker ESM), kjør node index.mjs. url-parameteren tar hvilken som helst YouTube-URL-variant eller en bare 11-tegn video-id, og maxChars begrenser transkripsjonslengden — 150000 er både standard og tak, så trimm det ned når teksten skal inn i en LLM-prompt.
Ingen nøkkel ennå? Grabb demoen:
curl https://youtube2text.org/api/demo-key
Den returnerer {"success":true,"apiKey":"yt_..."}. Vær oppmerksom på at den deles på tvers av alle anonyme brukere og begrenset til 5 videoer per måned per IP — en dekk-sparke nøkkel, ikke en produksjon.
Feil er JSON, så behandle dem slik
Hver feil har et stabilt code-felt. De verdt å forgrene 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 er den ærlige begrensningen for hele tilnærmingen: transkripsjoner kommer fra YouTubes egne undertekstspor, manuell eller auto-generert, engelsk foretrukket med fallback til hvilket som helst språk som finnes. En video med tekst deaktivert returnerer 404 og det finnes ingenting å prøve på nytt. Håndter det som en normal sak, ikke en unntak-sti.
TypeScript, hvis det er din ting
Respons-formen er stabil, så et par grensesnitt får deg full type-sikkerhet med null avhengigheter:
interface TranscriptResult {
videoId: string;
title: string;
pubDate: string;
content: string;
contentSize: number;
truncated: boolean;
}
interface ApiError {
code: string;
message: string;
status: number;
retryAfterSeconds?: number;
}
Type body som { result: TranscriptResult } | { error: ApiError } og begrense på res.ok. Ingen any, intet casting.
Hva dette plugges inn i
De fleste som ringer dette fra Node mater transkripsjoner til en språkmodell eller en innholds-rørledning — å gjøre snakk til utkast dekkes i YouTube-video til blogg-post, og hvis agent-rammeverket ditt snakker MCP kan du hoppe hele HTTP-laget helt med MCP-serveren for Claude og Codex. Det samme endepunktet fungerer identisk fra Python hvis stakken din er blandet — se Python-versjonen.
Den fulle parameter og feil-referanse bor på youtube2text.org/api.md. Det er skrevet for maskiner å lese, som som bivirkning gjør det barmhjertig kort for mennesker også.