Review this code. I think the AI has made it too complex and unmaintainable, too many conditions etc. it’s technically correct, but overkill.
/**
- ULC Background Video – Playback Bootstrap and UI helpers
-
- Purpose
- Initialize and drive the background
- most reliable pipeline per platform:
-
- Safari/iOS → native HLS (media element src = .m3u8)
-
- Other browsers → RxPlayer (DASH .mpd)
- Manifests
- Generated via website_utils/hls_dash_converter.py and emitted to:
-
- assets/video/stream.m3u8 (HLS master)
-
- assets/video/stream.mpd (DASH MPD)
- Design principles
-
- Resolution-first: pick the largest rendition appropriate for the display.
-
- Simplicity: minimal knobs, easy to trace and debug.
-
- Safe defaults: autoplay/inline/muted attributes set for broad compatibility.
- Debugging
-
- Set window.__ULC_VIDEO_DEBUG = true in DevTools to enable verbose logs.
*/
// Use an event listener (safer than overwriting onload in case other scripts also register handlers)
window.addEventListener(‘load’, (event) => { bootstrapBackgroundVideo(event); });
/**
- Bootstrap background video playback according to the current platform.
-
- On Safari/iOS: rely on native HLS playback.
-
- On other browsers: instantiate RxPlayer for DASH playback and apply a
- simple display-driven bitrate cap.
- @param {Event} event - The window ‘load’ event.
*/
function bootstrapBackgroundVideo(event) {
// Basic platform detection. Prefer native HLS on Safari/iOS.
const ua = navigator.userAgent || "";
const isIosDevice = /iPad|iPhone|iPod/.test(ua);
// Detect iPadOS Safari that spoofs Mac by checking touch points
const isIPadOS = navigator.platform === ‘MacIntel’ && navigator.maxTouchPoints > 1;
const isIOS = isIosDevice || isIPadOS;
// Reliable Safari detection (exclude Chrome/Edge on iOS/macOS)
const isSafari = /^Apple/.test(navigator.vendor || "") && /Safari/.test(ua) && !/CriOS|FxiOS|EdgiOS|Chrome/.test(ua);
// Manifests produced by the converter script
const HLS_URL = “assets/video/stream.m3u8”;
const DASH_URL = “assets/video/stream.mpd”;
// Grab the video element from DOM
const videoEl = document.getElementById(“bg-video”);
// Abort early if the expected element is missing. This allows the script to
// be included on pages without a background video without throwing errors.
if (!videoEl) {
if (typeof window !== ‘undefined’ && window.__ULC_VIDEO_DEBUG) {
console.warn(‘[Video] #bg-video element not found; bootstrap aborted.’);
}
return;
}
// Ensure attributes to satisfy autoplay policies across platforms
const ensureAutoplayAttrs = () => {
videoEl.muted = true; // set BEFORE src/play
videoEl.setAttribute(“muted”, “true”);
videoEl.setAttribute(“playsinline”, “true”);
videoEl.setAttribute(“webkit-playsinline”, “true”);
videoEl.setAttribute(“autoplay”, “true”);
videoEl.setAttribute(“loop”, “true”);
videoEl.preload = “auto”;
// IMPORTANT: Do not hide the video on desktop browsers (e.g., Brave/Chrome/Firefox on macOS).
// Hiding was intended to avoid flash on iOS where autoplay is flaky and UI overlays may flash.
// Keep hidden only on iOS/iPadOS; reveal immediately elsewhere.
videoEl.classList.add("is-hidden");
// If markup or prior runs left the class, clean it up for desktop.
videoEl.classList.remove("is-hidden");
videoEl.classList.add("is-ready");
};
ensureAutoplayAttrs();
// Define a simple rendition ladder we know our manifests contain.
// Heights are used only to pick a max bitrate cap per display size.
const LADDER = [
{ height: 1080, brKbps: 5000 },
{ height: 720, brKbps: 2800 },
{ height: 540, brKbps: 1800 },
{ height: 360, brKbps: 1000 },
{ height: 240, brKbps: 500 },
];
// Helper: pick target tier by current display height
const getScreenH = () => Math.max(window.screen?.height || 0, window.innerHeight || 0);
const pickTargetTier = () => {
const h = getScreenH();
// Choose the largest rung not exceeding the display height
const tier = LADDER.find(t => t.height <= h) || LADDER[LADDER.length - 1];
return { h, tier };
};
// ------------------------------------------------------------
// Minimal Debug helpers
// ------------------------------------------------------------
// Toggle logging: set window.__ULC_VIDEO_DEBUG = true in DevTools
const DEBUG = (typeof window.__ULC_VIDEO_DEBUG === “boolean”) ? window.__ULC_VIDEO_DEBUG : false;
const log = (msg, data) => { if (DEBUG) console.log([Video] ${msg}, data || ""); };
// Shared state (kept tiny)
const state = {
transport: null, // ‘native_hls’ | ‘dash’
videoHeight: 0,
capKbps: null,
};
const revealWhenPlaying = () => {
if (videoEl.classList.contains(‘is-hidden’)) {
videoEl.classList.replace(‘is-hidden’, ‘is-ready’);
} else {
videoEl.classList.add(‘is-ready’);
videoEl.classList.remove(‘is-hidden’);
}
};
if ((isIOS || isSafari) && videoEl.canPlayType && videoEl.canPlayType(‘application/vnd.apple.mpegURL’)) {
// Safari/iOS: rely on the native player for HLS. It has solid ABR.
state.transport = ‘native_hls’;
log(“Using native HLS (Safari/iOS)”);
videoEl.src = HLS_URL;
videoEl.load();
const tryPlay = () => videoEl.play()
.then(() => revealWhenPlaying())
.catch((err) => {
// Autoplay was blocked. Keep muted, no controls, and retry after first user gesture.
console.warn(“Autoplay blocked; waiting for user gesture”, err);
const onTap = () => {
videoEl.play().then(() => {
revealWhenPlaying();
window.removeEventListener(“touchstart”, onTap);
window.removeEventListener(“click”, onTap);
}).catch(() => {/* still blocked, leave hidden or show a subtle fallback */});
};
window.addEventListener(“touchstart”, onTap, { once: true });
window.addEventListener(“click”, onTap, { once: true });
});
// Start playback attempt once metadata is available or immediately
if (videoEl.readyState >= 1) { tryPlay(); }
else { videoEl.addEventListener("loadedmetadata", tryPlay, { once: true }); }
// We cannot cap native ABR. Track resolution changes and notify on upres.
const updateNativeMetrics = (why) => {
const hNow = videoEl.videoHeight || 0;
if (hNow && hNow !== state.videoHeight) {
const prev = state.videoHeight;
state.videoHeight = hNow;
log(`Resolution change → ${hNow}p`);
videoEl.addEventListener('loadedmetadata', () => {
updateNativeMetrics('loadedmetadata');
videoEl.addEventListener('resize', () => updateNativeMetrics('resize'));
// Periodic check for ABR height changes
setInterval(() => updateNativeMetrics('poll_height'), 5000);
// Also handle native 'playing' event for completeness
videoEl.addEventListener('playing', revealWhenPlaying, { once: true });
} else {
// Other browsers: use RxPlayer for robust DASH playback with ABR control.
state.transport = ‘dash’;
log(“Using RxPlayer (DASH)”);
// Ensure the RxPlayer library is present before proceeding.
const RxCtor = (typeof window !== 'undefined' && window.RxPlayer) ?
window.RxPlayer : (typeof RxPlayer !== 'undefined' ? RxPlayer : null);
console.error("RxPlayer is not available. Ensure assets/vendor/rx-player is loaded before main.js");
const player = new RxCtor({
enableFastSwitching: true,
// Utility: apply a bitrate cap in kbps (immediate)
const setCap = (kbps) => {
// RxPlayer#setMaxVideoBitrate expects a value in kbps. Keep units consistent.
const val = Math.max(250_000, Math.floor(kbps *1000)); // 250 kbps floor
player.setMaxVideoBitrate(val);
log(`Cap set → ${val} kbps`);
} catch (e) { /* older builds */ }
// Initial cap purely from display size
const applyDisplayCap = () => {
const { h, tier } = pickTargetTier();
log(`Display ${h}px → target ${tier.height}p (~${tier.brKbps} kbps)`);
// Looping via HTML attribute already does the trick; some players support an option too.
// Reveal once playback actually starts (covers autoplay and user-gesture cases)
videoEl.addEventListener('playing', revealWhenPlaying, { once: true });
videoEl.addEventListener('loadeddata', () => {
// Fallback: if autoplay is allowed and data is loaded, try to play
videoEl.play().catch(() => {/* ignore */});
// Keep the cap aligned with display size on resize
window.addEventListener('resize', () => applyDisplayCap());
player.addEventListener("error", (err) => {
console.error("RxPlayer error:", err);
// Track resolution changes; show toast on upres
const onHeightCheck = (why) => {
const hNow = videoEl.videoHeight || 0;
if (hNow && hNow !== state.videoHeight) {
const prev = state.videoHeight;
state.videoHeight = hNow;
// Guard showToast in case it is not defined on this page
if (typeof showToast === 'function') {
showToast(`Video quality increased to ${hNow}p`);
log(`Toast: Video quality increased to ${hNow}p`);
log(`Upres → ${hNow}p (${why || ''})`);
log(`Resolution change → ${hNow}p (${why || ''})`);
// Prefer precise representationChange if available
player.addEventListener('representationChange', () => {
setTimeout(() => onHeightCheck('representationChange'), 0);
setInterval(() => onHeightCheck('poll_height'), 5000);
}
}
(function() {
“use strict”;
// ------------------------------------------------------------
// DOM utilities and small UI interactions
// ------------------------------------------------------------
// Lightweight, framework-agnostic helpers used by various pages. These keep
// repetitive code tidy without introducing a dependency on a larger library.
/**
- Query selector helper.
- @param {string} el - CSS selector to query.
- @param {boolean} [all=false] - If true, returns an array of all matches; otherwise the first match (or null).
- @returns {Element|Element[]|null}
*/
const select = (el, all = false) => {
el = el.trim()
if (all) {
return […document.querySelectorAll(el)]
} else {
return document.querySelector(el)
}
}
/**
- Event listener helper.
- @param {string} type - Event type (e.g., ‘click’, ‘scroll’).
- @param {string} el - CSS selector for the target element(s).
- @param {Function} listener - Event handler callback.
- @param {boolean} [all=false] - When true, attaches to all matching elements.
*/
const on = (type, el, listener, all = false) => {
let selectEl = select(el, all)
if (selectEl) {
if (all) {
selectEl.forEach(e => e.addEventListener(type, listener))
} else {
selectEl.addEventListener(type, listener)
}
}
}
/**
- onscroll helper.
- @param {Element|Window|Document} el - Scrollable element to listen on.
- @param {Function} listener - Scroll handler.
*/
const onscroll = (el, listener) => {
el.addEventListener(‘scroll’, listener)
}
/**
- Burger menu toggle for narrow viewports.
- Toggles the ‘active’ class on the .burger element on click.
*/
const burgerMenu = select(‘.burger’)
on(‘click’, ‘.burger’, function(e) {
burgerMenu.classList.toggle(‘active’);
})
document.addEventListener(“DOMContentLoaded”, function () {
window.mobileAndTabletCheck = function() {
(function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) check = true;})(navigator.userAgent||navigator.vendor||window.opera);
if (window.mobileAndTabletCheck()) {
const items = document.querySelectorAll(".item-content");
if (!items.length) return;
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
const el = entry.target;
const ratio = entry.intersectionRatio;
// Appear when at least ~55% visible
el.classList.add('text-visible');
// Disappear only when it’s almost fully gone (prevents early top firing on up-scroll)
el.classList.remove('text-visible');
}
}, {
root: null,
// Linger longer as it leaves the viewport from either edge
rootMargin: ‘0px 0px -30% 0px’,
// Multiple thresholds give us stable ratio updates
threshold: [0, 0.15, 0.55, 0.75, 0.95,1]
});
items.forEach(item => observer.observe(item));
});
})()