HomeBlogTranscribePlansAPI Keys

Trascrizione YouTube in Golang: net/http e Tre Struct

Programma Go che decodifica una risposta dell'API YouTube Transcript in struct

Ecco l'intero programma. Spiegazione dopo.

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, fatto. Nessun modulo di terze parti, il che è il modo in cui ottenere una trascrizione YouTube in Golang dovrebbe sembrare — l'API è HTTPS semplice che restituisce JSON, quindi net/http e encoding/json coprono tutto. Non c'è una libreria Go ufficiale per questo, e sostengo che sia una caratteristica.

Il trucco dell'envelope

Le risposte di successo mettono i dati sotto result; i fallimenti mettono un oggetto strutturato sotto error. Decodificare entrambi in una struct con due campi puntatore significa che una singola chiamata Decode gestisce ogni risposta — qualunque puntatore sia non-nil è la tua risposta. Nessuna riletttura del corpo, nessun annusamento di Content-Type, e env.Error.Status corrisponde allo stato HTTP se vuoi fare una doppia verifica.

Codici che meritano un'istruzione switch

APIError.Code è stabile, quindi fai il branch su di esso piuttosto che su stringhe di messaggi:

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 è quello che le persone gestiscono male. Le trascrizioni provengono dai tracciamenti didascalici di YouTube — manuali o generati automaticamente, inglese preferito, primo linguaggio disponibile altrimenti. Se un video ha le didascalie disattivate, non c'è trascrizione da recuperare, e il ritentativo con backoff esponenziale non farà crescere le didascalie. Trattalo come un salto permanente nei lavori batch, o la tua coda di worker si riempie di zombie.

Parametri e chiavi

Due parametri di query in totale. url accetta qualsiasi forma di URL YouTube o un ID nudo di 11 caratteri. maxChars limita la lunghezza dell'output (150000 è il valore predefinito e massimo) — utile quando la trascrizione alimenta un LLM e stai pagando per token, il che è la maggior parte dei casi d'uso Go che sento, di solito RAG su un intero canale.

Per una chiave senza alcuna iscrizione, curl https://youtube2text.org/api/demo-key ne restituisce una funzionante — condivisa tra tutti gli utenti anonimi a 5 video al mese per IP, quindi è strettamente per provare cose. Se stai valutando questo rispetto a lanciare yt-dlp per i file di sottotitoli, ho scritto un confronto tra i sottotitoli yt-dlp e l'API; e se parte del tuo stack è Node, la stessa chiamata in JavaScript è ancora più breve.

Per un uso reale, accedi con Google su youtube2text.org/app/keys — nessuna carta, nessun telefono, livello gratuito di 5 video al mese, livelli a pagamento da $ 5,99 per 50 fino a $ 19,99 illimitati. Il codice Go precedente non cambia; solo la variabile env lo fa.