HomeBlogTranscribePlansAPI Keys

YouTube-Transkript in Golang: net/http und drei Structs

Go-Programm, das eine YouTube-Transkript-API-Antwort in Structs dekodiert

Hier ist das ganze Programm. Erklärung danach.

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
	"time"
)

type Transcript struct {
	VideoID     string `json:"videoId"`
	Title       string `json:"title"`
	PubDate     string `json:"pubDate"`
	Content     string `json:"content"`
	ContentSize int    `json:"contentSize"`
	Truncated   bool   `json:"truncated"`
}

type APIError struct {
	Code              string `json:"code"`
	Message           string `json:"message"`
	Status            int    `json:"status"`
	RetryAfterSeconds int    `json:"retryAfterSeconds"`
}

type envelope struct {
	Result *Transcript `json:"result"`
	Error  *APIError   `json:"error"`
}

func main() {
	q := url.Values{}
	q.Set("url", "https://www.youtube.com/watch?v=dQw4w9WgXcQ")

	req, err := http.NewRequest(http.MethodGet,
		"https://youtube2text.org/api/transcribe?"+q.Encode(), nil)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	req.Header.Set("x-api-key", os.Getenv("YT2TEXT_KEY"))

	client := &http.Client{Timeout: 60 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	defer resp.Body.Close()

	var env envelope
	if err := json.NewDecoder(resp.Body).Decode(&env); err != nil {
		fmt.Fprintln(os.Stderr, "decode:", err)
		os.Exit(1)
	}

	if env.Error != nil {
		fmt.Fprintf(os.Stderr, "%s: %s\n", env.Error.Code, env.Error.Message)
		os.Exit(1)
	}

	fmt.Println(env.Result.Title)
	fmt.Printf("%d chars, truncated=%v\n",
		env.Result.ContentSize, env.Result.Truncated)
}

go run main.go, fertig. Keine Module von Drittanbietern, das ist, wie es sein sollte, ein YouTube-Transkript in Golang zu bekommen — die API ist reines HTTPS, das JSON zurückgibt, also net/http und encoding/json decken alles ab. Es gibt keine offizielle Go-Bibliothek dafür, und ich würde argumentieren, dass das eine Funktion ist.

Der Hüllen-Trick

Erfolgreich-Antworten legen Daten unter result; Fehler legen ein strukturiertes Objekt unter error. Das Dekodieren beider in eine Struktur mit zwei Zeiger-Feldern bedeutet, ein einzelner Decode-Aufruf handhabt jede Antwort — welcher Zeiger nicht-nil ist, ist deine Antwort. Kein erneutes Lesen des Body, kein Schnüffeln in Content-Type, und env.Error.Status passt zum HTTP-Status, wenn du doppelt überprüfen willst.

Codes, die es wert sind, eine Switch-Anweisung

APIError.Code ist stabil, daher branchen darauf statt auf Message-Zeichenketten:

switch env.Error.Code {
case "RATE_LIMIT_EXCEEDED":
	wait := time.Duration(env.Error.RetryAfterSeconds) * time.Second
	time.Sleep(wait) // then retry the request
case "TRANSCRIPT_UNAVAILABLE":
	// video exists but has no caption track — skip permanently
case "VIDEO_NOT_FOUND", "INVALID_URL":
	// bad input; log and move on
default:
	// UNAUTHORIZED, VALIDATION_ERROR, YOUTUBE_ERROR
}

TRANSCRIPT_UNAVAILABLE ist der, den Leute falsch handhaben. Transkripte stammen aus Youtubes Untertitelspuren — manuell oder automatisch generiert, Englisch bevorzugt, erste verfügbare Sprache sonst. Wenn ein Video Untertitel ausgeschaltet hat, gibt es kein Transkript zum Abrufen, und erneut Versuchen mit exponentieller Backoff wird nicht Untertitel wachsen lassen. Behandle es als permanentes Überspringen in Batch-Jobs, oder deine Worker-Queue füllt sich mit Zombies.

Parameter und Schlüssel

Zwei Abfrage-Parameter insgesamt. url nimmt jede YouTube-URL-Form oder eine nackte 11-stellige ID. maxChars begrenzt die Ausgabelänge (150000 ist Standard und Maximum) — nützlich, wenn das Transkript einen LLM füttert und du pro Token bezahlst, das ist die meisten Go-Use-Cases, die ich höre, normalerweise RAG über einen ganzen Kanal.

Für einen Schlüssel ohne Anmeldung gibt curl https://youtube2text.org/api/demo-key einen funktionierenden zurück — geteilt über alle anonymen Benutzer bei 5 Videos pro Monat pro IP, daher ist es streng zum Ausprobieren. Wenn du überwiegst, das gegen die Nutzung von yt-dlp für Untertiteldateien zu verwenden, schrieb ich einen Vergleich von yt-dlp-Untertiteln vs die API; und wenn Teil deines Stacks Node ist, der gleiche Aufruf in JavaScript ist noch kürzer.

Für echte Nutzung melde dich mit Google bei youtube2text.org/app/keys an — keine Karte, kein Telefon, kostenlose Stufe von 5 Videos pro Monat, bezahlte Stufen von $5,99 für 50 bis $19,99 unbegrenzt. Der Go-Code oben ändert sich nicht; nur die Umgebungsvariable.