はじめに
YouTubeの動画から文字起こしを簡単に取得できるWebツールを作ろうと考えました。スマートフォンからでも使いやすく、URLを入力するだけで文字起こしが取得できる便利なツールです。
しかし、実際に開発を進めると、ブラウザのセキュリティ制限という大きな壁にぶつかりました。この記事では、その問題と向き合った過程、そして最終的に選んだ現実的な解決策について共有します。
当初のアイディアとCORS制限という壁
当初考えていた仕組みはシンプルでした。ユーザーがYouTubeのURLを入力すると、JavaScriptがYouTubeの字幕APIに直接アクセスして文字起こしを取得し、整理して表示するというものです。
この方法なら、完全にクライアントサイドで処理が完結します。ユーザーにとっても、アカウント登録などの面倒な手続きが一切必要ありません。
しかし、実装を始めるとすぐに問題が発生しました。ブラウザのCORS(Cross-Origin Resource Sharing)制限です1。
CORSとは、異なるドメイン間でのデータのやり取りを制限するブラウザのセキュリティ機能です。例えば、自分のサイト(mydomain.com)からYouTubeのデータ(youtube.com)に直接アクセスしようとすると、ブラウザが「危険かもしれない」と判断してアクセスを遮断します。ブラウザのセキュリティシステムは、異なるサイト間での無許可のデータアクセスを防いでいます。
プロキシサーバーでの迂回を試みる
CORS制限を回避する一般的な方法として、プロキシサーバーの利用があります。これは中継地点を経由してデータを取得する方法で、直接的なアクセスではないためCORS制限を避けられる場合があります。
複数の無料プロキシサービスを試しました。cors-anywhere.herokuapp.com、api.allorigins.win、thingproxy.freeboard.ioなどです2。しかし、結果はすべて失敗でした。
CORS制限によるアクセス拒否
最初に発生したのは、以下のようなエラーでした。
Access to fetch at 'https://cors-anywhere.herokuapp.com/...'
from origin 'null' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Code language: JavaScript (javascript)
このエラーメッセージを分解すると、重要な情報が見えてきます。まず「origin ‘null’」は、ローカルファイルとして開いたHTMLファイルからのリクエストであることを示しています。通常のWebサーバーから配信される場合は、具体的なドメイン名が表示されます。
「No ‘Access-Control-Allow-Origin’ header is present」の部分が核心です。これは、アクセス先のサーバーが、リクエスト元のドメインからのアクセスを許可していないことを意味します。ブラウザは事前にサーバーに確認し、許可されていないアクセスを自動的に遮断したのです。
プロキシサーバーからの403エラー
次に試したプロキシサーバーからは、より直接的な拒否応答が返されました。
GET https://cors-anywhere.herokuapp.com/... 403 (Forbidden)
Code language: JavaScript (javascript)
403エラーは「アクセス権限がない」ことを示すHTTPステータスコードです。cors-anywhere.herokuapp.comは、2021年以降、不正使用を防ぐために事前承認制となっており、一般的な利用では403エラーが返されるようになっていました。
JSONパースエラーの発生
別のプロキシサービスでは、異なるタイプのエラーが発生しました。
SyntaxError: Failed to execute 'json' on 'Response':
Unexpected end of JSON input
Code language: JavaScript (javascript)
このエラーは、プロキシサーバーから返されたレスポンスが期待していたJSON形式ではなかったことを示しています。サーバーがエラーページのHTMLを返したり、空のレスポンスを返したりした場合に発生します。
JavaScriptでは、response.json()メソッドがレスポンスボディをJSON形式として解析しようとしますが、有効なJSONデータでない場合にこのエラーが発生します。
ネットワークレベルでの失敗
さらに、以下のようなエラーも観測されました。
Failed to load resource: net::ERR_FAILED
Code language: CSS (css)
これはネットワークレベルでのエラーで、DNS解決の失敗、接続タイムアウト、またはサーバー側でのコネクション拒否などが原因となります。一部のプロキシサービスは、サーバー自体が不安定だったり、過負荷で応答できない状態でした。
エラーから見える根本的問題
これらのエラーパターンからわかるのは、個別のプロキシサービスの問題ではないことです。無料のプロキシサービスは、制限が厳しく、安定性も保証されていません。
また、CORS制限は、ブラウザのセキュリティアーキテクチャに組み込まれた仕組みです。さらに重要なのは、仮にCORS制限を回避できたとしても、YouTube側のAPI制限やレート制限に直面する可能性が高いことです。大規模なサービスは、不正なアクセスや過度な負荷を防ぐために、複数の層でアクセス制限を設けています。
既存サービスの仕組み分析(YouTube Data API)
DownSubのような既存の字幕ダウンロードサービスがどのように実現しているかも調査しました。これらのサービスは、サーバーサイドでYouTube APIを処理することでCORS制限を回避しています。
これはGoogleが公式に提供するAPIで、適切な認証を行えば字幕データを取得できます。サーバーがあることで、ブラウザの制限を受けずにYouTubeのデータにアクセスできます。
しかし、この方法には重要な制約があります。まず、APIキーの取得が必要で、ユーザーにとって敷居が高くなります。さらに重要なのは、利用量に応じてコストが発生することです。
YouTube Data APIは1日あたり10,000クォータユニットまでが無料で、文字起こし1回につき約100ユニットを消費します3。つまり、1日約100回まで無料で利用できますが、それを超えると課金が始まります。月額換算すると、1,000回の利用で約100円のコストが発生します。
AdSenseによる収益化の検討
APIコストをAdSenseで回収できるかも検討しました。しかし、文字起こしツールの特性を考えると、収益化は困難です。
ユーザーの滞在時間が短く、目的がはっきりしているため広告のクリック率が低いことが予想されます。1,000ページビューあたり50-200円程度の収益が見込めても、
1,000ページビューあたり50-200円程度の収益が見込んでも4、同程度のAPIコストは、約100円。利益はほとんど残りません。
さらに深刻な問題は、利用者が増加した場合のコスト爆発です。月10万回の利用があると約10,000円、月100万回では約100,000円のAPIコストが発生します。個人運営では到底負担できない金額になってしまいます。
結局、実装は断念した
これらの検討を経て、最終的にはこれまでのやり方を選択しました。スマートフォンによる自動化は諦め、パソコンでYouTubeから手動で文字起こしをコピーすることです。
YouTubeの「文字起こしを表示」機能を使うだけなので、特別な技術知識は不要です。
まとめ
YouTube文字起こし取得ツールの開発を通じて、ブラウザのセキュリティ制限とAPI利用コストという現実的な制約に直面しました。理想的な完全自動化は技術的に可能でも、コスト面で持続可能ではありませんでした。
最終的に選択した手動支援型のアプローチは、完全な自動化ではないものの、コストゼロで確実に動作し、ユーザーにとっても理解しやすい方法となりました。Web開発においては、技術的な可能性だけでなく、運用コストや持続可能性も重要な考慮要素であることを実感しました。
CORS制限、API利用料金、サーバー運用コストといった制約を理解し、現実的な解決策を選択することが、実用的なWebアプリケーション開発には不可欠です。
- CORS制限は、2014年にW3Cで標準化されたセキュリティ機能で、異なるオリジン間でのリソース共有を制御します。オリジンはプロトコル・ドメイン・ポートの組み合わせで定義されます。 – Cross-Origin Resource Sharing (CORS) – MDN Web Docs
- cors-anywhere.herokuapp.comは2021年1月以降、不正使用防止のため事前リクエストが必要になり、実質的に一般利用が制限されています。多くの無料プロキシサービスは類似の制限を導入しています。 – Important changes to cors-anywhere.herokuapp.com – GitHub Issues
- YouTube Data APIのクォータは操作によって異なり、captions.listは100ユニット、captions.downloadは200ユニットを消費します。料金は地域によって異なりますが、米国では10,000ユニット超過分に対して1ドル程度の課金が発生します。 – YouTube Data API のクォータと料金について – Google Developers
- AdSenseの収益はジャンル、地域、季節によって大きく変動します。ツール系サイトのRPM(Revenue per Mille)は一般的に低く、特に滞在時間が短いサイトでは0.05-0.2ドル程度となることが多いです。 – Google AdSense RPM(1,000ページビューあたりの収益)を理解する – Google AdSense ヘルプ