我已经看到了一些关于这个的帖子,但没有答案,所以我想我会在被污染的 youtube 相关页面的坟墓场添加另一个。
我有一个 100MB 的 mp4 视频,需要通过浏览器完全下载,
但是,完全下载后不会触发任何事件,并且 Chrome 似乎停止缓冲任何视频,直到当前视频时间几乎达到缓冲区的末尾,然后它会请求更多。
如何让浏览器完全下载视频并 100% 缓冲?
谢谢
我已经看到了一些关于这个的帖子,但没有答案,所以我想我会在被污染的 youtube 相关页面的坟墓场添加另一个。
我有一个 100MB 的 mp4 视频,需要通过浏览器完全下载,
但是,完全下载后不会触发任何事件,并且 Chrome 似乎停止缓冲任何视频,直到当前视频时间几乎达到缓冲区的末尾,然后它会请求更多。
如何让浏览器完全下载视频并 100% 缓冲?
谢谢
可悲的是,Chrome - 与其他 HTML5 浏览器一样 - 试图对其下载的内容保持智能并避免不必要的带宽使用......这意味着有时我们会留下次优体验(具有讽刺意味的是,YouTube 遭受了如此多的痛苦,以至于有扩展强制更多的预缓冲!)
就是说,我发现对于良好的服务器和良好的连接来说,这并不是经常需要的 - 但是如果你需要一些东西,我发现的唯一解决方案就是有点大锤......使用 Ajax 下载文件您要播放然后将其加载到视频元素的源中。
下面的示例假设您的浏览器支持 m4v/mp4 - 如果您不能保证(例如)Chrome,您可能希望使用 canPlayType 测试为您的用户选择最合适的视频格式。您还需要测试以查看它处理所需大小的视频的效果(我尝试了一些相当大的视频,但不确定它可以可靠地处理什么上限)
该示例也非常简单......它启动请求并且在加载时不会与用户交流任何内容 - 对于您大小的视频,您可能想要显示一个进度条只是为了让他们感兴趣.. .
此过程的另一个缺点是,在您完全下载文件之前它不会开始播放 - 如果您想更深入地从缓冲区动态显示视频,那么您需要开始深入研究前沿(目前)MediaSource
如http://francisshanahan.com/index.php/2013/build-an-mpeg-dash-player-from-scratch/等帖子中所述的世界
<!DOCTYPE html>
<html>
<head>
<title>Preload video via AJAX</title>
</head>
<body>
<script>
console.log("Downloading video...hellip;Please wait...")
var xhr = new XMLHttpRequest();
xhr.open('GET', 'BigBuck.m4v', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
console.log("got it");
var myBlob = this.response;
var vid = (window.webkitURL || window.URL).createObjectURL(myBlob);
// myBlob is now the blob that the object URL pointed to.
var video = document.getElementById("video");
console.log("Loading video into element");
video.src = vid;
// not needed if autoplay is set for the video element
// video.play()
}
}
xhr.send();
</script>
<video id="video" controls autoplay></video>
</body>
</html>
我的解决方案是针对比所描述的 OP 小得多的视频,但是所需的行为是相同的:防止视频开始播放,直到视频完全缓冲。如果视频已被缓存,则应为返回用户播放视频。
下面的答案深受这个答案的影响,并且已经在 Chrome、Safari 和 Firefox 上进行了测试。
Javascript 文件:
$(document).ready(function(){
// The video_length_round variable is video specific.
// In this example the video is 10.88 seconds long, rounded up to 11.
var video_length_round = 11;
var video = document.getElementById('home_video_element');
var mp4Source = document.getElementById('mp4Source');
// Ensure home_video_element present on page
if(typeof video !== 'undefined'){
// Ensure video element has an mp4Source, if so then update video src
if(typeof mp4Source !== 'undefined'){
$(mp4Source).attr('src', '/assets/homepage_video.mp4');
}
video.load();
// Ensure video is fully buffered before playing
video.addEventListener("canplay", function() {
this.removeEventListener("canplay", arguments.callee, false);
if(Math.round(video.buffered.end(0)) >= video_length_round){
// Video is already loaded
this.play();
} else {
// Monitor video buffer progress before playing
video.addEventListener("progress", function() {
if(Math.round(video.buffered.end(0)) == video_length_round){
this.removeEventListener("progress", arguments.callee, false);
video.play();
}
}, false);
}
}, false);
}
});
上面的 javascript 更新了一个视频元素的来源,例如这个:
<video id="home_video_element" loop="" poster="/assets/home/video_poster_name.jpg" preload="auto">
<source id="mp4Source" type="video/mp4">
</video>
我有一个类似的问题,我试图解决,我希望 chrome 在未计量的连接上更积极地为桌面上的用户加载视频。我尝试MediaSource
按照上面建议的答案之一进行调查,但是使用它会涉及我必须将我的 mp4 编码为碎片化的 mp4,这似乎工作量太大。
最终我决定了这种行为:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<script>
function load(){
const url = document.getElementById('url').value
const vid = document.getElementById('video')
vid.src = url;
const progressElem = document.getElementById('progress')
const xhr = new XMLHttpRequest();
xhr.onload = function() {
const wasPaused = vid.paused
const time = vid.currentTime;
vid.src = URL.createObjectURL(xhr.response);
vid.currentTime = time;
if(!wasPaused)
vid.play();
};
xhr.onprogress = onprogress = function (event) {
progressElem.innerText = 'Download Progress: ' + (event.loaded / event.total);
};
xhr.responseType = "blob";
xhr.open("GET", url)
xhr.send();
}
</script>
<body style="padding-left: 30px">
<h1>Testing video loading</h1>
<input type="text" id="url" value="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" size="200">
<br>
<button onclick="load()">Load Video</button>
<br>
<h3 id="progress"></h3>
<br>
<video id="video" style="max-width:min(800px, 100vw)" controls></video>
</body>
</html>
基本上我会先让用户从他们的浏览器本地流式传输视频,但我也会开始下载整个文件,一旦完成,我只需将下载的数据交换到 vid.src 并确保播放器在正确的状态。请注意,这确实会在视频中产生轻微的卡顿/缓冲效果。
这个解决方案绝对不是最有效的带宽,但它似乎对桌面上的 1-2GB 视频文件工作得相当好。
我还应该提到,我认为您应该只在 Chrome 中执行此操作,因为其他浏览器可能有更好的解决方案。例如,在 Firefox 中,用户可以访问一些设置来控制缓冲的视频量。