feat: implement lazy loading for hls.js and enhance video player initialization
CI / test (push) Successful in 6m9s
CI / docker (push) Successful in 3m11s
CI / release (push) Skipped

This commit is contained in:
zwitschi committed 2026-08-04 19:43:39 +02:00
1 parent fca4286d87
commit dd5789fcd9
3 files changed
+18 -7

No files matched your search

+1
View File
@@ -19,6 +19,7 @@
- Updated chat runtime image to include ffmpeg/ffprobe for media duration probing on upload. - Updated chat runtime image to include ffmpeg/ffprobe for media duration probing on upload.
- Rebuilt viewer, admin, and admin-login pages around custom semantic class structures with accessibility-focused landmarks, tab semantics, and keyboard-focus behavior. - Rebuilt viewer, admin, and admin-login pages around custom semantic class structures with accessibility-focused landmarks, tab semantics, and keyboard-focus behavior.
- Replaced legacy and Tailwind-based stylesheet rules with a custom design-token CSS system covering responsive layouts, forms, tables, and reduced-motion behavior. - Replaced legacy and Tailwind-based stylesheet rules with a custom design-token CSS system covering responsive layouts, forms, tables, and reduced-motion behavior.
- Code-split `hls.js` via lazy loading in the viewer bootstrap to shrink the main frontend bundle and isolate stream playback logic into a dedicated chunk.
### Fixed ### Fixed
+16 -7
View File
@@ -1,6 +1,7 @@
import Hls from "hls.js";
import "./style.css"; import "./style.css";
type HlsClass = typeof import("hls.js")["default"];
declare global { declare global {
interface Window { interface Window {
switchRoom: (room: string) => void; switchRoom: (room: string) => void;
@@ -9,7 +10,7 @@ declare global {
} }
} }
let hls: Hls | null = null; let hls: InstanceType<HlsClass> | null = null;
let ws: WebSocket | null = null; let ws: WebSocket | null = null;
let currentRoom = "main"; let currentRoom = "main";
let username = "viewer" + Math.floor(Math.random() * 1000); let username = "viewer" + Math.floor(Math.random() * 1000);
@@ -109,18 +110,26 @@ function addMessage(
messages.scrollTop = messages.scrollHeight; messages.scrollTop = messages.scrollHeight;
} }
function initPlayerAndChat() { async function initPlayerAndChat() {
const video = document.getElementById("player") as HTMLVideoElement; const video = document.getElementById("player") as HTMLVideoElement;
const manifestUrl = resolveManifestUrl(); const manifestUrl = resolveManifestUrl();
if (video.canPlayType("application/vnd.apple.mpegurl")) {
video.src = manifestUrl;
video.addEventListener("loadedmetadata", () => video.play());
} else {
try {
const { default: Hls } = await import("hls.js");
if (Hls.isSupported()) { if (Hls.isSupported()) {
hls = new Hls(); hls = new Hls();
hls.loadSource(manifestUrl); hls.loadSource(manifestUrl);
hls.attachMedia(video); hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, () => video.play()); hls.on(Hls.Events.MANIFEST_PARSED, () => video.play());
} else if (video.canPlayType("application/vnd.apple.mpegurl")) { }
video.src = manifestUrl; } catch (error) {
video.addEventListener("loadedmetadata", () => video.play()); console.error("Failed to load HLS player", error);
addMessage("system", "Unable to initialize video player.");
}
} }
connectWebSocket("main"); connectWebSocket("main");
@@ -183,5 +192,5 @@ window.sendMessage = sendMessage;
window.togglePrivateDM = togglePrivateDM; window.togglePrivateDM = togglePrivateDM;
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
initPlayerAndChat(); void initPlayerAndChat();
}); });
+1
View File
@@ -3,6 +3,7 @@ import { defineConfig } from "vite";
export default defineConfig({ export default defineConfig({
envDir: "..", envDir: "..",
build: { build: {
chunkSizeWarningLimit: 600,
rollupOptions: { rollupOptions: {
input: { input: {
main: "index.html", main: "index.html",