SpringFrameworkとChromeを使用したビデオストリームの設定

Aug 19 2020

Amazon S3ストアからのビデオ(またはオーディオ)ファイルをストリーミングできるHTTPエンドポイントを利用できるようにするSpringサービスを作成しています。基本的な考え方は、Google ChromeのアドレスバーにURLを入力すると、サービスがS3からファイルを取得してストリーミングするため、ユーザーはダウンロードを待たずにすぐに視聴を開始できます。完了し、ユーザーはビデオのプログレスバーのランダムなスポットをクリックして、すぐにそのスポットからビデオの視聴を開始できます。

これが理論的には機能するはずだと私が理解している方法は、Chromeがファイルのダウンロードを開始するということです。このサービスはHTTP200で応答し、Accept-Ranges: bytesContent-Length: filesizeヘッダーを含みます。filesizeファイル全体をフェッチせずにS3からメタデータとしてクエリできるため、これは既知です。これらのヘッダーを含めると、ブラウザはダウンロードをキャンセルし、Range: bytes=0-whateverヘッダー(whateverChromeが決定するチャンクサイズ)を使用してファイルを再度要求します。次に、サービスはHTTP 206(部分コンテンツ)と要求されたバイト範囲で応答します。これは、S3が同じ範囲プロトコルをサポートしているため簡単に判別できます。その後、Chromeは、ストリームが終了するまで、サービスに連続するチャンクを要求します。

Spring側では、データをResponseEntity<InputStreamResource>(このSOの回答に従って)で送信しています。

ただし、実際には、Chromeは数百バイト後に最初のリクエストをキャンセルします。ただし、Range: bytes=0-ヘッダー付きの2番目の要求を送信し、ファイル全体を効果的に要求します。サーバーはHTTP206で応答します。その結果、ダウンロードされたのは数百バイトのビデオのみであり、ビデオの再生は明らかに開始されません。

興味深いことに、Firefoxではすべてが正しく機能します。残念ながら、アプリはChromeをサポートする必要があります。プロトコルの一部が欠落していますか?

回答

2 jqno Sep 01 2020 at 21:28

Content-Range応答ヘッダーに1つずつずれたエラーがあったことがわかりました。

構文はContent-Range: bytes start-end/totalです。あなたが全体の範囲を取得したい場合、あなたは指定する必要はありません、私たちが何をしていたありました、。total10bytes 0-9/100-10/10

もちろん、実際のファイルのサイズが大きく、そのようなファイルの中央にチャンクの実際の範囲があるため、このエラーは、前の段落の不自然な例よりもはるかに気づきにくいものでした...ಠ_ಠ