私があなたが直面している本当の問題が何であるかは確かではありません。
Chromeにはキャッシュする最大サイズの制限がある可能性があります。その場合、範囲リクエストを使用しないと何も解決しません。
もう1つの考えられる説明は、メディアのキャッシュは実際には単純な作業ではないということです。
ファイルを見ないと、どちらであるかを確実に判断することは困難ですが、メディアを再生するために、ブラウザーがファイル全体をフェッチする必要がないことを理解する必要があります。
たとえば、<audio>要素でビデオファイルを非常にうまく再生できます。ビデオストリームは使用されないため、ブラウザは完全に省略して、オーディオストリームのみをダウンロードできます。あるかどうかは不明ですが、可能です。ほとんどのメディア形式は、ファイル内で物理的に別々のオーディオストリームとビデオストリームを実行し、それらのバイト位置はメタデータでマークされます。
それらは確かに実行するRange-Requestsをキャッシュすることができますが、それでもまだかなりまれです。
ただし、範囲要求を無効にするのが魅力的な場合があるため、サーバーが範囲要求を許可しない場合、一部のブラウザー(Safari)がメディアを再生しないことを知っておく必要があります。
だから、それでも、それはおそらくあなたが望むものではありません。
あなたが試したいと思うかもしれない最初の事はあなたのビデオをウェブ用に最適化することです。mp4の代わりに、webmファイルを提供します。これらは通常、同じ品質で必要なスペースが少なくなり、おそらく最大サイズの制限を回避できます。
結果のファイルがまだ大きすぎる場合は、MediaSourceを使用してファイルをメモリに保持し、一度だけフェッチする必要があるという汚い解決策があります。
次の例では、ファイルは1MBのチャンクで完全に1回だけフェッチされ、フェッチされるときにMediaSourceによってストリーミングされ、メモリ内のデータのみが再生のループに使用されます。
document.getElementById('streamVid').onclick = e => (async () => {
const url = 'https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm';
// you must know the mimeType of your video before hand.
const type = 'video/webm; codecs="vp8, vorbis"';
if( !MediaSource.isTypeSupported( type ) ) {
throw 'Unsupported';
}
const source = new MediaSource();
source.addEventListener('sourceopen', sourceOpen);
document.getElementById('out').src = URL.createObjectURL( source );
// async generator Range-Fetcher
async function* fetchRanges( url, chunk_size = 1024 * 1024 ) {
let chunk = new ArrayBuffer(1);
let cursor = 0;
while( chunk.byteLength ) {
const resp = await fetch( url, {
method: "get",
headers: { "Range": "bytes=" + cursor + "-" + ( cursor += chunk_size ) }
}
)
chunk = resp.ok && await resp.arrayBuffer();
cursor++; // add one byte for next iteration, Ranges are inclusive
yield chunk;
}
}
// set up our MediaSource
async function sourceOpen() {
const buffer = source.addSourceBuffer( type );
buffer.mode = "sequence";
// waiting forward to appendAsync...
const appendBuffer = ( chunk ) => {
return new Promise( resolve => {
buffer.addEventListener( 'update', resolve, { once: true } );
buffer.appendBuffer( chunk );
} );
}
// while our RangeFetcher is running
for await ( const chunk of fetchRanges(url) ) {
if( chunk ) { // append to our MediaSource
await appendBuffer( chunk );
}
else { // when done
source.endOfStream();
}
}
}
})().catch( console.error );
<button id="streamVid">stream video</button>
<video id="out" controls muted autoplay loop></video>