Transcription YouTube en Golang : net/http et trois structs

Voici l'intégralité du programme. Explication après.
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, c'est fait. Pas de modules tiers, c'est comme récupérer une transcription YouTube en Golang devrait fonctionner — l'API est du HTTPS pur retournant du JSON, donc net/http et encoding/json couvrent tout. Il n'existe pas de bibliothèque Go officielle pour cela, et je dirais que c'est une fonctionnalité.
L'astuce de l'enveloppe
Les réponses de succès mettent les données sous result ; les défaillances mettent un objet structuré sous error. Décoder les deux dans une struct avec deux champs pointeur signifie qu'un seul appel Decode gère chaque réponse — quel que soit le pointeur non-nil, c'est votre réponse. Pas de relecture du corps, pas de reniflement du Content-Type, et env.Error.Status correspond au code d'état HTTP si vous voulez double-vérifier.
Codes qui méritent une instruction switch
APIError.Code est stable, donc branchezdessu plutôt que sur les chaînes de message :
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 est celui que les gens traitent mal. Les transcriptions proviennent des pistes de sous-titres de YouTube — manuelles ou générées automatiquement, l'anglais préféré, première langue disponible sinon. Si une vidéo a les sous-titres désactivés, il n'y a pas de transcription à récupérer, et réessayer avec backoff exponentiel ne fera pas pousser de sous-titres. Traitez-la comme un skip permanent dans les tâches batch, ou votre file d'attente de workers se remplit de zombies.
Paramètres et clés
Deux paramètres de requête au total. url accepte n'importe quelle forme d'URL YouTube ou un identifiant nu de 11 caractères. maxChars limite la longueur de la sortie (150000 est la valeur par défaut et le maximum) — utile quand la transcription alimente un LLM et que vous payez par jeton, ce qui est la plupart des cas d'utilisation Go que j'entends, généralement RAG sur un canal entier.
Pour une clé sans aucune inscription, curl https://youtube2text.org/api/demo-key retourne une clé fonctionnelle — partagée entre tous les utilisateurs anonymes à 5 vidéos par mois par IP, donc c'est strictement pour essayer les choses. Si vous pesez cela par rapport à invoquer yt-dlp pour les fichiers de sous-titres, j'ai écrit une comparaison des sous-titres yt-dlp vs l'API ; et si une partie de votre pile est Node, l'même appel en JavaScript est encore plus court.
Pour une utilisation réelle, connectez-vous avec Google sur youtube2text.org/app/keys — pas de carte, pas de téléphone, une limite gratuite de 5 vidéos par mois, les plans payants de $5.99 pour 50 jusqu'à $19.99 illimité. Le code Go ci-dessus ne change pas ; seule la variable d'environnement change.