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(); })();