C#의 YouTube 스크립트 HttpClient 및 Records 사용

dotnet run에서 인쇄된 스크립트까지는 내 컴퓨터에서 약 2초가 걸렸고, 대부분은 네트워크 라운드 트립이었습니다. 이 게시물의 어디에도 NuGet 패키지가 나타나지 않습니다. C#에서 YouTube 스크립트를 얻는 것은 하나의 GET 요청이고, HttpClient 더하기 System.Text.Json은 수년 동안 상자에 포함되어 있습니다. 끝까지 응답에 대한 레코드 타입, 비동기 Main, 상태 코드에서 추측하는 대신 API의 구조화된 오류 개체를 읽는 오류 처리가 있는 완전한 콘솔 응용 프로그램이 있습니다.
3개의 레코드
API는 성공 시 {"result": {...}}를 반환하고 실패 시 {"error": {...}}를 반환하므로 봉투를 직접 모델링하십시오:
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);
하나의 Deserialize<Envelope> 호출이 모든 응답을 처리합니다. 어느 속성이 null이 아닌지는 당신의 대답입니다. RetryAfterSeconds는 속도 제한 오류만 이를 수행하기 때문에 nullable입니다.
프로그램
.NET 8을 대상으로 하며 6과 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은 API의 camelCase 필드를 PascalCase 레코드 속성에 매핑하므로 단일 [JsonPropertyName] 속성도 보이지 않습니다. url 매개변수는 모든 YouTube URL 변형과 11자 ID를 허용하고, 헤더가 미들웨어에 더 적합하면 x-api-key 대신 Authorization: Bearer yt_...일 수 있습니다.
maxChars=40000 정보
maxChars는 스크립트 길이를 제한합니다. 150000은 기본값과 하드 상한선입니다. 비디오의 캡션이 상한선을 넘으면 Truncated가 true로 돌아오고 첫 번째 N자를 얻습니다. 전체 텍스트가 있다고 가정하기 전에 플래그를 확인하세요. 이러한 스크립트는 보통 LLM 프롬프트로 끝나므로 예제에서 40000으로 설정했습니다. 대략 4자 = 토큰이므로 10k 토큰 예산입니다. 모델 호출이 OpenAI Responses API를 통해 이루어지면 OpenAI를 사용하는 MCP 서버를 통해 HTTP 배관을 완전히 건너뛸 수 있는 방법이 있습니다. Anthropic 동등물은 Claude API와 함께 스크립트 사용에 있습니다.
분기할 오류 코드
ApiError.Code는 안정적인 문자열입니다: UNAUTHORIZED (401), VALIDATION_ERROR 및 INVALID_URL (400), VIDEO_NOT_FOUND 및 TRANSCRIPT_UNAVAILABLE (404), RATE_LIMIT_EXCEEDED (429), YOUTUBE_ERROR (500). 사람들을 놀라게 하는 것은 TRANSCRIPT_UNAVAILABLE입니다: 스크립트는 YouTube의 캡션 트랙에서 나오며, 소유자가 캡션을 비활성화한 비디오는 반환할 것이 없습니다. 재시도 정책이 이를 수정하지 않습니다. 코드에서 패턴을 일치시키고 영구 건너뛰기로 취급하세요.
제로 가입 테스트 키의 경우 GET https://youtube2text.org/api/demo-key를 가져오세요. 공유되며 IP당 월 5개 비디오로 제한되므로 실험용입니다. Go도 스택에 있으면 Golang에서 동일한 호출은 동일한 봉투 트릭을 사용합니다.
전체 기계 판독 가능 참고 - 모든 매개변수, 모든 오류, 시스템 프롬프트에 붙여넣을 준비가 됨 - youtube2text.org/api.md에 있습니다.