YouTube Transcript i Golang: net/http og tre strukturer

Her er hele programmet. Forklaring etter.
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, ferdig. Ingen tredjeparts-moduler, som er hvordan å få en YouTube-transkripsjon i Golang burde se ut — APIen er ren HTTPS som returnerer JSON, så net/http og encoding/json dekker alt. Det finnes intet offisielt Go-bibliotek for dette, og jeg ville hevde det er en funksjon.
Konvolutt-trikset
Suksess-responser legger data under result; feil legger et strukturert objekt under error. Dekoding av begge inn i en struktur med to peker-felt betyr et enkelt Decode-kall håndterer hver respons — hvilken som helst peker som ikke er nil er svaret ditt. Ingen gjenlesing av kroppen, ingen sniffing av Content-Type, og env.Error.Status stemmer HTTP-statusen hvis du vil dobbeltsjekk.
Koder verdt en switch-setning
APIError.Code er stabil, så forgrene på den i stedet for på meldingsstrenger:
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 er den folk håndterer dårlig. Transkripsjoner kommer fra YouTubes undertekstspor — manuell eller auto-generert, engelsk foretrukket, første tilgjengelige språk ellers. Hvis en video har tekst slått av, er det ingen transkripsjon å hente, og forsøk på nytt med eksponentiell backoff vil ikke få tekst til å vokse. Behandle det som permanent hopp i batch-jobber, eller arbeidskøen din fyller seg med zombier.
Parametere og nøkkler
To query-parametere totalt. url tar hvilken som helst YouTube-URL-form eller en bare 11-tegn-id. maxChars begrenser utdatalengden (150000 er standard og maks) — nyttig når transkripsjonen mater en LLM og du betaler per token, som er mest Golang bruk saker jeg hører om, vanligvis RAG over en helt kanal.
For en nøkkel uten innmelding, curl https://youtube2text.org/api/demo-key returnerer en fungerende — delt på tvers av alle anonyme brukere på 5 videoer per måned per IP, så det er strengt for å prøve ting. Hvis du veier dette mot å shell ut til yt-dlp for undertekst-filer, skrev jeg en sammenligning av yt-dlp undertekster vs APIen; og hvis del av stakken er Node, samme kall i JavaScript er enda kortere.
For faktisk bruk, logg inn med Google på youtube2text.org/app/keys — intet kort, intet telefon, gratis nivå på 5 videoer per måned, betalte nivåer fra $5.99 for 50 og opp til $19.99 ubegrenset. Go-koden ovenfor endrer seg ikke; bare env var gjør det.