(function () { var HLS_CDN = "https://cdn.jsdelivr.net/npm/hls.js@1.5.7/dist/hls.min.js"; function loadHls() { if (window.Hls) return Promise.resolve(); if (window.__hlsLoad) return window.__hlsLoad; window.__hlsLoad = new Promise(function (resolve, reject) { var s = document.createElement("script"); s.src = HLS_CDN; s.async = true; s.onload = resolve; s.onerror = reject; document.head.appendChild(s); }); return window.__hlsLoad; } function ready(fn) { if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", fn, { once: true }); } else { fn(); } } function addDecorativeCaptionsTrack(video) { if (video.querySelector('track[data-ps-track="1"]')) return; var vtt = "WEBVTT\n\nNOTE\nThis video has no spoken dialogue.\n\n1\n00:00:00.000 --> 00:00:00.001\n.\n"; var track = document.createElement("track"); track.setAttribute("data-ps-track", "1"); track.kind = "captions"; track.label = "No speech"; track.srclang = "en"; track.src = "data:text/vtt;charset=utf-8," + encodeURIComponent(vtt); video.appendChild(track); if (video.textTracks && video.textTracks.length) { try { video.textTracks[0].mode = "hidden"; } catch (e) {} } } function muxMp4FromUrl(url) { var m = (url || "").match(/stream\.mux\.com\/([^/?#]+)/i); if (!m) return ""; var id = m[1].replace(/\.m3u8$/i, ""); return "https://stream.mux.com/" + id + "/capped-1080p.mp4"; } function applyVideoFlags(video) { video.muted = true; video.defaultMuted = true; video.autoplay = true; video.loop = true; video.playsInline = true; video.setAttribute("muted", ""); video.setAttribute("autoplay", ""); video.setAttribute("loop", ""); video.setAttribute("playsinline", ""); video.setAttribute("preload", "auto"); video.removeAttribute("data-lazy-load"); } function requestPlay(video) { function tryPlay() { if (!video || !video.paused) return; video.muted = true; video.play().catch(function () {}); } tryPlay(); video.addEventListener("canplay", tryPlay); video.addEventListener("loadeddata", tryPlay); document.addEventListener("visibilitychange", function () { if (!document.hidden) tryPlay(); }); window.addEventListener("pageshow", tryPlay); } function attachHls(video, url) { loadHls() .then(function () { if (!window.Hls || !Hls.isSupported()) { video.src = url; requestPlay(video); return; } var hls = new Hls({ enableWorker: true, autoStartLoad: true }); hls.loadSource(url); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, function () { requestPlay(video); }); video._hls = hls; }) .catch(function () { video.src = url; requestPlay(video); }); } function startVideo(video) { addDecorativeCaptionsTrack(video); var url = video.getAttribute("data-hls-src") || video.getAttribute("data-src") || video.getAttribute("src") || ""; if (!url) return; if (video.dataset.hlsInit === "1") { requestPlay(video); return; } video.dataset.hlsInit = "1"; applyVideoFlags(video); var isHls = /\.m3u8(\?|#|$)/i.test(url); var isMp4 = /\.mp4(\?|#|$)/i.test(url); var muxMp4 = muxMp4FromUrl(url); if (isMp4) { if (video.src !== url) video.src = url; requestPlay(video); return; } // Chrome autoplay: progressive MP4, not HLS if (muxMp4) { video.src = muxMp4; video.addEventListener( "error", function () { if (isHls) attachHls(video, url); }, { once: true } ); requestPlay(video); return; } if (!isHls) return; // hls.js first; native HLS only if MSE is unavailable (Safari) if (window.Hls && Hls.isSupported()) { attachHls(video, url); return; } if (video.canPlayType("application/vnd.apple.mpegurl")) { video.src = url; requestPlay(video); return; } attachHls(video, url); } ready(function () { var videos = document.querySelectorAll("video"); var needsHls = Array.prototype.some.call(videos, function (video) { var url = video.getAttribute("data-hls-src") || video.getAttribute("data-src") || video.getAttribute("src") || ""; return /\.m3u8(\?|#|$)/i.test(url) && !muxMp4FromUrl(url); }); var initAll = function () { videos.forEach(startVideo); }; if (needsHls) { loadHls().then(initAll).catch(initAll); } else { initAll(); } }); })();