diff --git a/src/lib/components/widget/CameraStreamWidget.svelte b/src/lib/components/widget/CameraStreamWidget.svelte index b8787b0..91fff05 100644 --- a/src/lib/components/widget/CameraStreamWidget.svelte +++ b/src/lib/components/widget/CameraStreamWidget.svelte @@ -14,6 +14,7 @@ let error = $state(false); let fullscreen = $state(false); let videoEl: HTMLVideoElement | null = $state(null); + let fullscreenVideoEl: HTMLVideoElement | null = $state(null); const streamType = $derived(config.type ?? 'image'); const refreshMs = $derived((config.refreshInterval ?? 10) * 1000); @@ -106,6 +107,34 @@ }; }); + // HLS.js for fullscreen video element + $effect(() => { + if (streamType !== 'hls' || !fullscreenVideoEl) return; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let hls: any = null; + + (async () => { + try { + const { default: Hls } = await import('hls.js'); + if (Hls.isSupported()) { + hls = new Hls(); + hls.loadSource(config.streamUrl); + hls.attachMedia(fullscreenVideoEl!); + } else if (fullscreenVideoEl!.canPlayType('application/vnd.apple.mpegurl')) { + fullscreenVideoEl!.src = config.streamUrl; + } + } catch { + if (fullscreenVideoEl!.canPlayType('application/vnd.apple.mpegurl')) { + fullscreenVideoEl!.src = config.streamUrl; + } + } + })(); + + return () => { + if (hls) hls.destroy(); + }; + }); + function handleImgError() { error = true; loading = false; @@ -206,13 +235,15 @@