I have a video playlist made with video.js and JavaScript. I added a js file duration.js to show the length of each video in the playlist and it works. but most of the time, if I refresh the page, the duration will disappear for some or all the videos, and it might appear randomly for different videos each time I refresh. I have a feeling it has to do with what script runs first or something like that. I am putting part of the relevant code below:
DEMO: https://cheerful-bienenstitch-239dd7.netlify.app/lessons.html
note: the page works as expected but the only problem is the duration disappearing at refresh. also, I noticed if the developers console is open, it loads correctly!
MAIN PAGE: the page that contains the playlist, I included only 3 videos
- at the bottom of the page I'm calling duration.js, and vid.js (this is the file that contains video.js instance and other settings)
//Bootstrap library CDN
<!-- style for the page -->
<link rel="stylesheet" href="lessons_style.css">
<!-- style for video.js -->
<link href="https://vjs.zencdn.net/7.18.1/video-js.css" rel="stylesheet" />
<!-- Quality selector CSS -->
<link href="https://unpkg.com/@silvermine/videojs-quality-selector/dist/css/quality-selector.css"
rel="stylesheet" />
<body>
<a href="" id="dark" class="btn btn-outline-primary">Dark Mode</a>
<div class="containers">
<div class="main-video">
<div class="video">
<video autofocus id="playedVideo" class="video-js vjs-big-play-centered" max-width="100%" height="auto">
<source
src="https://cdn.videvo.net/videvo_files/video/free/2013-09/large_watermarked/AbstractRotatingCubesVidevo_preview.mp4"
type="video/mp4" label="720P" />
<source src="https://cdn.videvo.net/videvo_files/video/free/2013-09/large_watermarked/AbstractRotatingCubesVidevo_preview.mp4" type="video/mp4" label="480P" />
<source src="https://cdn.videvo.net/videvo_files/video/free/2013-09/large_watermarked/AbstractRotatingCubesVidevo_preview.mp4" type="video/mp4" label="144P" />
<p class="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a
web browser that
<a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a>
</p>
</video>
<h3 class="title">01. heres the video title</h3>
</div>
</div>
<!-- here comes the video list -->
<div class="video-list">
<div id="1" class="vid active">
<video>
<source
src="https://cdn.videvo.net/videvo_files/video/free/2013-09/large_watermarked/AbstractRotatingCubesVidevo_preview.mp4"
type="video/mp4" label="720P" />
<source
src="https://cdn.videvo.net/videvo_files/video/free/2013-09/large_watermarked/AbstractRotatingCubesVidevo_preview.mp4"
type="video/mp4" label="480P" />
<source
src="https://cdn.videvo.net/videvo_files/video/free/2013-09/large_watermarked/AbstractRotatingCubesVidevo_preview.mp4"
type="video/mp4" label="144P" />
</video>
<h3 class="title">01. heres the video title</h3>
<button class="btn btn-dark btn-sm"><span class="badge"></span></button>
</div>
<div id="2" class="vid">
<video>
<source
src="https://assets.mixkit.co/videos/preview/mixkit-traveling-on-the-highway-on-a-sunny-day-42368-large.mp4"
type="video/mp4" label="720P" />
<source
src="https://cdn.videvo.net/videvo_files/video/free/2013-09/large_watermarked/AbstractRotatingCubesVidevo_preview.mp4"
type="video/mp4" label="480P" />
<source
src="https://media.istockphoto.com/videos/digital-abstract-optic-lights-environment-video-id1272167390"
type="video/mp4" label="144P" />
</video>
<h3 class="title">02. heres the video title</h3>
<button class="btn btn-dark btn-sm"><span class="badge"></span></button>
</div>
<div id=3 class="vid">
<video muted>
<source
src="https://cdn.videvo.net/videvo_files/video/free/2013-08/large_watermarked/hd0992_preview.mp4"
type="video/mp4" label="720P" />
<source
src="https://cdn.videvo.net/videvo_files/video/free/2013-08/large_watermarked/hd0992_preview.mp4"
type="video/mp4" label="480P" />
<source
src="https://cdn.videvo.net/videvo_files/video/free/2013-08/large_watermarked/hd0992_preview.mp4"
type="video/mp4" label="144P" />
</video>
<h3 class="title">03. heres the video title</h3>
<button class="btn btn-dark btn-sm"><span class="badge"></span></button>
</div>
</body>
<!-- videoJS CDN -->
<script src="https://vjs.zencdn.net/7.18.1/video.min.js"></script>
<!-- hotkeys CDN -->
<script src="https://cdn.sc.gl/videojs-hotkeys/latest/videojs.hotkeys.min.js"></script>
<!-- quality selector CDN -->
<script src="https://unpkg.com/@silvermine/videojs-quality-selector/dist/js/silvermine-
videojs-quality-selector.min.js">
</script>
<!-- JavaScript for the vjs library -->
<script src="vid.js" defer></script>
<script src="duration.js" defer ></script>
duration.js
vElements = document.querySelectorAll("video");
for (let i = 1; i < vElements.length; i++) {
let video = document.getElementById(i).firstElementChild;
video.addEventListener('loadedmetadata', function () {
let vLength = video.duration;
// console.log(vLength + ' seconds \n');
document.getElementById(i).lastElementChild.innerHTML = format(vLength);
});
}
function format(s) {
var m = Math.floor(s / 60);
m = (m >= 10) ? m : "0" + m;
s = Math.floor(s % 60);
s = (s >= 10) ? s : "0" + s;
return m + ":" + s;
}
vid.js
let currentVideo = 1;
var myPlayer;
// Initialize the VideoJs Player
myPlayer = videojs("#playedVideo", {
preload: 'metadata',
controls: true,
fluid: true,
aspectRatio: "16:9",
playbackRates: [0.25, 0.5, 1, 1.5, 2],
plugins: {
hotkeys: {
seekStep: 5
}
},
});
myPlayer.controlBar.addChild("QualitySelector");
// Handle Vide Click
let listVideo = document.querySelectorAll('.video-list .vid');
let mainVideo = document.querySelector('.main-video video');
let title = document.querySelector('.main-video .title');
listVideo.forEach(video => {
video.onclick = () => {
currentVideo = Number(video.id)
listVideo.forEach(vid => vid.classList.remove('active'));
video.classList.add('active');
if (video.classList.contains('active')) {
let src0 = video.children[0].children[0].getAttribute("src");
let src1 = video.children[0].children[1].getAttribute("src");
let src2 = video.children[0].children[2].getAttribute("src");
document.querySelector('.video-list').scrollTo({ top: (video.getBoundingClientRect().top) - 150, behavior: 'smooth' });
myPlayer.src([
{
src: src0,
type: "video/mp4",
label: "720P",
selected: true
},
{
src: src1,
type: "video/mp4",
label: "480P",
},
{
src: src2,
type: "video/mp4",
label: "144P",
},
]);
myPlayer.play();
let text = video.children[1].innerHTML;
title.innerHTML = text;
}
}
});
// Handle Video PlayList
const video = document.querySelector("video");
video.addEventListener("ended", (event) => {
let listVideo = document.querySelectorAll(".video-list .vid");
let title = document.querySelector(".main-video .title");
listVideo.forEach((video) => {
if (video.id == currentVideo + 1) {
listVideo.forEach((vid) => vid.classList.remove("active"));
video.classList.add("active");
if (video.classList.contains("active")) {
let src0 = video.children[0].children[0].getAttribute("src");
let src1 = video.children[0].children[1].getAttribute("src");
let src2 = video.children[0].children[2].getAttribute("src");
// Handle Scrolling
document.querySelector('.video-list').scrollTo({ top: (video.getBoundingClientRect().y) - 120, behavior: 'smooth' });
myPlayer.src([
{
src: src0,
type: "video/mp4",
label: "720P",
selected: true
},
{
src: src1,
type: "video/mp4",
label: "480P",
},
{
src: src2,
type: "video/mp4",
label: "144P",
},
]);
myPlayer.ready(function () {
myPlayer.play();
});
let text = video.children[1].innerHTML;
title.innerHTML = text;
}
}
});
currentVideo++;
});
// Dark theme for lessons page, and save theme to local storage
let dark = document.getElementById('dark');
dark.addEventListener('click', (e) => {
e.preventDefault();
document.body.classList.toggle('dark');
if (dark.innerText == "Dark Mode") {
dark.innerHTML = "Light Mode";
localStorage.setItem('state', 'dark')
}
else {
dark.innerHTML = "Dark Mode";
localStorage.setItem('state', 'light')
}
});
// get the theme state from localStorage
if (localStorage.getItem('state') == 'dark') {
document.body.classList.toggle('dark');
if (dark.innerText == "Dark Mode") {
dark.innerHTML = "Light Mode";
}
else {
dark.innerHTML = "Dark Mode";
}
}