유대선
프로젝트로
·기술 회고·5

YouTube 자막 — 검증된 방법 랭킹 + 폴백 런북 (이게 깨지면 어디로 가나)

7개 방법을 적대적으로 실측 검증한 뒤 'bgutil POToken 사이드카'를 채택. 깨졌을 때 갈아탈 폴백 순서와 각 대안의 트레이드오프를 런북으로 남긴다.

의사결정 기록 + 폴백 런북. 자막 import가 깨지면 여기부터 읽고 아래 순서대로 갈아탄다.

채택: yt-dlp + bgutil-ytdlp-pot-provider (POToken 사이드카)

검증 랭킹 (전부 실측, 가정 IP)

방법무료아무URL데이터센터 가능?prod에 서드파티 코드비고
bgutil 사이드카 (채택)✅ 검증된 메커니즘¹⚠️ 있음깨짐-유지보수, ToS 회색
youtubei.js + bgutils-js (in-proc)✅ 동일 원리⚠️ 있음(npm)백엔드에 Node 추가 필요
서드파티 API (Supadata 등)프리티어~100/월✅ (아키텍처상)❌ 없음(HTTPS 호출)벤더 의존, 한도 후 유료
홈워커 (집 머신 yt-dlp)n/a(가정 IP)❌ 없음집 머신 켜둬야
레지덴셜 프록시 + yt-dlp❌(~cents/건)❌ 없음돈, 처리량에도 도움
youtube-transcript-api❌ IP의존집머신 전용
yt-dlp --impersonate❌ TLS만데이터센터 무용
InnerTube get_transcript❌ 400 사망쓰지 말 것

¹ 적대 검증: 다른 영상으로 재현(실제 ASR 세그먼트), no-pot 대조=0바이트, wrong-video pot 대조 실패. 단 "AWS IP에서 mint" 자체는 미검증 — 배포 첫 import가 결정적 테스트(로그 Retrieved a gvs PO Token).

폴백 런북 — 채택안이 깨지면 이 순서로

  1. YouTube가 BotGuard를 바꿔서 깨짐brainicism/bgutil-ytdlp-pot-provider 이미지 + bgutil-ytdlp-pot-provider 플러그인을 최신으로 bump(보통 며칠 내 패치 나옴). 버전 핀만 올리고 재배포.
  2. AWS IP에서 mint가 거부됨(attestation이 데이터센터 깎음) → mint 트래픽만 레지덴셜 프록시로 (--proxy는 mint/fetch egress에만, 토큰은 그대로 유효).
  3. 서드파티 코드를 prod에서 빼고 싶다 / 유지보수 지겹다Supadata식 API로 전환. 백엔드 YoutubeTranscriptClient를 yt-dlp 셸아웃 대신 HTTPS 호출로 교체(Gemini 호출과 동형). 프리티어 한도 확인.
  4. 완전 자립·무료 원하고 집 머신 OK → 홈워커: 집 머신에서 plain yt-dlp(가정 IP라 토큰 불필요) → 백엔드의 client-transcript 엔드포인트(이미 구현됨, importByUrl(url, {transcriptSegments}))로 POST.
  5. 그 외 전부 실패 → 큐레이션(운영자가 집 머신에서 미리 채움) — 자막 게이트와 무관, 항상 작동.

처리량 주의 (접근과 별개)

POToken은 봇 차단을 푸는 거지 IP 레이트리밋을 풀지 않는다. 단일 AWS IP에서 대량이면 429가 뜬다. 개인용은 무관하나, 볼륨 생기면 요청 페이싱 + 소량 레지덴셜 프록시 필요.

비-협상 사실 (VERIFIED)