YouTube Transcript i Ruby: Net::HTTP og null småbiter

Ruby-refleksen er bundle add noe før du skriver en linje kode. Mål det i fem minutter: å hente en YouTube-transkripsjon i Ruby trenger ingenting utenfor standardbiblioteket, fordi APIen er ett HTTPS GET som returnerer JSON, og net/http pluss json har sittet i hver Ruby-installasjon siden for alltid. På slutten av denne posten får du et skript som tar noen YouTube-URL og skriver ut video-tittelen og transkripsjonen, med en case-setning som dekker hver feil APIen returnerer — og et tomt Gemfile.
Ja, Net::HTTP-grensesnittet er like klumpete som sitt rykte. Det er fremdeles bare tjue linjer.
Skriptet
require "net/http"
require "json"
require "uri"
uri = URI("https://youtube2text.org/api/transcribe")
uri.query = URI.encode_www_form(
url: "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
)
req = Net::HTTP::Get.new(uri)
req["x-api-key"] = ENV.fetch("YT2TEXT_KEY")
res = Net::HTTP.start(uri.hostname, uri.port,
use_ssl: true, read_timeout: 60) do |http|
http.request(req)
end
data = JSON.parse(res.body)
if res.is_a?(Net::HTTPSuccess)
transcript = data["result"]
puts transcript["title"]
puts "#{transcript['contentSize']} chars, truncated: #{transcript['truncated']}"
puts transcript["content"][0, 400]
else
err = data["error"]
case err["code"]
when "RATE_LIMIT_EXCEEDED"
puts "Rate limited. Retry in #{err['retryAfterSeconds']}s."
when "TRANSCRIPT_UNAVAILABLE"
puts "No captions on this video. Skip it."
when "VIDEO_NOT_FOUND", "INVALID_URL"
puts "Bad video reference: #{err['message']}"
else
abort "#{err['code']}: #{err['message']}"
end
end
url-parameteren er tillatende — full se URL-er, youtu.be korte lenker, shorts, eller en bare 11-tegn video-id all arbeid. Legg til maxChars: 20000 til encode_www_form hvis transkripsjonen er påvei til en LLM-prompt og du heller ikke ville betale for en tre-times podcast verdt tokens; 150000 er standard og maksimum.
Hvis kodebasis allerede har Faraday eller httparty, OK, bruk dem — forespørselen er samme tre ingredienser: endepunktet, en query-streng og en header. Snakker om som, req["Authorization"] = "Bearer #{key}" fungerer identisk til x-api-key hvis bearer-tokens passer oppsettet ditt bedre.
En nøkkel i en kommando
curl https://youtube2text.org/api/demo-key
Det returnerer {"success":true,"apiKey":"yt_..."} med ingen konto, ingen e-post, ingenting. Fangsten: den er en delt nøkkel for alle anonyme brukere, begrenset til 5 videoer per måned per IP. Flott for å verifisere at skriptet fungerer, galt for noe du ville distribuert.
Hva transkripsjonen egentlig er
Verdt å være klar-øyet her: teksten kommer fra YouTubes undertekstspor. Manuelt lastet opp tekst leser vakkert; auto-generert en forvirrer av og til sjargong og produktnavn, og det er ingenting noen API kan gjøre om det oppstrøms. Engelsk spor foretrukket, med fallback til første tilgjengelige språk. Og en video med tekst deaktivert returnerer TRANSCRIPT_UNAVAILABLE — case-grenen ovenfor behandler det som en hopp, ikke en retry, fordi å prøve igjen en video som ikke har tekst er en veldig tålmodig måte å oppnå ingenting på.
Hvor Rubyister tar det
Mønsteret jeg ser mest er batch-prosessering: løkke over en kanals video-id-er, hent hver transkripsjon, mater den til noe nedstrøms. Studenter gjør forelesnings-videoer til studienota; hvis nedstrøms er Claude, gratis transkripsjoner i Claude gjennomgang forbinder de to uten egendefinert lim. Det samme endepunktet fra PHP er nesten linje-for-linje identisk — sammenligning her hvis laget ditt kjører begge deler.
Når den delte demo-nøkkelen blir tørket, logg inn med Google på youtube2text.org/app/keys — intet telefon, intet kort. Du får din egen gratis nøkkel på 5 videoer per måned, med betalte nivåer fra $5.99 for 50 til $19.99 ubegrenset. Skriptet endrer seg ikke; ENV["YT2TEXT_KEY"] gjør det.