Files
com.xaymar.www/assets/site.js
T
Michael Fabian 'Xaymar' Dirks 58d126287e Significant video player improvements
2022-11-26 05:12:02 +01:00

283 lines
7.5 KiB
JavaScript

async function xmr_media_lazyload_perform(element) {
let content = element.querySelector("noscript");
if (content) {
element.innerHTML = content.innerText;
}
}
async function xmr_media_lazyload_initialize() {
// Figure out what to load.
let elements = document.querySelectorAll(".block-media > [data-lazyload]");
let stack = Array.from(elements);
console.debug("Lazily loading " + stack.length + " elements...");
// Add a lazyloading handler to all entries.
for (let el of stack) {
xmr_media_lazyload_perform(el);
}
}
async function xmr_initialize_player(el) {
let media = el.querySelector("video");
if (!media)
el.querySelector("audio");
// Play/Pause
let play_pause = el.querySelector(".bottom > .play");
play_pause.update = function() {
if (media.paused) {
play_pause.classList.remove("playing");
play_pause.innerText = "⏵";
} else if (media.error || media.ended) {
play_pause.classList.remove("playing");
play_pause.innerText = "⏹";
} else {
play_pause.classList.add("playing");
play_pause.innerText = "⏸";
}
}
play_pause.addEventListener("click", () => {
if (media.paused) {
media.play();
} else {
media.pause();
}
});
media.addEventListener("play", () => { play_pause.update(); });
media.addEventListener("pause", () => { play_pause.update(); });
media.addEventListener("ended", () => { play_pause.update(); });
media.addEventListener("error", () => { play_pause.update(); });
play_pause.update();
// Mute
let audio_mute = el.querySelector(".bottom > .audio > .mute");
audio_mute.update = function() {
if (media.muted) {
audio_mute.classList.add("muted");
audio_mute.innerText = "🔇";
} else {
audio_mute.classList.remove("muted");
if (media.volume > 0.5) {
audio_mute.innerText = "🔊";
} else if (media.volume > 0.125) {
audio_mute.innerText = "🔉";
} else {
audio_mute.innerText = "🔈";
}
}
}
audio_mute.addEventListener("click", () => {
media.muted = !media.muted;
});
media.addEventListener("volumechange", () => {
audio_mute.update();
});
audio_mute.update();
// Volume
let audio_volume = el.querySelector(".bottom > .audio > .volume");
audio_volume.min = 0;
audio_volume.max = 2147483647;
audio_volume.update = function() {
let min = parseInt(audio_volume.min, 10);
let max = parseInt(audio_volume.max, 10);
let dlt = max - min;
audio_volume.value = (media.volume * dlt) + min;
if (media.muted) {
audio_volume.classList.add("muted");
} else {
audio_volume.classList.remove("muted");
}
}
audio_volume.addEventListener("input", () => {
let min = parseInt(audio_volume.min, 10);
let max = parseInt(audio_volume.max, 10);
let val = parseInt(audio_volume.value, 10);
let dlt = max - min;
let vol = (val + min) / dlt;
media.volume = vol;
media.muted = (media.volume < 0.01);
});
media.addEventListener("volumechange", () => { audio_volume.update(); });
audio_volume.update();
// Time
let playback_time = el.querySelector(".bottom > .playback > .time");
playback_time.update = function() {
let duration_text = "";
let need_hour = false;
if (isNaN(media.duration)) {
duration_text = "Error";
} else if (!isFinite(media.duration)) {
duration_text = "Unknown";
} else {
let dur = media.duration;
let s = dur % 60;
let m0 = (dur - s) / 60;
let m = m0 % 60;
let h = (m0 - m) / 60;
let ss = Math.floor(s).toString().padStart(2, '0');
let ms = Math.floor(m).toString().padStart(2, '0');
if (h > 0) {
duration_text = `${h}:${ms}:${ss}`;
need_hour = true;
} else {
duration_text = `${ms}:${ss}`;
}
}
let current_text = "";
{
let dur = media.currentTime;
let s = dur % 60;
let m0 = (dur - s) / 60;
let m = m0 % 60;
let h = (m0 - m) / 60;
let ss = Math.floor(s).toString().padStart(2, '0');
let ms = Math.floor(m).toString().padStart(2, '0');
if (need_hour) {
current_text = `${h}:${ms}:${ss}`;
} else {
current_text = `${ms}:${ss}`;
}
}
playback_time.innerText = `${current_text} / ${duration_text}`;
}
media.addEventListener("timeupdate", () => { playback_time.update(); });
media.addEventListener("loadedmetadata", () => { playback_time.update(); });
playback_time.update();
// Progress
let playback_progress = el.querySelector(".bottom > .playback > .progress");
playback_progress.update = function() {
playback_progress.disabled = !media.seekable;
playback_progress.min = 0;
playback_progress.max = media.duration * 100;
playback_progress.value = media.currentTime * 100;
}
playback_progress.addEventListener("input", () => {
media.currentTime = parseInt(playback_progress.value, 10) / 100;
});
media.addEventListener("timeupdate", () => { playback_progress.update(); });
media.addEventListener("loadedmetadata", () => { playback_progress.update(); });
playback_progress.update();
// Fullscreen
let fullscreen = el.querySelector(".fullscreen");
fullscreen.update = function() {
if (document.fullscreenElement) {
fullscreen.innerText = "⬚";
} else {
fullscreen.innerText = "⛶";
}
};
fullscreen.addEventListener("click", () => {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
el.requestFullscreen();
}
});
el.addEventListener("fullscreenchange", (ev) => {
fullscreen.update();
});
fullscreen.update();
// Variants
let variants = el.querySelector(".variant");
variants.addEventListener("input", () => {
media.pause();
play_pause.update();
media.src = variants.value;
});
variants.addEventListener("value", () => {
media.pause();
play_pause.update();
media.src = variants.value;
});
function createVariants(el, key, value) {
if (typeof(value) === "object") {
for (let k in value) {
let v = value[k];
createVariants(el, `${key} / ${k}`, v);
}
} else if (typeof(value) === "string") {
let option = document.createElement("option");
option.value = value;
option.textContent = key;
el.appendChild(option);
} else {
el.appendChild(document.createElement(typeof(value)));
}
}
for (let k in el.variants) {
let v = el.variants[k];
createVariants(variants, k, v);
}
variants.value = media.src = variants.querySelectorAll("option")[0].value;
// Media Play/Pause by click
media.addEventListener("click", () => {
play_pause.click();
})
// Hide/Show controls
el.showOverlay = function() {
el.cancelHideOverlay();
el.classList.remove("hide");
}
el.hideOverlay = function() {
if (!media.paused && !media.ended && !media.error) {
el.classList.add("hide");
}
}
el.delayHideOverlay = function() {
el.cancelHideOverlay();
el.timer = setTimeout(() => { el.hideOverlay(); }, 2500);
}
el.cancelHideOverlay = function() {
if (el.timer) {
clearTimeout(el.timer);
}
}
el.addEventListener("mousemove", () => {
el.showOverlay();
if (!media.paused && !media.ended && !media.error) {
el.delayHideOverlay();
}
});
el.hideOverlay();
}
async function xmr_initialize_players() {
// Figure out what to initialize.
let elements = document.querySelectorAll(".block-media.player");
let stack = Array.from(elements);
console.debug("Initializing " + stack.length + " players...");
// Add a lazyloading handler to all entries.
for (let el of stack) {
xmr_initialize_player(el);
}
}
(function() {
'use strict';
// Support for Mobile Devices
document.querySelector("#navigation-toggle").addEventListener("click", (ev) => {
document.querySelector("#header #navigation").classList.toggle("open");
});
// Lazily load Media
xmr_media_lazyload_initialize();
// Initialize media player.
xmr_initialize_players();
})();