YouTube文字起こしAPIが動かない?診断チェックリスト
文字起こしリクエストが失敗する本当の理由すべてを、推測ではなくオープンソースコミュニティ自身の最も議論されたissueに基づいてまとめました。それぞれの正確なエラーコードと対処法つきです。
診断チェックリスト
エラーコード(またはレスポンスの形)を以下の表と照らし合わせてください。
| コード | 意味 | 対処法 |
|---|---|---|
MISSING_URL / INVALID_URL · 400 | vパラメータがないか、YouTubeが認識する動画ID/URLではありません。 | 有効な11文字の動画ID、または完全なyoutube.com/watch?v=...形式のURLを渡してください。 |
VIDEO_UNAVAILABLE · 404 | 動画が非公開、削除済み、または地域制限されています - サーバーの視点では存在しません。 | まず通常のブラウザで動画が読み込まれるか確認してください。読み込まれない場合、APIが取得できるものはありません。 |
TRANSCRIPT_DISABLED · 404 | 通常はアップロード者が字幕を無効にしたことを意味しますが、地域制限やIPブロックも全く同じに見えるエラーを引き起こすことがあります。 | 恒久的だと決めつける前に、下記の補足を確認してください。 |
LANGUAGE_NOT_AVAILABLE · 404 | 動画には字幕がありますが、リクエストした言語のものではありません。 | 言語パラメータを外して利用可能なものを取得するか、まず動画自体の字幕一覧を確認してください。 |
TRANSCRIPT_NOT_FOUND · 404 | この動画にはどの言語でも文字起こしが存在しません。 | 字幕無効の場合と同じで、取得できるものがありません。すべての動画にあるわけではありません。 |
RATE_LIMITED · 429 | APIキーがプランの1分あたりの上限を超えるリクエストを行いました。 | ペースを落として再試行するか、より高いレート制限のプランにアップグレードしてください。 |
UPSTREAM_* · 429/503/504 | あなたのキーやリクエストではなく、YouTube自体との通信における一時的な問題です。 | 少し待ってから再試行して問題ありません - まさにホスト型APIが代わりに吸収するタイプの障害です。 |
「字幕無効」は必ずしも無効を意味しない
オープンソースyoutube-transcript-apiの歴史上、最も議論されたissue(187件のコメント)は、実際には無効になっていない動画に対してスクリプトが「TranscriptsDisabled」を出すというものです - 通常のブラウザでは問題なく字幕が再生されます。3つの異なる本当の原因が、ほぼ同一に見えるエラーを引き起こします:
- 本当に無効 - アップロード者が字幕をオフにした。どの言語でも取得できるものはありません。
- 地域制限 - 動画やその字幕がサーバーの国からは利用できないが、別の地域のブラウザからは機能します。
- IPブロック - YouTubeが特定の理由ではなく一般的な失敗を返しており、本当の原因は下記のクラウドホスティングの問題です。
きれいな例外の代わりに生のXMLパースエラー("no element found"、"line 1, column 0")が出るのも同じ系統の問題です - 空のレスポンスボディで、通常は下記の同じIPブロックやPoTokenが原因であり、パースコード自体のバグではありません。
AWS、GCP、Azure、またはVPSでブロックされていますか?
スクリプトがノートPCでは完璧に動くのに、クラウドサーバーにデプロイした途端に失敗する場合、ほぼ常にこれが理由です:YouTubeの字幕取得エンドポイントは、個々の不正なIPだけでなく、データセンターのIP範囲全体をブロックします。何千もの無関係なスクリプトが同じアドレス範囲を共有しているため、大手クラウドプロバイダーのIP空間はいずれこれに当たります。
Could not retrieve a transcript for the video https://www.youtube.com/watch?v=...!
This is most likely caused by:
YouTube is blocking requests from your IP.現実的な回避策を、おおよそ手間の順に挙げると:
- レジデンシャルまたはモバイルのプロキシプール経由でリクエストする - 時々は機能しますが、有料のローテーション型レジデンシャル設定でも失敗するという報告が増えています。恒久的な解決策ではありません。
- 複数のクラウドプロバイダーやリージョンをローテーションする - それらの範囲もいずれフラグ付けされるまでの時間稼ぎになります。
- 同じ動画を再取得しないよう積極的にキャッシュする - ブロックに当たる頻度は減りますが、なくなりはしません。
- このインフラをすでに運用しているホスト型APIを使う - 問題が「あなたのプロジェクト」から「それを機能させ続けるのが本当の仕事である誰か」に移ります。
それこそが、私たち自身のYouTube文字起こしAPIが埋めている本当のギャップです - 別のライブラリではなく、まさにこの問題のためにすでに構築されたインフラです。
PoTokenRequiredが出ますか?
より新しい障害モード:YouTubeの字幕エンドポイントは、実行時に自身のプレーヤーJavaScriptによって生成される証明トークンをますます要求するようになっています - クッキーでも、IPレピュテーションチェックでもなく、暗号学的な値です。単純なHTTPリクエストにはそれを生成する方法がありません。
実際の技術的詳細はjdepoix/youtube-transcript-api#592をご覧ください - その報告の時点では、オープンソースライブラリに文書化された回避策はありません。
これはまさにホスト型APIが吸収すべき種類の問題です - エンドポイントを1回呼び出すだけで、自分でトークン生成を解決する必要なく、文字起こしか明確なエラーが返ってきます。
各失敗に対して私たち自身のAPIが返すもの
すでに私たちのAPIを使っていて、HTTPステータスだけから推測するのではなく正確な失敗で分岐したい場合、すべてのエラーは安定した`code`フィールドとともに返ってきます:
curl "https://getyoutubetranscript.com/api/v1/transcript?v=dQw4w9WgXcQ" \
-H "Authorization: Bearer sk_live_..."
# A failure looks like:
# { "success": false, "code": "TRANSCRIPT_DISABLED", "message": "Transcripts are disabled for this video." }完全なパラメータリファレンスとすべてのステータスコードはAPIドキュメントにあります。
よくあるYouTube文字起こしAPIのエラー
なぜ'YouTube is blocking requests from your IP'が出るのですか?
クラウド/データセンターのIPアドレス(AWS、GCP、Azure、VPSなど)からYouTubeの字幕エンドポイントを呼び出しており、YouTubeは自宅/レジデンシャルIPよりもそれらの範囲をより積極的にブロックします。通常は個人的なものではなく、何千もの他のスクリプトと共有されているIP範囲全体の問題です。
なぜスクリプトはローカルでは動くのに、デプロイすると失敗するのですか?
ノートPCはレジデンシャルIPを持ち、サーバーはデータセンターIPを持っています。同じコードでもネットワークの評判が違う - 自分でYouTube文字起こしライブラリをホストする人にとって「ここでは動くのに、あそこでは失敗する」の最も一般的な原因です。
なぜ「字幕無効」が時々間違いだと分かるのですか?
YouTubeが常に具体的な理由を返すわけではないためです - 地域制限やIPブロックは、本当に無効になっている動画と同じ一般的なエラーを引き起こすことがあります。恒久的に利用できないと決めつける前に、別のネットワークの通常のブラウザで動画が字幕を再生するか確認してください。
PoTokenRequiredとは何ですか?
YouTubeが実行時に本物のプレーヤーJavaScriptによって生成される証明トークンを要求すること - ハードコードしたり一度抽出したりできる静的な値ではありません。単純なHTTPリクエスト、そしてほとんどのスクレイピングライブラリには、それを生成する方法がなく、そのためオープンソースライブラリには現在文書化された回避策がありません。
リクエストした言語で文字起こしがないのはなぜですか?
動画には字幕がありますが、その言語のものではありません。言語パラメータなしでリクエストして利用可能なものを取得するか、まずどの言語が存在するか確認してください。
レート制限を避けるにはどうすればよいですか?
2つの異なる制限があります:あなたのプラン自体の1分あたりのリクエスト上限(より高いものへアップグレード)と、YouTube自体のアップストリーム制限(少し待ってから再試行して問題なし - ホスト型APIがその大部分をあなたの代わりに吸収します)。