Transcription YouTube en Node.js : fetch natif, pas d'installation npm

Vous n'avez pas besoin d'un package pour cela. Récupérer une transcription YouTube en Node.js c'est un seul appel HTTPS, fetch est global depuis Node 18, et le point de terminaison parle du JSON pur. Tout dans cet article s'exécute dans un répertoire vide sans package.json — à la fin, vous aurez une fonction transcribe() qui retourne le titre, la date de publication et le texte de transcription complet pour n'importe quelle URL YouTube, avec une gestion des erreurs qui ne devine pas.
Le registre npm a une douzaine de gratteurs de transcription, et ils partagent un sort : ils récupèrent YouTube en utilisant l'IP de votre serveur, et YouTube bloque les IP de centre de données. Une API hébergée contourne entièrement cela.
Le tout
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));
Enregistrez en tant que index.mjs (await de niveau supérieur veut ESM), exécutez node index.mjs. Le paramètre url accepte n'importe quelle variante d'URL YouTube ou un identifiant vidéo nu de 11 caractères, et maxChars limite la longueur de la transcription — 150000 est à la fois la valeur par défaut et le plafond, donc réduisez-le quand le texte va dans un prompt LLM.
Pas encore de clé ? Attrapez la démo :
curl https://youtube2text.org/api/demo-key
Elle retourne {"success":true,"apiKey":"yt_..."}. Soyez averti qu'elle est partagée entre tous les utilisateurs anonymes et limitée à 5 vidéos par mois par IP — une clé de test de pneus, pas une clé de production.
Les erreurs sont JSON, traitez-les comme telles
Chaque défaillance a un champ code stable. Ceux qui valent la peine de brancher sur :
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 est l'honnête limitation de toute l'approche : les transcriptions proviennent des propres pistes de sous-titres de YouTube, manuelles ou auto-générées, l'anglais préféré avec repli à quelle que soit la langue qui existe. Une vidéo avec sous-titres désactivés retourne un 404 et il n'y a rien à réessayer. Traitez-la comme un cas normal, pas un chemin d'exception.
TypeScript, si c'est votre truc
La forme de la réponse est stable, donc quelques interfaces vous obtiennent la sécurité de type complète avec zéro dépendances :
interface TranscriptResult {
videoId: string;
title: string;
pubDate: string;
content: string;
contentSize: number;
truncated: boolean;
}
interface ApiError {
code: string;
message: string;
status: number;
retryAfterSeconds?: number;
}
Typez body comme { result: TranscriptResult } | { error: ApiError } et réduisez sur res.ok. Pas de any, pas de casting.
Ce que cela se branche sur
La plupart des gens appelant cela de Node alimentent les transcriptions à un modèle de langage ou un pipeline de contenu — transformer les discours en brouillons est couvert dans vidéo YouTube en article de blog, et si votre framework d'agent parle MCP vous pouvez ignorer complètement la couche HTTP avec le serveur MCP pour Claude et Codex. Le même point de terminaison fonctionne de manière identique à partir de Python si votre pile est mixte — voir la version Python.
La référence complète du paramètre et de l'erreur se trouve sur youtube2text.org/api.md. C'est écrit pour les machines pour lire, ce qui par effet secondaire la rend merveilleusement courte pour les humains aussi.