web-dev-qa-db-ja.com

反応アプリケーションでビデオをプリフェッチする方法は?

Reactアプリには、ユーザー入力に応じて異なる動画を読み込むコンポーネントがあります。小さな動画は4つか5つしかないので、ブラウザですべてをプリフェッチしたいと思います。非アクティブです。

私のコンポーネント内には、次のものがあります。

<video src={this.props.video} type="video/mp4" />

私のindex.htmlには、ビデオの頭の中に次の行があります。

<link rel="prefetch" as="video/mp4" href="link/to/my/video.mp4">

ただし、これは機能しません。コンソールを見ると、ビデオはフェッチされていますが(ステータスは200)、キャッシュには保存されていません(サイズは、応答の場合は5 Mb、ディスク上の場合は0 Mb)。ユーザー入力を提供し、コンポーネントがそのビデオを表示する必要がある場合、数秒かかる再フェッチされます。

PS-私がビデオ要素にプリロードを使用しようとしない理由は、プリロードは、表示しているページにビデオが含まれている場合にのみ機能するためです。私の場合、現在のページに必要ない場合でも、ビデオをロードしたいと思います。

更新: pen を作成しました。ここでは、ヘッドでリンクタグを使用しているにもかかわらず、ビデオがプリフェッチされていないことがわかります。

9
bluprince13

あなたの状況では、AJAXリクエストを作成し、そのリクエストの応答からblob URLを作成できます。

あなたは 私のコードペン から見ることができます

function playVideo() {
    var video = document.getElementById('video')

    if (video) {
        video.play().then(_ => {
            console.log('played!')
        });
    }
}

function onSuccess(url) {
    console.log(url);
    var video = document.createElement('VIDEO')
    if (!video.src) {
        video.id = 'video';
        document.body.appendChild(video);
        video.src = url
    }
}

function onProgress() {

}

function onError() {

}

prefetch_file('https://raw.githubusercontent.com/FilePlayer/test/gh-pages/sw_360_lq.mp4', onSuccess, onProgress, onError)

function prefetch_file(url,
                       fetched_callback,
                       progress_callback,
                       error_callback) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.responseType = "blob";

    xhr.addEventListener("load", function () {
        if (xhr.status === 200) {
            var URL = window.URL || window.webkitURL;
            var blob_url = URL.createObjectURL(xhr.response);
            fetched_callback(blob_url);
        } else {
            error_callback();
        }
    }, false);

    var prev_pc = 0;
    xhr.addEventListener("progress", function (event) {
        if (event.lengthComputable) {
            var pc = Math.round((event.loaded / event.total) * 100);
            if (pc != prev_pc) {
                prev_pc = pc;
                progress_callback(pc);
            }
        }
    });
    xhr.send();
}

このアプローチの欠点は、ビデオでサイトの [〜#〜] cors [〜#〜] が許可されていない場合は機能しないことです。

5
Max

ビデオをコードに置き換えてください。お役に立てば幸いです。

<video controls>
  <source src={this.props.video}  type="video/mp4" /> 
</video>
1
Araz Babayev

画面をロードする前に、すべてのビデオをプリフェッチする必要が本当にありますか?小さなビデオですが、必ずしも使用されるとは限らない情報をプリロードすることだけが選択肢ではありません。ユーザーが5つのビデオのうち1つだけを視聴した場合、プリロードされたすべてのデータの80%が使用されなかったことを意味します。別の方法は、Netflixがオプションを検索するときに行うように、ビデオのロード中にコンポーネントを表示することです。

0
Julia Melo