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(".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(".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(".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(".time"); playback_time.update = function() { function formatSeconds(seconds, with_ms, with_minutes, with_hour) { let result = []; if (isFinite(seconds) && !isNaN(seconds)) { let tainted_seconds = seconds % 60; let pure_seconds = Math.floor(seconds % 60); let tainted_minutes = ((seconds - pure_seconds) / 60); let pure_minutes = Math.floor(tainted_minutes % 60); let pure_hours = Math.floor((tainted_minutes - pure_minutes) / 60); result.unshift(`${pure_seconds.toString(10).padStart(2, '0')}`); if (with_ms) { result[0] = `${result[0]}.${Math.floor((tainted_seconds % 1) * 100).toString(10).padStart(2, '0')}` } if ((with_minutes === true) || ((with_minutes === undefined) && (pure_minutes > 0))) { result[0] = result[0].padStart(2, '0'); result.unshift(`${pure_minutes.toString(10)}`); } if ((with_hour === true) || ((with_hour === undefined) && (pure_hours > 0))) { result[0] = result[0].padStart(2, '0'); result.unshift(`${pure_hours.toString(10)}`); } } return result; } let duration = formatSeconds(media.duration, true); let current = formatSeconds(media.currentTime, true, duration.length >= 2, duration.length >= 3); for (let idx in duration) { current[idx].padStart(duration[idx].length, '0'); } if (duration.length > 0) { playback_time.innerText = `${current.join(':')} / ${duration.join(':')}`; } else { playback_time.innerText = `${current.join(':')}`; } } media.addEventListener("timeupdate", () => { playback_time.update(); }); media.addEventListener("durationupdate", () => { playback_progress.update(); }); media.addEventListener("loadedmetadata", () => { playback_time.update(); }); playback_time.update(); // Progress let playback_progress = el.querySelector(".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", () => { if (isFinite(media.duration)) { media.currentTime = parseInt(playback_progress.value, 10) / 100; } }); media.addEventListener("timeupdate", () => { playback_progress.update(); }); media.addEventListener("durationupdate", () => { playback_progress.update(); }); media.addEventListener("loadeddata", () => { 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(); }) // Media Fullscreen by dblclick media.addEventListener("dblclick", () => { fullscreen.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(); // Variants let variant = el.querySelector(".variant"); variant.update = function() { // Store current state and pause. let paused = media.paused; let muted = media.muted; let volume = media.volume; let time = media.currentTime; media.pause(); play_pause.update(); // Tell the media source to begin loading. media.src = variant.value; media.load(); media.currentTime = time; media.addEventListener("canplay", () => { media.currentTime = time; media.volume = volume; media.muted = muted; if (paused) { media.pause(); } else { media.play(); } play_pause.update(); }, { "once": true }) } 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; } 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(); })();