2022-05-14 08:48:18 +02:00
|
|
|
async function xmr_media_lazyload_perform(element) {
|
|
|
|
|
let content = element.querySelector("noscript");
|
|
|
|
|
if (content) {
|
|
|
|
|
element.innerHTML = content.innerText;
|
|
|
|
|
}
|
2022-01-12 21:56:02 +01:00
|
|
|
}
|
|
|
|
|
|
2022-05-14 08:48:18 +02:00
|
|
|
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...");
|
2022-01-12 21:56:02 +01:00
|
|
|
|
2022-05-14 08:48:18 +02:00
|
|
|
// Add a lazyloading handler to all entries.
|
|
|
|
|
for (let el of stack) {
|
|
|
|
|
xmr_media_lazyload_perform(el);
|
|
|
|
|
}
|
2022-01-12 21:56:02 +01:00
|
|
|
}
|
|
|
|
|
|
2022-11-26 05:12:02 +01:00
|
|
|
async function xmr_initialize_player(el) {
|
|
|
|
|
let media = el.querySelector("video");
|
|
|
|
|
if (!media)
|
|
|
|
|
el.querySelector("audio");
|
|
|
|
|
|
|
|
|
|
// Play/Pause
|
2022-11-27 00:53:36 +01:00
|
|
|
let play_pause = el.querySelector(".play");
|
2022-11-26 05:12:02 +01:00
|
|
|
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
|
2022-11-27 00:53:36 +01:00
|
|
|
let audio_mute = el.querySelector(".mute");
|
2022-11-26 05:12:02 +01:00
|
|
|
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
|
2022-11-27 00:53:36 +01:00
|
|
|
let audio_volume = el.querySelector(".volume");
|
2022-11-26 05:12:02 +01:00
|
|
|
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
|
2022-11-27 00:53:36 +01:00
|
|
|
let playback_time = el.querySelector(".time");
|
2022-11-26 05:12:02 +01:00
|
|
|
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
|
2022-11-27 00:53:36 +01:00
|
|
|
let playback_progress = el.querySelector(".progress");
|
2022-11-26 05:12:02 +01:00
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
// Media Play/Pause by click
|
|
|
|
|
media.addEventListener("click", () => {
|
|
|
|
|
play_pause.click();
|
|
|
|
|
})
|
|
|
|
|
|
2022-11-26 05:20:02 +01:00
|
|
|
// Media Fullscreen by dblclick
|
|
|
|
|
media.addEventListener("dblclick", () => {
|
|
|
|
|
fullscreen.click();
|
|
|
|
|
})
|
|
|
|
|
|
2022-11-26 05:12:02 +01:00
|
|
|
// 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();
|
2022-11-27 00:53:36 +01:00
|
|
|
|
|
|
|
|
// Variants
|
|
|
|
|
let variant = el.querySelector(".variant");
|
|
|
|
|
variant.update = function() {
|
|
|
|
|
let paused = media.paused;
|
|
|
|
|
let muted = media.muted;
|
|
|
|
|
let volume = media.volume;
|
|
|
|
|
let time = media.currentTime;
|
|
|
|
|
|
|
|
|
|
media.pause();
|
|
|
|
|
media.currentSrc = variant.value;
|
|
|
|
|
media.play();
|
|
|
|
|
|
|
|
|
|
media.currentTime = time;
|
|
|
|
|
media.volume = volume;
|
|
|
|
|
media.muted = muted;
|
|
|
|
|
if (paused) {
|
|
|
|
|
media.pause();
|
|
|
|
|
} else {
|
|
|
|
|
media.play();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
play_pause.update();
|
|
|
|
|
}
|
|
|
|
|
variant.addEventListener("input", () => { variant.update(); });
|
|
|
|
|
variant.addEventListener("value", () => { variant.update(); });
|
|
|
|
|
|
|
|
|
|
// Add options from available sources.
|
|
|
|
|
let sources = el.querySelectorAll("source");
|
|
|
|
|
for (let k of sources) {
|
|
|
|
|
let option = document.createElement("option");
|
|
|
|
|
option.value = k.src;
|
|
|
|
|
option.textContent = k.title;
|
|
|
|
|
variant.appendChild(option);
|
|
|
|
|
}
|
|
|
|
|
variant.value = media.currentSrc;
|
2022-11-26 05:12:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-24 20:05:17 +01:00
|
|
|
(function() {
|
2021-12-24 20:14:03 +01:00
|
|
|
'use strict';
|
2021-12-24 20:05:17 +01:00
|
|
|
|
|
|
|
|
// Support for Mobile Devices
|
|
|
|
|
document.querySelector("#navigation-toggle").addEventListener("click", (ev) => {
|
|
|
|
|
document.querySelector("#header #navigation").classList.toggle("open");
|
|
|
|
|
});
|
|
|
|
|
|
2022-01-12 21:56:02 +01:00
|
|
|
// Lazily load Media
|
|
|
|
|
xmr_media_lazyload_initialize();
|
2022-11-26 05:12:02 +01:00
|
|
|
|
|
|
|
|
// Initialize media player.
|
|
|
|
|
xmr_initialize_players();
|
2021-12-24 20:05:17 +01:00
|
|
|
})();
|