I have a 4 videos and preloader, that should hide when all the videos is fully buffeder
<div id="preload">
<h1>
Download...
</h1>
</div>
<video preload="auto" class="active">
<source src="video1.mp4" type='video/mp4;'>
</video>
<video preload="auto">
<source src="video2.mp4" type='video/mp4;'>
</video>
<video preload="auto">
<source src="video3.mp4" type='video/mp4;'>
</video>
<video preload="auto">
<source src="video4.mp4" type='video/mp4;'>
</video>
There is the code that checks if videos is buffered
preload = [];
preloadOverlay = document.querySelector('#preload');
videos = document.querySelectorAll("video")
[...videos].forEach(function(video, index) {
video.addEventListener('canplay', function(){
let timerId = setTimeout(function tick() {
// console.log(preload)
// console.log(video.buffered.end(0), video.duration)
if(preload.length < 4)
{
if(video.buffered.end(0) === video.duration)
{
preload.push(index)
}
timerId = setTimeout(tick, 200);
}
else if(preload.length === 4)
{
clearTimeout(timerId);
preloadOverlay.classList.add('hide');
}
}, 200);
})
})
but sometimes buffering just stops, for example all the videos are 3 seconds long, but buffering stops at 2 second
i changed my code a little bit to
[...videos].forEach(function(video, index) {
video.addEventListener("canplaythrough", function() {
preload.push(index)
});
let timerId = setTimeout(function tick() {
if(preload.length < 4)
{
console.log(preload)
console.log(video.buffered.end(0), video.duration)
timerId = setTimeout(tick, 200);
}
else if(preload.length === 4)
{
clearTimeout(timerId)
preloadOverlay.classList.add('hide')
layoutAnimation(timeoutClassRemover)
}
}, 200);
})
but still, one or two videos does not load till the end, and stops randomly
I wouldn't use the timer for this task. Promises look more suitable here from my perspective.
Also, I would recommend removing ;
at the end of types video/mp4
.
Please let me know if this helps.
// just to make the snippet working
const testVideoUrl = 'https://r2---sn-ntqe6n7r.c.2mdn.net/videoplayback/id/97eca827be163084/itag/15/source/doubleclick/requiressl/yes/ratebypass/yes/mime/video%2Fmp4/ip/0.0.0.0/ipbits/0/expire/2144448000/sparams/expire,id,ip,ipbits,itag,mh,mime,mip,mm,mn,ms,mv,mvi,pl,ratebypass,requiressl,source/signature/160FEBC1E31299C398B4F585BB3AC111D899FB8D.4E8EB91A32577DC9954E0EB1CED4109081DE6B71/key/cms1/cms_redirect/yes/mh/Hp/mip/60.241.173.252/mm/42/mn/sn-ntqe6n7r/ms/onc/mt/1679898045/mv/m/mvi/2/pl/23/file/file.mp4'
const preloadPromises = [];
const preloadOverlay = document.querySelector('#preload');
const videos = document.querySelectorAll("video");
[...videos].forEach((video, index) => {
// just for the test the URL is assigned from the script
video.src = testVideoUrl;
let resolve;
const promise = new Promise((_resolve) => {
resolve = _resolve;
});
video.addEventListener('canplaythrough', resolve);
preloadPromises.push(promise);
});
// wait for all videos to precache
Promise.all(preloadPromises).then(() => {
console.log('all the videos can be played through');
// all the videos can be played through
preloadOverlay.classList.add('hide');
});
<html>
<body>
<div id="preload">
<h1>
Download...
</h1>
</div>
<video preload="auto" class="active">
<source src="video1.mp4" type='video/mp4'>
</video>
<video preload="auto">
<source src="video2.mp4" type='video/mp4'>
</video>
<video preload="auto">
<source src="video3.mp4" type='video/mp4'>
</video>
<video preload="auto">
<source src="video4.mp4" type='video/mp4'>
</video>
</body>
</html>