【问题标题】:How to prefetch video in a react application?如何在反应应用程序中预取视频?
【发布时间】:2019-01-14 23:48:25
【问题描述】:

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

【问题讨论】:

  • 似乎link ref="pref"&lt;video preload 都不会强制浏览器预加载整个视频。在我的 chrome 上,它只缓冲视频的一部分(所以你可以立即开始播放)。

标签: javascript html reactjs html5-video prefetch


【解决方案1】:

根据您的情况,您可以发出 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,它将不起作用。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 是的,以提高性能。我宁愿浪费数据也不愿让用户等待视频缓冲——至少在这种特殊情况下是这样。
    猜你喜欢
    • 2019-09-07
    • 2022-01-05
    • 2016-12-06
    • 2015-08-29
    • 2011-08-27
    • 1970-01-01
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多