HomeBlogTranscribePlansAPI Keys

YouTube Transkription i Ruby: Net::HTTP och noll juveler

Ruby-skript som tolkar ett YouTube transkriptions-API-svar med standardbiblioteket

Ruby-reflexen är bundle add något innan du skriver en kodrad. Motstå den i fem minuter: att hämta en YouTube-transkription i Ruby behöver ingenting utanför standardbiblioteket, för API:t är ett HTTPS GET som returnerar JSON, och net/http plus json har suttit i varje Ruby-installation sedan evigt. I slutet av det här inlägget har du ett skript som tar valfri YouTube URL och skriver ut videotiteln och transkriptionen, med ett case-uttalande som täcker varje fel API:t returnerar — och en tom Gemfile.

Ja, Net::HTTP:s gränssnitt är så skrynkligt som sitt rykte. Det är fortfarande bara tjugo rader.

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

Parametern url är förlåtande — fullständiga watch-URL:er, youtu.be korta länkar, shorts, eller ett enkelt 11-tecken video-id alla fungerar. Lägg till maxChars: 20000 till encode_www_form om transkriptionen är på väg in i en LLM-prompt och du snarare inte vill betala för en tre-timmars poddcasts värd tokens; 150000 är standard och maximum.

Om din kodbase redan har Faraday eller httparty, bra, använd dem — begäran är samma tre ingredienser: slutpunkten, en frågesträng och en header. Talat om vilket, req["Authorization"] = "Bearer #{key}" fungerar identiskt till x-api-key om bärtokens passar din inställning bättre.

En nyckel i ett kommando

curl https://youtube2text.org/api/demo-key

Det returnerar {"success":true,"apiKey":"yt_..."} utan konto, utan e-post, ingenting. Fångsten: det är en delad nyckel för alla anonyma användare, begränsad till 5 videor per månad per IP. Bra för att verifiera skriptet fungerar, fel för allt du skulle distribuera.

Vad transkriptionen faktiskt är

Värt att vara klarsynt här: texten kommer från Youtubes bildtextsspår. Manuellt uppladdade bildtexter läser vackert; automatiskt genererade månglar ibland jargong och produktnamn, och det finns ingenting något API kan göra om det strömuppströms. Engelska spår föredraget, med återgång till det första tillgängliga språket. Och en video med inaktiverad bildtexter returnerar TRANSCRIPT_UNAVAILABLEcase-grenen ovan behandlar det som ett hopp, inte ett försök igen, för att försöka igen en video som har inga bildtexter är ett mycket tålmodig sätt att åstadkomma ingenting.

Vart Rubyists tar det här

Mönstret jag ser mest är batch-bearbetning: slinga över en kanals video-id:n, hämta varje transkription, mata dem till något nedströms. Studenter förvandlar föreläsningsvideos till studieanteckningar; om nedströms är Claude, fria transkriptioner i Claude genomgång förbinder de två utan anpassad lim. Samma slutpunkt från PHP är nästan rad-för-rad identisk — jämförelse här om ditt team kör båda.

När den delade demo-nyckeln torkade, logga in med Google på youtube2text.org/app/keys — ingen telefon, inget kort. Du får din egen gratis nyckel på 5 videor per månad, med betalda nivåer från $5,99 för 50 upp till $19,99 unlimited. Skriptet förändras inte; ENV["YT2TEXT_KEY"] gör.