我正在嘗試構建一個英雄橫幅,它開始播放四個隨機視頻中的一個并繼續播放串列。但是,據我了解,我當前的代碼,每當需要播放新視頻并且已經加載并播放過一次時,都會再次使用互聯網獲取相同的資料。
從我到目前為止的谷歌搜索來看,我可能是錯的,因為我還是個新手,可以在播放該視頻之前預取,這樣就不會出現任何卡頓等問題。我怎樣才能加載一次并重復使用視頻資料稍后再?現在我唯一的選擇是創建物件/HTML元素,為它們分配和加載視頻,在需要播放某個視頻時附加,洗掉它并附加下一個,基本上就像一個播放串列。然而,我很擔心這個邏輯,如果它有效,不會對性能友好,因為我試圖在 JS 方面做得更好,同時也了解各個方面的優秀優化實踐。
這是當前代碼:
<img
src="image.jpg"
id="noscript-img"
width="100%"
heigh="100%"
loading="lazy"
/>
<video id="hero-banner" muted="" playsinline disablePictureInPicture>
<source src="" type="video/mp4" id="hero-banner-src" />
</video>
<div class="curtains"></div>
<h1 class="collection-title">{{ collection.title }}</h1>
</div>
<script defer type="text/javascript">
var heroBanner;
var heroBannerSrc;
var sources;
var startWith;
var curDuration;
var curtains;
function fadeAnim() {
var opacity = 0.1;
var anim = setInterval(function () {
if (opacity >= 1) {
clearInterval(anim);
}
curtains.style.opacity = opacity;
opacity = opacity * 0.1;
}, 10);
}
function fadeOutAnim() {
var opacity = 1;
var anim1 = setInterval(function () {
if (opacity <= 0.1) {
clearInterval(anim1);
}
curtains.style.opacity = opacity;
opacity -= opacity * 0.1;
}, 50);
}
window.addEventListener("load", (event) => {
heroBanner = document.getElementById("hero-banner");
heroBanner.style.visibility = "visible";
document.getElementById("noscript-img").remove();
heroBannerSrc = document.getElementById("hero-banner-src");
sources = [
"video1.mp4",
"video2.mp4",
"video3.mp4",
"video4.mp4",
];
startWith = Math.floor(Math.random() * 4);
heroBannerSrc.setAttribute("src", sources[startWith]);
heroBanner.load();
curtains = document.querySelector(".curtains");
heroBanner.addEventListener("loadeddata", (event) => {
curDuration = heroBanner.duration * 1000;
setTimeout(fadeAnim, curDuration - 800);
});
heroBanner.play();
heroBanner.addEventListener("ended", (event) => {
if (startWith < 3 && startWith >= 0) {
startWith ;
} else if (startWith >= 3 || startWith <= 0) {
startWith = 0;
}
heroBannerSrc.setAttribute("src", sources[startWith]);
heroBanner.load();
heroBanner.addEventListener("loadeddata", (event) => {
curDuration = heroBanner.duration * 1000;
setTimeout(fadeOutAnim, 0);
setTimeout(fadeAnim, curDuration - 800);
});
heroBanner.play();
});
});
</script>
任何幫助是極大的贊賞。
uj5u.com熱心網友回復:
好吧,使用XMLHttpRequest()將加載的視頻保存到陣列中解決了我的問題。
如果還有其他人仍在學習 JavaScript 并正在尋找一種方法來做我在這里嘗試做的事情,那么它會是什么樣子:
var preVideos = new Array("", "", "", "");
//since I start a random video from my playlist
//and continue the query from there this is why
//I pre add four elements to the Array
function preLoad(fadeOutState) {
//'fadeOutState' is plainly for the transition animation
if (preVideos.at(startWith) != "") {
heroBannerSrc.src = preVideos.at(startWith);
heroBanner.load();
//the video element in my case has <source> as a child
//heroBannerSrc points to the <source> element
//heroBanner points to the <video> element
heroBanner.addEventListener("loadeddata", (event) => {
curDuration = heroBanner.duration * 1000;
setTimeout(fadeOutAnim, 0);
setTimeout(fadeAnim, curDuration - 800);
//this event is plainly for a transition between videos animation
});
heroBanner.play();
return;
//overall this 'if' is to stop HTTP requests from happening below,
//after all of the videos have already been loaded and stored
}
let req = new XMLHttpRequest();
req.open("GET", sources[startWith], true);
req.responseType = "blob";
req.onload = function () {
if (req.readyState !== XMLHttpRequest.DONE && status != 200) {
console.log(
"Status does not equal to 200 or HTTP request hasn't finished
yet"
);
return;
}
var blob = URL.createObjectURL(this.response);
switch (startWith) {
case 0:
preVideos.splice(0, 1, blob);
//if I didn't need to preadd elements to the
//array I'd use '.push(blob)' instead of '.splice'
//and I wouldn't need the 'switch case' for that matter too
heroBannerSrc.src = blob;
break;
case 1:
preVideos.splice(1, 1, blob);
heroBannerSrc.src = blob;
break;
case 2:
preVideos.splice(2, 1, blob);
heroBannerSrc.src = blob;
break;
case 3:
preVideos.splice(3, 1, blob);
heroBannerSrc.src = blob;
break;
default:
heroBannerSrc.src = blob;
}
heroBanner.load();
switch (fadeOutState) {
case false:
heroBanner.addEventListener("loadeddata", (event) => {
curDuration = heroBanner.duration * 1000;
setTimeout(fadeAnim, curDuration - 800);
heroBanner.play();
//event for the anim.
});
case true:
heroBanner.addEventListener("loadeddata", (event) => {
curDuration = heroBanner.duration * 1000;
setTimeout(fadeOutAnim, 0);
setTimeout(fadeAnim, curDuration - 800);
heroBanner.play();
//event for the anim.
});
}
};
req.send();
}
但是,可能有一種對性能更友好的方法來解決這個問題,如果您還希望實作所有“核心”(我認為?)要求,快取視頻也是一個好主意。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/493254.html
標籤:javascript html 表现 视频 加载
