我有一个带有组件的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,您可以看到尽管在头部使用了链接标签,但视频并未预提取。
答案 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在搜索选项时所做的那样。