Transkrypcja YouTube w Node.js: Natywny fetch, Brak npm Install

Nie potrzebujesz pakietu do tego. Pobieranie transkrypcji YouTube w Node.js to jedno wywołanie HTTPS, fetch była globalna od Node 18, a punkt końcowy mówi zwykły JSON. Wszystko w tym poście działa w pustym katalogu bez package.json — na koniec będziesz mieć funkcję transcribe() zwracającą tytuł, datę publikacji i pełny tekst transkrypcji dla każdego adresu URL YouTube, z obsługą błędów, która nie zgaduje.
Rejestr npm ma tuzin transcriptorów, i dzielą los: pobierają z YouTube za pomocą IP Twojego serwera, a YouTube blokuje IP centrum danych. Hostowany API całkowicie to pomija.
Całe to
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));
Zapisz jako index.mjs (najwyższy poziom await chce ESM), uruchom node index.mjs. Parametr url przyjmuje każdą odmianę URL YouTube lub gołe 11-znakowe id wideo, a maxChars ogranicza długość transkrypcji — 150000 to zarówno domyślna, jak i górna granica, więc przyciosaj to, gdy tekst idzie do promptu LLM.
Brak klucza jeszcze? Weź demo:
curl https://youtube2text.org/api/demo-key
Zwraca {"success":true,"apiKey":"yt_..."}. Bądź ostrzegany, że jest wspólny dla wszystkich anonimowych użytkowników i ograniczony do 5 filmów na miesiąc na IP — klucz kopania opon, nie produkcyjny.
Błędy to JSON, traktuj je jako takie
Każde niepowodzenie ma stabilne pole code. Te godne rozgałęzienia:
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 to szczera ograniczenie całego podejścia: transkrypcje pochodzą z pasów napisów YouTube, ręczny lub autogenerowany, angielski preferowany z rezerwą na niezależnie jaki język istnieje. Film z wyłączonymi napisami zwraca 404 i nie ma nic do ponownej próby. Obsługuj to jako normalny przypadek, nie ścieżkę wyjątku.
TypeScript, jeśli to Twoja rzecz
Kształt odpowiedzi jest stabilny, więc parę interfejsów daje Ci pełną bezpieczeństwo typu z zerem zależności:
interface TranscriptResult {
videoId: string;
title: string;
pubDate: string;
content: string;
contentSize: number;
truncated: boolean;
}
interface ApiError {
code: string;
message: string;
status: number;
retryAfterSeconds?: number;
}
Wpisz body jako { result: TranscriptResult } | { error: ApiError } i zawęź na res.ok. Brak any, brak rzutowania.
Co to podłącza
Większość ludzi wywoływania tego z Node karmi transkrypcje do modelu języka lub rurociągu zawartości — zamienianie rozmów w projekty jest pokryte w YouTube video to blog post, a jeśli Twoja struktura agenta mówi MCP możesz pominąć warstwę HTTP całkowicie za pomocą serwera MCP dla Claude i Codex. Ten sam punkt końcowy działa identycznie z Python, jeśli Twój stos jest mieszany — zobacz wersję Python.
Pełne odniesienie parametru i błędu znajduje się na youtube2text.org/api.md. Jest napisane dla maszyn do czytania, co jako efekt uboczny czyni to cudownie krótko dla ludzi zbyt.