如何在React应用程序中预取视频?

时间:2018-08-07 19:45:23

标签: javascript html reactjs html5-video prefetch

我有一个带有组件的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,您可以看到尽管在头部使用了链接标签,但视频并未预提取。

3 个答案:

答案 0 :(得分:5)

根据您的情况,您可以发出AJAX请求并根据该请求的响应创建 blob URL

您可以从my code pen看到

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,则该方法将无法正常工作。

答案 1 :(得分:1)

用代码替换您的视频。希望它有用

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

答案 2 :(得分:0)

真的需要在加载屏幕之前预取所有视频吗?即使它们是小型视频,预加载不一定要使用的信息也不是唯一的选择。想象一下,如果用户只观看了五个视频之一,则意味着80%的预加载数据从未使用过。另一种选择是在加载视频时显示组件,就像Netflix在搜索选项时所做的那样。