HomeBlogTranscribePlansAPI Keys

YouTube Transcript i C# med HttpClient og Records

C#-konsoll-app som deserialiserer en YouTube-transkripsjon med System.Text.Json

Fra dotnet run til en trykt transkripsjon tok om lag to sekunder på maskinen min, og det meste av det var nettverks-rundturen. Ingen NuGet-pakker vises noe sted i denne posten — å få en YouTube-transkripsjon i C# er ett GET-kall, og HttpClient pluss System.Text.Json har sendt i boksen i årevis. På slutten får du en komplett konsoll-app med post-typer for responsen, en asynkron Main, og feilhåndtering som leser det strukturerte feilobjektet til APIen i stedet for å gjette fra statuskoder.

Tre poster

APIen returnerer {"result": {...}} ved suksess og {"error": {...}} ved feil, så modeller konvolutten direkte:

public record Transcript(
    string VideoId,
    string Title,
    string PubDate,
    string Content,
    int ContentSize,
    bool Truncated);

public record ApiError(
    string Code,
    string Message,
    int Status,
    int? RetryAfterSeconds);

public record Envelope(Transcript? Result, ApiError? Error);

Et Deserialize<Envelope>-kall håndterer hver respons. Hvilken som helst eiendom som ikke er null er svaret ditt. RetryAfterSeconds kan være null fordi bare rate-limit-feil bærer det.

Programmet

Sikter på .NET 8, fungerer som-er på 6 og 7:

using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;

public static class Program
{
    private static readonly HttpClient Http = new();
    private static readonly JsonSerializerOptions Json =
        new(JsonSerializerDefaults.Web);

    public static async Task Main(string[] args)
    {
        var videoUrl = args.Length > 0
            ? args[0]
            : "https://www.youtube.com/watch?v=dQw4w9WgXcQ";

        var request = new HttpRequestMessage(HttpMethod.Get,
            "https://youtube2text.org/api/transcribe" +
            $"?url={Uri.EscapeDataString(videoUrl)}&maxChars=40000");
        request.Headers.Add("x-api-key",
            Environment.GetEnvironmentVariable("YT2TEXT_KEY"));

        var response = await Http.SendAsync(request);
        var envelope = JsonSerializer.Deserialize<Envelope>(
            await response.Content.ReadAsStringAsync(), Json);

        if (envelope?.Error is { } err)
        {
            Console.Error.WriteLine($"{err.Code}: {err.Message}");
            if (err.RetryAfterSeconds is int wait)
                Console.Error.WriteLine($"Retry after {wait}s");
            Environment.Exit(1);
        }

        var t = envelope!.Result!;
        Console.WriteLine($"{t.Title} ({t.ContentSize} chars, truncated: {t.Truncated})");
        Console.WriteLine(t.Content[..Math.Min(t.Content.Length, 400)]);
    }
}

JsonSerializerDefaults.Web kartlegger APIens camelCase-felt til PascalCase-post-egenskaper, så det er ikke et eneste [JsonPropertyName]-attributt i synet. url-parameteren godtar hver YouTube-URL-variant pluss bare 11-tegn-id-er, og headeren kan være Authorization: Bearer yt_... i stedet for x-api-key hvis det passer din mellomvare bedre.

Om den maxChars=40000

maxChars begrenser transkripsjonslengden; 150000 er både standard og hard tak. Hvis videoens undertekster kjører forbi ditt tak, kommer Truncated tilbake true og du får de første N tegn — så sjekk flagget før du antar at du har hele teksten. Jeg satte 40000 i eksemplet fordi disse transkripsjoner vanligvis ender opp i en LLM-prompt, og ved omtrent fire tegn per token er det et 10k-token-budsjett. Hvis modellkallene dine går gjennom OpenAI Responses API, er det en måte å hoppe over hele HTTP-rørsystemet helt på via MCP-serveren med OpenAI; Anthropic-ekvivalenten er i bruk av transkripsjoner med Claude API.

Feilkoder å forgrene seg på

ApiError.Code er en stabil streng: UNAUTHORIZED (401), VALIDATION_ERROR og INVALID_URL (400), VIDEO_NOT_FOUND og TRANSCRIPT_UNAVAILABLE (404), RATE_LIMIT_EXCEEDED (429), YOUTUBE_ERROR (500). Den som overrasker folk er TRANSCRIPT_UNAVAILABLE: transkripsjoner kommer fra YouTubes undertekstspor, og en video hvis eier deaktiverte tekst har ingen å returnere — ingen retry-policy reparerer det. Mønster-match på koden, behandle som permanent hopp.

For en null-innmelding test-nøkkel, GET https://youtube2text.org/api/demo-key — den deles og er begrenset til 5 videoer per måned per IP, så det er bare for eksperimenter. Hvis Go også er i stakken din, bruker samme kall i Golang det identiske konvolutt-trikset.

Den komplette maskin-lesbare referanse — hver parameter, hver feil, klar til å lime inn i en systemprompt — er på youtube2text.org/api.md.