react-helios 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/VideoPlayer.tsx","../src/lib/format.ts","../src/lib/hls.ts","../src/hooks/useVideoPlayer.ts","../src/components/control-elements/index.ts","../src/components/control-elements/control-buttons.tsx","../src/components/control-elements/volume-control.tsx","../src/lib/vtt.ts","../src/components/control-elements/progress-bar.tsx","../src/components/control-elements/settings-menu.tsx","../src/components/control-elements/time-display.tsx","../src/components/Controls.tsx","../src/components/ContextMenu.tsx","../src/components/AudioModeOverlay.tsx","../src/lib/types.ts"],"names":["formatTime","seconds","total","h","m","s","isHLSUrl","url","getMimeType","lower","buildQualityLevels","levels","l","i","DEFAULT_STATE","useVideoPlayer","videoRef","src","options","hlsRef","useRef","fullscreenContainerRef","lastVolumeRef","networkRetriesRef","optionsRef","state","setState","useState","stateRef","bwSamplesRef","autoSwitchedRef","manualCooldownActiveRef","manualCooldownTimerRef","useEffect","video","prev","opts","HLS","hls","Events","_","data","threshold","bwKbps","samples","avg","v","MAX_RETRIES","delay","err","fatalErr","handlePlay","handlePause","handleEnded","handleTimeUpdate","handleDurationChange","dur","live","handleVolumeChange","vol","handleRateChange","handleError","e","handleWaiting","handleCanPlay","handlePlaying","handleFullscreenChange","fs","handlePiPChange","play","useCallback","pause","seek","time","setVolume","volume","toggleMute","restore","setPlaybackRate","rate","setQualityLevel","level","seekToLive","livePos","toggleFullscreen","container","togglePictureInPicture","toggleTheaterMode","next","toggleAudioMode","getState","currentTime","bufferedRanges","getVideoElement","ref","useMemo","control_elements_exports","__export","ControlElements","FullscreenButton","PauseButton","PiPButton","PlayButton","progress_bar_default","settings_menu_default","TheaterButton","time_display_default","volume_control_default","memo","onClick","jsx","isFullscreen","isPiP","isTheater","VolumeControl","isMuted","onVolumeChange","onToggleMute","showSlider","setShowSlider","displayVolume","percentage","sliderBackground","jsxs","parseVttTime","parts","resolveUrl","base","parseThumbnailVtt","text","baseUrl","cues","lines","line","arrow","start","end","urlLine","hashIdx","x","y","w","coords","findThumbnailCue","lo","hi","mid","ProgressBar","playerRef","enablePreview","thumbnailVtt","containerRef","progressFilledRef","scrubHandleRef","tooltipRef","hoverTimeTextRef","hoverIndicatorRef","thumbRef","setBufferedRanges","isDraggingRef","hoverPosRef","hoverTimeRef","lastCueRef","thumbnailCuesRef","rectCacheRef","invalidate","getRect","cancelled","r","updateProgress","ct","pct","updateBuffered","ranges","startDragging","stopDragging","showTooltip","hideTooltip","applyThumbnail","cue","el","getTimeFromClientX","clientX","rect","getPxFromClientX","handleKeyDown","step","handleMouseMove","px","tooltipWidth","containerWidth","halfWidth","clampedLeft","handleMouseLeave","handleMouseDown","handleClick","onTouchMove","handleTouchStart","handleTouchMove","up","bufferedSegments","range","width","SettingsMenu","currentRate","playbackRates","onRateChange","qualityLevels","currentQualityLevel","onQualityChange","open","setOpen","tab","setTab","hasQuality","handler","sortedLevels","a","b","currentQualityName","o","TimeDisplay","isLive","currentRef","durationRef","updateTime","updateDuration","Controls","playerContainerRef","isPlaying","playbackRate","isPictureInPicture","isTheaterMode","isAudioMode","showAudioButton","audioModeIcon","videoModeIcon","audioModeLabel","videoModeLabel","controlBarItems","autoHideControls","hideTimeoutRef","showControls","setShowControls","liveRef","handleShow","handleHide","target","playing","handleToggleMute","handleQualityChange","handlePiP","handleTheaterToggle","handleAudioToggle","handleFullscreen","handleSeekToLive","GoLiveButton","AudioModeButton","item","label","ContextMenu","onClose","contextMenuItems","menuRef","isLooping","setIsLooping","adjustedX","adjustedY","handleScroll","handlePlayPause","handleToggleLoop","handleCopyUrl","handleCopyTimestamp","Fragment","AudioModeOverlay","poster","logo","audioModeFallback","isBuffering","onOverlayClick","VideoPlayer","forwardRef","props","forwardedRef","className","controls","autoplay","muted","loop","preload","enableHLS","hlsConfig","subtitles","crossOrigin","audioSrc","defaultAudioMode","audioBandwidthThreshold","onPlay","onPause","onEnded","onError","onTimeUpdate","onDurationChange","onBuffering","onTheaterModeChange","onAudioModeChange","contextMenu","setContextMenu","React","handleVideoClick","handleDoubleClick","handleContextMenu","track","VideoPlayer_default","AUDIO_BANDWIDTH_THRESHOLDS"],"mappings":"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","file":"index.mjs","sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useEffect, useRef, useCallback, useState } from \"react\";\nimport type { VideoPlayerProps, VideoPlayerRef } from \"../lib/types\";\nimport { useVideoPlayer } from \"../hooks/useVideoPlayer\";\nimport { Controls } from \"./Controls\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { AudioModeOverlay } from \"./AudioModeOverlay\";\n\nconst VideoPlayer = forwardRef<VideoPlayerRef, VideoPlayerProps>(\n (props, forwardedRef) => {\n const { src, poster, className, controls = true, options = {} } = props;\n\n const {\n autoplay = false,\n muted = false,\n loop = false,\n preload = \"metadata\",\n playbackRates = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],\n enableHLS = true,\n enablePreview = true,\n thumbnailVtt,\n hlsConfig,\n autoHideControls = true,\n subtitles,\n crossOrigin,\n logo,\n audioModeFallback,\n audioSrc,\n showAudioButton,\n audioModeIcon,\n videoModeIcon,\n audioModeLabel,\n videoModeLabel,\n defaultAudioMode,\n audioBandwidthThreshold,\n onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n onDurationChange,\n onBuffering,\n onTheaterModeChange,\n onAudioModeChange,\n contextMenuItems,\n controlBarItems,\n } = options;\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n const { state, ref: playerRef, fullscreenContainerRef } = useVideoPlayer(\n videoRef,\n src,\n {\n autoplay,\n muted,\n loop,\n playbackRates,\n enableHLS,\n hlsConfig,\n defaultAudioMode,\n audioBandwidthThreshold,\n onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n onDurationChange,\n onBuffering,\n onTheaterModeChange,\n onAudioModeChange,\n },\n );\n\n const [contextMenu, setContextMenu] = useState<{ x: number; y: number } | null>(null);\n\n useEffect(() => {\n fullscreenContainerRef.current = containerRef.current;\n }, [fullscreenContainerRef]);\n\n React.useImperativeHandle(forwardedRef, () => playerRef, [playerRef]);\n\n const handleVideoClick = useCallback(() => {\n // Focus the container so keyboard shortcuts activate for this player\n containerRef.current?.focus();\n if (state.isPlaying) playerRef.pause();\n else playerRef.play();\n }, [state.isPlaying, playerRef]);\n\n const handleDoubleClick = useCallback(() => {\n playerRef.toggleFullscreen();\n }, [playerRef]);\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n setContextMenu({ x: e.clientX, y: e.clientY });\n }, []);\n\n\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n style={{\n position: \"relative\",\n width: \"100%\",\n backgroundColor: \"#000\",\n aspectRatio: \"16 / 9\",\n userSelect: \"none\",\n outline: \"none\",\n }}\n className={className}\n data-test=\"video-player-container\"\n data-theater={state.isTheaterMode ? \"true\" : undefined}\n onContextMenu={handleContextMenu}\n >\n <video\n ref={videoRef}\n poster={poster}\n preload={preload}\n crossOrigin={crossOrigin}\n onClick={handleVideoClick}\n onDoubleClick={handleDoubleClick}\n playsInline\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n cursor: \"pointer\",\n // Keep the element in the DOM so audio keeps playing; just hide it visually\n visibility: state.isAudioMode ? \"hidden\" : \"visible\",\n }}\n data-test=\"video-element\"\n >\n {subtitles?.map((track) => (\n <track\n key={track.id}\n kind=\"subtitles\"\n src={track.src}\n label={track.label}\n srcLang={track.srclang}\n default={track.default}\n />\n ))}\n </video>\n\n {/* Audio mode overlay — sits above video, below controls (DOM order) */}\n {state.isAudioMode && (\n <AudioModeOverlay\n poster={poster}\n logo={logo}\n audioModeFallback={audioModeFallback}\n isBuffering={state.isBuffering}\n onOverlayClick={handleVideoClick}\n />\n )}\n\n {controls && (\n <Controls\n videoRef={videoRef}\n playerRef={playerRef}\n playerContainerRef={containerRef}\n playbackRates={playbackRates}\n enablePreview={enablePreview}\n thumbnailVtt={state.isAudioMode ? undefined : thumbnailVtt}\n isPlaying={state.isPlaying}\n volume={state.volume}\n isMuted={state.isMuted}\n playbackRate={state.playbackRate}\n isFullscreen={state.isFullscreen}\n isPictureInPicture={state.isPictureInPicture}\n isTheaterMode={state.isTheaterMode}\n isAudioMode={state.isAudioMode}\n showAudioButton={showAudioButton ?? !!audioSrc}\n audioModeIcon={audioModeIcon}\n videoModeIcon={videoModeIcon}\n audioModeLabel={audioModeLabel}\n videoModeLabel={videoModeLabel}\n isLive={state.isLive}\n qualityLevels={state.qualityLevels}\n currentQualityLevel={state.currentQualityLevel}\n controlBarItems={controlBarItems}\n autoHideControls={autoHideControls}\n />\n )}\n\n {contextMenu && (\n <ContextMenu\n x={contextMenu.x}\n y={contextMenu.y}\n isPlaying={state.isPlaying}\n src={src}\n videoRef={videoRef}\n playerRef={playerRef}\n onClose={() => setContextMenu(null)}\n contextMenuItems={contextMenuItems}\n />\n )}\n\n {/* LIVE badge */}\n {state.isLive && (\n <div\n style={{\n position: \"absolute\",\n top: 12,\n left: 12,\n backgroundColor: \"#e53935\",\n color: \"#fff\",\n fontSize: 11,\n fontWeight: 700,\n letterSpacing: \"0.08em\",\n padding: \"2px 8px\",\n borderRadius: 3,\n pointerEvents: \"none\",\n }}\n >\n LIVE\n </div>\n )}\n\n {/* Buffering spinner */}\n {state.isBuffering && !state.error && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 12,\n color: \"#fff\",\n pointerEvents: \"none\",\n }}\n data-test=\"buffering-indicator\"\n >\n <div\n style={{\n width: 48,\n height: 48,\n border: \"4px solid rgba(255,255,255,0.25)\",\n borderTop: \"4px solid #fff\",\n borderRadius: \"50%\",\n animation: \"rvp-spin 0.8s linear infinite\",\n }}\n />\n </div>\n )}\n\n {/* Error overlay */}\n {state.error && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.85)\",\n color: \"#fff\",\n padding: 24,\n }}\n data-test=\"error-overlay\"\n >\n <div style={{ textAlign: \"center\", maxWidth: 400 }}>\n <div style={{ fontSize: 36, marginBottom: 12 }}>⚠</div>\n <h3 style={{ margin: \"0 0 8px\", fontSize: 18 }}>\n {state.error.code === \"MEDIA_ERR_SRC_NOT_SUPPORTED\"\n ? \"Unsupported Format\"\n : state.error.code.startsWith(\"HLS\")\n ? \"Stream Error\"\n : \"Playback Error\"}\n </h3>\n <p style={{ margin: 0, fontSize: 13, opacity: 0.75 }}>\n {state.error.message}\n </p>\n </div>\n </div>\n )}\n </div>\n );\n },\n);\n\nVideoPlayer.displayName = \"VideoPlayer\";\n\nexport default VideoPlayer;\n","/**\n * Format seconds → MM:SS or HH:MM:SS\n */\nexport function formatTime(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"0:00\";\n\n const total = Math.floor(seconds);\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = total % 60;\n\n if (h > 0) {\n return `${h}:${String(m).padStart(2, \"0\")}:${String(s).padStart(2, \"0\")}`;\n }\n return `${m}:${String(s).padStart(2, \"0\")}`;\n}\n\n/**\n * Detect an HLS stream URL regardless of query-string parameters.\n */\nexport function isHLSUrl(url: string): boolean {\n try {\n const pathname = new URL(url, \"https://x\").pathname.toLowerCase();\n return (\n pathname.endsWith(\".m3u8\") ||\n /\\/hls\\//i.test(url) ||\n /\\/stream\\.m3u8/i.test(url)\n );\n } catch {\n return url.toLowerCase().includes(\".m3u8\");\n }\n}\n\n/**\n * Return the MIME type for a given video URL.\n */\nexport function getMimeType(url: string): string {\n if (isHLSUrl(url)) return \"application/x-mpegURL\";\n\n const lower = url.toLowerCase().split(\"?\")[0];\n if (lower.endsWith(\".mp4\")) return \"video/mp4\";\n if (lower.endsWith(\".webm\")) return \"video/webm\";\n if (lower.endsWith(\".ogv\") || lower.endsWith(\".ogg\")) return \"video/ogg\";\n if (lower.endsWith(\".mov\")) return \"video/quicktime\";\n\n return \"video/mp4\";\n}\n","import HLS, { type HlsConfig, Events } from \"hls.js\";\nimport type { HLSQualityLevel, PlayerError } from \"./types\";\n\nconst MAX_NETWORK_RETRIES = 3;\n\n/**\n * Initialize an HLS.js instance with sensible production defaults.\n * Returns null when HLS.js is not supported (caller should fall back to native).\n */\nexport function initializeHLS(\n video: HTMLVideoElement,\n hlsUrl: string,\n config?: Partial<HlsConfig>,\n): HLS | null {\n if (!HLS.isSupported()) {\n return null;\n }\n\n const hls = new HLS({\n autoStartLoad: true,\n startLevel: -1, // start with auto ABR\n capLevelOnFPSDrop: true,\n capLevelToPlayerSize: true,\n enableWorker: true,\n\n // ABR tuning\n abrEwmaFastLive: 3,\n abrEwmaSlowLive: 9,\n abrEwmaFastVoD: 3,\n abrEwmaSlowVoD: 9,\n abrBandWidthFactor: 0.95,\n\n // Buffer tuning\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000, // 60 MB\n\n // Low-latency live\n liveBackBufferLength: 30,\n liveSyncDurationCount: 3,\n\n ...config,\n });\n\n hls.attachMedia(video);\n hls.loadSource(hlsUrl);\n\n return hls;\n}\n\n/**\n * Map HLS.js level objects to our own quality-level shape.\n */\nexport function buildQualityLevels(levels: HLS[\"levels\"]): HLSQualityLevel[] {\n return levels.map((l, i) => ({\n id: i,\n height: l.height ?? 0,\n width: l.width ?? 0,\n bitrate: l.bitrate ?? 0,\n name: l.height ? `${l.height}p` : `Level ${i + 1}`,\n }));\n}\n\n/**\n * Attach a robust error-recovery handler to an HLS instance.\n * Returns the retry-count object so callers can inspect / reset it.\n */\nexport function attachHLSErrorHandler(\n hls: HLS,\n onFatalError: (err: PlayerError) => void,\n): { retries: number } {\n const state = { retries: 0 };\n\n hls.on(Events.ERROR, (_, data) => {\n if (!data.fatal) {\n // Non-fatal: log and let HLS.js auto-recover\n console.warn(\"[hls] non-fatal error:\", data.type, data.details);\n return;\n }\n\n switch (data.type) {\n case HLS.ErrorTypes.NETWORK_ERROR:\n if (state.retries < MAX_NETWORK_RETRIES) {\n state.retries += 1;\n console.warn(\n `[hls] network error – retry ${state.retries}/${MAX_NETWORK_RETRIES}`,\n );\n // Exponential back-off before retrying\n setTimeout(() => hls.startLoad(), 1000 * state.retries);\n } else {\n console.error(\"[hls] fatal network error after retries:\", data);\n onFatalError({\n code: \"HLS_NETWORK_ERROR\",\n message: \"Failed to load video stream after multiple retries.\",\n details: data.details,\n });\n }\n break;\n\n case HLS.ErrorTypes.MEDIA_ERROR:\n console.warn(\"[hls] media error – attempting recovery\");\n hls.recoverMediaError();\n break;\n\n default:\n console.error(\"[hls] unrecoverable fatal error:\", data);\n hls.destroy();\n onFatalError({\n code: \"HLS_FATAL_ERROR\",\n message: \"An unrecoverable HLS error occurred.\",\n details: data.details,\n });\n }\n });\n\n return state;\n}\n\n/** Safely destroy an HLS instance */\nexport function destroyHLS(hls: HLS | null): void {\n hls?.destroy();\n}\n","\"use client\";\n\nimport { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport HLS, { Events } from \"hls.js\";\nimport type {\n PlayerState,\n VideoPlayerRef,\n PlaybackRate,\n HLSQualityLevel,\n VideoError,\n VideoErrorCode,\n} from \"../lib/types\";\nimport type { HlsConfig } from \"hls.js\";\nimport { isHLSUrl } from \"../lib/format\";\nimport { buildQualityLevels } from \"../lib/hls\";\n\ninterface UseVideoPlayerOptions {\n autoplay?: boolean;\n muted?: boolean;\n loop?: boolean;\n playbackRates?: PlaybackRate[];\n enableHLS?: boolean;\n hlsConfig?: Partial<HlsConfig>;\n defaultAudioMode?: boolean;\n /** Kbps — HLS only. 0 = disabled. @default 300 */\n audioBandwidthThreshold?: number;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onError?: (error: VideoError) => void;\n onTimeUpdate?: (currentTime: number) => void;\n onDurationChange?: (duration: number) => void;\n onBuffering?: (isBuffering: boolean) => void;\n onTheaterModeChange?: (isTheater: boolean) => void;\n onAudioModeChange?: (isAudio: boolean) => void;\n}\n\nconst DEFAULT_STATE: PlayerState = {\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n volume: 1,\n isMuted: false,\n playbackRate: 1,\n isFullscreen: false,\n isPictureInPicture: false,\n isTheaterMode: false,\n isAudioMode: false,\n isBuffering: false,\n bufferedRanges: [],\n error: null,\n isLive: false,\n qualityLevels: [],\n currentQualityLevel: -1,\n};\n\nexport function useVideoPlayer(\n videoRef: React.RefObject<HTMLVideoElement | null>,\n src: string,\n options: UseVideoPlayerOptions = {},\n) {\n const hlsRef = useRef<HLS | null>(null);\n const fullscreenContainerRef = useRef<HTMLElement | null>(null);\n const lastVolumeRef = useRef<number>(1);\n const networkRetriesRef = useRef<number>(0);\n\n // ── Stable refs so effects never need options/state in their dep arrays ──────\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const [state, setState] = useState<PlayerState>({\n ...DEFAULT_STATE,\n isMuted: options.muted ?? false,\n volume: options.muted ? 0 : 1,\n isAudioMode: options.defaultAudioMode ?? false,\n });\n\n const stateRef = useRef(state);\n stateRef.current = state;\n\n // ── Audio mode / bandwidth detection ─────────────────────────────────────\n /** Rolling window of the last 5 HLS bandwidth samples (Kbps). */\n const bwSamplesRef = useRef<number[]>([]);\n /** True when the current audio-mode switch was triggered automatically. */\n const autoSwitchedRef = useRef<boolean>(false);\n /** While true, auto-detection is suppressed (user just manually toggled). */\n const manualCooldownActiveRef = useRef<boolean>(false);\n const manualCooldownTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n // ─── Source / HLS initialisation ────────────────────────────────────────────\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n networkRetriesRef.current = 0;\n\n // Reset bandwidth samples and cooldown for the new source\n bwSamplesRef.current = [];\n autoSwitchedRef.current = false;\n manualCooldownActiveRef.current = false;\n if (manualCooldownTimerRef.current) {\n clearTimeout(manualCooldownTimerRef.current);\n manualCooldownTimerRef.current = null;\n }\n\n setState((prev) => ({\n ...prev,\n currentTime: 0,\n duration: 0,\n error: null,\n isBuffering: false,\n isLive: false,\n qualityLevels: [],\n currentQualityLevel: -1,\n isAudioMode: optionsRef.current.defaultAudioMode ?? false,\n }));\n\n if (!src) return;\n\n const opts = optionsRef.current;\n\n if (opts.enableHLS !== false && isHLSUrl(src)) {\n if (video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n // Native HLS (Safari) – no HLS.js instance needed\n video.src = src;\n video.load();\n if (opts.autoplay) video.play().catch(() => {});\n } else if (HLS.isSupported()) {\n const hls = new HLS({\n autoStartLoad: true,\n startLevel: -1,\n capLevelToPlayerSize: true,\n capLevelOnFPSDrop: true,\n enableWorker: true,\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n liveBackBufferLength: 30,\n liveSyncDurationCount: 3,\n ...opts.hlsConfig,\n });\n\n hls.attachMedia(video);\n hls.loadSource(src);\n\n hls.on(Events.MANIFEST_PARSED, (_, data) => {\n const levels: HLSQualityLevel[] = buildQualityLevels(data.levels);\n setState((prev) => ({\n ...prev,\n qualityLevels: levels,\n currentQualityLevel: -1,\n }));\n if (optionsRef.current.autoplay) video.play().catch(() => {});\n });\n\n hls.on(Events.LEVEL_SWITCHED, (_, data) => {\n setState((prev) => ({ ...prev, currentQualityLevel: data.level }));\n });\n\n hls.on(Events.FRAG_LOADED, () => {\n const threshold = optionsRef.current.audioBandwidthThreshold ?? 300;\n if (!threshold) return; // 0 = disabled\n if (manualCooldownActiveRef.current) return;\n\n const bwKbps = hls.bandwidthEstimate / 1000; // hls.js EWM estimate\n if (bwKbps <= 0) return;\n\n const samples = bwSamplesRef.current;\n samples.push(bwKbps);\n if (samples.length > 5) samples.shift();\n if (samples.length < 3) return; // wait for enough data\n\n const avg = samples.reduce((s, v) => s + v, 0) / samples.length;\n\n setState((prev) => {\n if (!prev.isAudioMode && avg < threshold) {\n autoSwitchedRef.current = true;\n optionsRef.current.onAudioModeChange?.(true);\n return { ...prev, isAudioMode: true };\n }\n // Switch back only if we were the one who auto-switched\n if (prev.isAudioMode && autoSwitchedRef.current && avg > threshold * 1.5) {\n autoSwitchedRef.current = false;\n optionsRef.current.onAudioModeChange?.(false);\n return { ...prev, isAudioMode: false };\n }\n return prev;\n });\n });\n\n const MAX_RETRIES = 3;\n hls.on(Events.ERROR, (_, data) => {\n if (!data.fatal) {\n console.warn(\"[hls] non-fatal:\", data.details);\n return;\n }\n switch (data.type) {\n case HLS.ErrorTypes.NETWORK_ERROR:\n if (networkRetriesRef.current < MAX_RETRIES) {\n networkRetriesRef.current += 1;\n const delay = 1000 * networkRetriesRef.current;\n console.warn(\n `[hls] network error – retry ${networkRetriesRef.current}/${MAX_RETRIES} in ${delay}ms`,\n );\n // Guard against retry firing after this HLS instance was replaced/destroyed\n setTimeout(() => {\n if (hlsRef.current === hls) hls.startLoad();\n }, delay);\n } else {\n const err: VideoError = {\n code: \"HLS_NETWORK_ERROR\",\n message: \"Failed to load stream after multiple retries.\",\n };\n setState((prev) => ({ ...prev, error: err }));\n optionsRef.current.onError?.(err);\n }\n break;\n case HLS.ErrorTypes.MEDIA_ERROR:\n console.warn(\"[hls] media error – recovering\");\n hls.recoverMediaError();\n break;\n default: {\n hls.destroy();\n hlsRef.current = null;\n const fatalErr: VideoError = {\n code: \"HLS_FATAL_ERROR\",\n message: \"An unrecoverable HLS error occurred.\",\n };\n setState((prev) => ({ ...prev, error: fatalErr }));\n optionsRef.current.onError?.(fatalErr);\n break;\n }\n }\n });\n\n hlsRef.current = hls;\n }\n } else {\n // Regular video (mp4, webm, etc.)\n video.src = src;\n video.load();\n if (opts.autoplay) video.play().catch(() => {});\n }\n\n return () => {\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n if (manualCooldownTimerRef.current) {\n clearTimeout(manualCooldownTimerRef.current);\n manualCooldownTimerRef.current = null;\n }\n };\n }, [src, videoRef]);\n\n // ─── Video element event listeners ──────────────────────────────────────────\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n if (optionsRef.current.muted) video.muted = true;\n if (optionsRef.current.loop) video.loop = true;\n\n const handlePlay = () => {\n setState((prev) => ({ ...prev, isPlaying: true }));\n optionsRef.current.onPlay?.();\n };\n const handlePause = () => {\n setState((prev) => ({ ...prev, isPlaying: false }));\n optionsRef.current.onPause?.();\n };\n const handleEnded = () => {\n setState((prev) => ({ ...prev, isPlaying: false }));\n optionsRef.current.onEnded?.();\n };\n const handleTimeUpdate = () => {\n // currentTime is NOT stored in React state — ProgressBar and TimeDisplay\n // subscribe to the video element directly, eliminating re-renders on every tick.\n optionsRef.current.onTimeUpdate?.(video.currentTime);\n };\n const handleDurationChange = () => {\n const dur = video.duration;\n const live = !Number.isFinite(dur);\n setState((prev) => ({ ...prev, duration: live ? 0 : dur, isLive: live }));\n if (!live) optionsRef.current.onDurationChange?.(dur);\n };\n const handleVolumeChange = () => {\n const vol = video.volume;\n if (vol > 0 && !video.muted) lastVolumeRef.current = vol;\n setState((prev) => ({\n ...prev,\n volume: vol,\n isMuted: video.muted || vol === 0,\n }));\n };\n const handleRateChange = () => {\n setState((prev) => ({ ...prev, playbackRate: video.playbackRate }));\n };\n const handleError = () => {\n const e = video.error;\n if (!e) return;\n const codeMap: Partial<Record<number, VideoErrorCode>> = {\n 1: \"MEDIA_ERR_ABORTED\",\n 2: \"MEDIA_ERR_NETWORK\",\n 3: \"MEDIA_ERR_DECODE\",\n 4: \"MEDIA_ERR_SRC_NOT_SUPPORTED\",\n };\n const err: VideoError = {\n code: codeMap[e.code] ?? \"UNKNOWN\",\n message: e.message || \"Unknown media error\",\n };\n setState((prev) => ({ ...prev, error: err }));\n optionsRef.current.onError?.(err);\n };\n const handleWaiting = () => {\n setState((prev) => ({ ...prev, isBuffering: true }));\n optionsRef.current.onBuffering?.(true);\n };\n const handleCanPlay = () => {\n setState((prev) => ({ ...prev, isBuffering: false }));\n optionsRef.current.onBuffering?.(false);\n };\n const handlePlaying = () =>\n setState((prev) => ({ ...prev, isBuffering: false }));\n const handleFullscreenChange = () => {\n const fs = !!(\n document.fullscreenElement || (document as any).webkitFullscreenElement\n );\n setState((prev) => ({ ...prev, isFullscreen: fs }));\n };\n const handlePiPChange = () => {\n setState((prev) => ({\n ...prev,\n isPictureInPicture: document.pictureInPictureElement === video,\n }));\n };\n\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n video.addEventListener(\"timeupdate\", handleTimeUpdate);\n video.addEventListener(\"durationchange\", handleDurationChange);\n video.addEventListener(\"volumechange\", handleVolumeChange);\n video.addEventListener(\"ratechange\", handleRateChange);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"playing\", handlePlaying);\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n document.addEventListener(\"webkitfullscreenchange\", handleFullscreenChange);\n video.addEventListener(\"enterpictureinpicture\", handlePiPChange);\n video.addEventListener(\"leavepictureinpicture\", handlePiPChange);\n\n return () => {\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n video.removeEventListener(\"timeupdate\", handleTimeUpdate);\n video.removeEventListener(\"durationchange\", handleDurationChange);\n video.removeEventListener(\"volumechange\", handleVolumeChange);\n video.removeEventListener(\"ratechange\", handleRateChange);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"playing\", handlePlaying);\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n document.removeEventListener(\n \"webkitfullscreenchange\",\n handleFullscreenChange,\n );\n video.removeEventListener(\"enterpictureinpicture\", handlePiPChange);\n video.removeEventListener(\"leavepictureinpicture\", handlePiPChange);\n };\n }, [videoRef]); // stable – options accessed via optionsRef\n\n // ─── Control methods (all stable via useCallback with empty or minimal deps) ─\n const play = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n try {\n await video.play();\n } catch (err: unknown) {\n if (err instanceof Error && err.name !== \"AbortError\")\n console.error(\"[player] play() failed:\", err);\n }\n }, [videoRef]);\n\n const pause = useCallback(() => {\n videoRef.current?.pause();\n }, [videoRef]);\n\n const seek = useCallback(\n (time: number) => {\n const video = videoRef.current;\n if (!video) return;\n video.currentTime = Math.max(0, Math.min(time, video.duration || time));\n },\n [videoRef],\n );\n\n const setVolume = useCallback(\n (volume: number) => {\n const video = videoRef.current;\n if (!video) return;\n const v = Math.max(0, Math.min(volume, 1));\n if (v > 0) lastVolumeRef.current = v;\n video.volume = v;\n video.muted = v === 0;\n },\n [videoRef],\n );\n\n const toggleMute = useCallback(() => {\n const video = videoRef.current;\n if (!video) return;\n if (video.muted || video.volume === 0) {\n const restore = lastVolumeRef.current > 0 ? lastVolumeRef.current : 1;\n video.volume = restore;\n video.muted = false;\n } else {\n lastVolumeRef.current = video.volume;\n video.muted = true;\n }\n }, [videoRef]);\n\n const setPlaybackRate = useCallback(\n (rate: PlaybackRate) => {\n const video = videoRef.current;\n if (video) video.playbackRate = rate;\n },\n [videoRef],\n );\n\n const setQualityLevel = useCallback((level: number) => {\n const hls = hlsRef.current;\n if (!hls) return;\n hls.currentLevel = level;\n setState((prev) => ({ ...prev, currentQualityLevel: level }));\n }, []);\n\n const seekToLive = useCallback(() => {\n const hls = hlsRef.current;\n const video = videoRef.current;\n if (!hls || !video) return;\n const livePos = hls.liveSyncPosition;\n if (livePos != null && Number.isFinite(livePos))\n video.currentTime = livePos;\n }, [videoRef]);\n\n const toggleFullscreen = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n const container = fullscreenContainerRef.current ?? video.parentElement;\n if (!container) return;\n try {\n if (\n !document.fullscreenElement &&\n !(document as any).webkitFullscreenElement\n ) {\n if (container.requestFullscreen) await container.requestFullscreen();\n else (container as any).webkitRequestFullscreen?.();\n } else {\n if (document.exitFullscreen) await document.exitFullscreen();\n else (document as any).webkitExitFullscreen?.();\n }\n } catch (err) {\n console.error(\"[player] fullscreen toggle failed:\", err);\n }\n }, [videoRef]);\n\n const togglePictureInPicture = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n try {\n if (document.pictureInPictureElement)\n await document.exitPictureInPicture();\n else await video.requestPictureInPicture();\n } catch (err) {\n console.error(\"[player] PiP toggle failed:\", err);\n }\n }, [videoRef]);\n\n const toggleTheaterMode = useCallback(() => {\n const next = !stateRef.current.isTheaterMode;\n setState((prev) => ({ ...prev, isTheaterMode: next }));\n optionsRef.current.onTheaterModeChange?.(next);\n }, []);\n\n const toggleAudioMode = useCallback(() => {\n // Clear any running cooldown\n if (manualCooldownTimerRef.current) clearTimeout(manualCooldownTimerRef.current);\n\n // Mark as a manual override — suppress auto-detection for 60 s\n autoSwitchedRef.current = false;\n manualCooldownActiveRef.current = true;\n manualCooldownTimerRef.current = setTimeout(() => {\n manualCooldownActiveRef.current = false;\n // Clear samples so auto-detection starts fresh after cooldown\n bwSamplesRef.current = [];\n }, 60_000);\n\n const next = !stateRef.current.isAudioMode;\n setState((prev) => ({ ...prev, isAudioMode: next }));\n optionsRef.current.onAudioModeChange?.(next);\n }, []);\n\n const getState = useCallback((): PlayerState => {\n const video = videoRef.current;\n const currentTime = video?.currentTime ?? 0;\n const bufferedRanges: import(\"../lib/types\").BufferedRange[] = [];\n if (video) {\n for (let i = 0; i < video.buffered.length; i++) {\n bufferedRanges.push({ start: video.buffered.start(i), end: video.buffered.end(i) });\n }\n }\n return { ...stateRef.current, currentTime, bufferedRanges };\n }, [videoRef]);\n\n const getVideoElement = useCallback(\n (): HTMLVideoElement | null => videoRef.current ?? null,\n [videoRef],\n );\n\n const ref = useMemo<VideoPlayerRef>(\n () => ({\n play,\n pause,\n seek,\n setVolume,\n toggleMute,\n setPlaybackRate,\n setQualityLevel,\n seekToLive,\n toggleFullscreen,\n togglePictureInPicture,\n toggleTheaterMode,\n toggleAudioMode,\n getState,\n getVideoElement,\n }),\n [\n play,\n pause,\n seek,\n setVolume,\n toggleMute,\n setPlaybackRate,\n setQualityLevel,\n seekToLive,\n toggleFullscreen,\n togglePictureInPicture,\n toggleTheaterMode,\n toggleAudioMode,\n getState,\n getVideoElement,\n ],\n );\n\n return { state, ref, hlsRef, fullscreenContainerRef };\n}\n","import {\n PlayButton,\n PauseButton,\n FullscreenButton,\n PiPButton,\n TheaterButton,\n} from \"./control-buttons\";\nimport VolumeControl from \"./volume-control\";\nimport ProgressBar from \"./progress-bar\";\nimport SettingsMenu from \"./settings-menu\";\nimport TimeDisplay from \"./time-display\";\n\nexport type {\n PlayButtonProps,\n PauseButtonProps,\n FullscreenButtonProps,\n PiPButtonProps,\n TheaterButtonProps,\n} from \"./control-buttons\";\n\nexport type { VolumeControlProps } from \"./volume-control\";\nexport type { ProgressBarProps } from \"./progress-bar\";\nexport type { SettingsMenuProps } from \"./settings-menu\";\nexport type { TimeDisplayProps } from \"./time-display\";\n\nexport {\n PlayButton,\n PauseButton,\n FullscreenButton,\n PiPButton,\n TheaterButton,\n} from \"./control-buttons\";\n\nexport { default as VolumeControl } from \"./volume-control\";\nexport { default as ProgressBar } from \"./progress-bar\";\nexport { default as SettingsMenu } from \"./settings-menu\";\nexport { default as TimeDisplay } from \"./time-display\";\n\nexport const ControlElements = {\n PlayButton,\n PauseButton,\n FullscreenButton,\n PiPButton,\n TheaterButton,\n VolumeControl,\n ProgressBar,\n SettingsMenu,\n TimeDisplay,\n};\n","\"use client\";\n\nimport { memo } from \"react\";\n\nexport interface PlayButtonProps { onClick: () => void; }\nexport interface PauseButtonProps { onClick: () => void; }\nexport interface FullscreenButtonProps { onClick: () => void; isFullscreen?: boolean; }\nexport interface PiPButtonProps { onClick: () => void; isPiP?: boolean; }\n\nexport const PlayButton = memo<PlayButtonProps>(({ onClick }) => (\n <button onClick={onClick} className=\"controlButton\" aria-label=\"Play\" title=\"Play (Space)\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n </button>\n));\nPlayButton.displayName = \"PlayButton\";\n\nexport const PauseButton = memo<PauseButtonProps>(({ onClick }) => (\n <button onClick={onClick} className=\"controlButton\" aria-label=\"Pause\" title=\"Pause (Space)\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\" />\n </svg>\n </button>\n));\nPauseButton.displayName = \"PauseButton\";\n\nexport const FullscreenButton = memo<FullscreenButtonProps>(({ onClick, isFullscreen = false }) => (\n <button\n onClick={onClick}\n className=\"controlButton\"\n aria-label={isFullscreen ? \"Exit Fullscreen\" : \"Fullscreen\"}\n title={isFullscreen ? \"Exit Fullscreen (F)\" : \"Fullscreen (F)\"}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n {isFullscreen ? (\n <path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\" />\n ) : (\n <path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\" />\n )}\n </svg>\n </button>\n));\nFullscreenButton.displayName = \"FullscreenButton\";\n\nexport const PiPButton = memo<PiPButtonProps>(({ onClick, isPiP = false }) => (\n <button\n onClick={onClick}\n className=\"controlButton\"\n aria-label={isPiP ? \"Exit Picture-in-Picture\" : \"Picture-in-Picture\"}\n title={isPiP ? \"Exit Picture-in-Picture (P)\" : \"Picture-in-Picture (P)\"}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V5h18v14.02z\" />\n </svg>\n </button>\n));\nPiPButton.displayName = \"PiPButton\";\n\nexport interface TheaterButtonProps { onClick: () => void; isTheater?: boolean; }\n\nexport const TheaterButton = memo<TheaterButtonProps>(({ onClick, isTheater = false }) => (\n <button\n onClick={onClick}\n className=\"controlButton\"\n aria-label={isTheater ? \"Exit Theater Mode\" : \"Theater Mode\"}\n title={isTheater ? \"Exit Theater Mode (T)\" : \"Theater Mode (T)\"}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n {isTheater ? (\n /* Exit theater: narrower inner rectangle — signals \"shrink back\" */\n <path d=\"M19 7H5c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zm0 8H5V9h14v6z\" />\n ) : (\n /* Enter theater: full-width rectangle — signals \"expand wide\" */\n <path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z\" />\n )}\n </svg>\n </button>\n));\nTheaterButton.displayName = \"TheaterButton\";\n\nexport default { PlayButton, PauseButton, FullscreenButton, PiPButton, TheaterButton };\n","\"use client\";\n\nimport { memo, useState, useMemo } from \"react\";\n\nexport interface VolumeControlProps {\n volume: number;\n isMuted: boolean;\n onVolumeChange: (volume: number) => void;\n onToggleMute: () => void;\n}\n\n\nconst VolumeControl = memo<VolumeControlProps>(({\n volume,\n isMuted,\n onVolumeChange,\n onToggleMute,\n}) => {\n const [showSlider, setShowSlider] = useState(false);\n const displayVolume = isMuted ? 0 : volume;\n const percentage = displayVolume * 100;\n\n const sliderBackground = useMemo(\n () =>\n `linear-gradient(to right, #60a5fa 0%, #60a5fa ${percentage}%, rgba(255,255,255,0.3) ${percentage}%, rgba(255,255,255,0.3) 100%)`,\n [percentage],\n );\n\n return (\n <div\n className=\"volumeContainer\"\n onMouseEnter={() => setShowSlider(true)}\n onMouseLeave={() => setShowSlider(false)}\n >\n <button\n onClick={onToggleMute}\n className=\"controlButton\"\n aria-label={isMuted ? \"Unmute\" : \"Mute\"}\n title={isMuted ? \"Unmute (M)\" : \"Mute (M)\"}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n {displayVolume === 0 ? (\n <path d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C23.16 14.42 24 13.3 24 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\" />\n ) : displayVolume < 0.5 ? (\n <path d=\"M7 9v6h4l5 5V4l-5 5H7z\" />\n ) : (\n <path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\" />\n )}\n </svg>\n </button>\n\n {showSlider && (\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n value={percentage}\n onChange={(e) => onVolumeChange(Number(e.target.value) / 100)}\n className=\"volumeSlider\"\n style={{ background: sliderBackground }}\n aria-label=\"Volume\"\n aria-valuenow={Math.round(percentage)}\n />\n )}\n </div>\n );\n});\n\nVolumeControl.displayName = \"VolumeControl\";\nexport default VolumeControl;\n","export interface ThumbnailCue {\n start: number;\n end: number;\n /** Absolute URL to the sprite image */\n url: string;\n /** Pixel offset from the left of the sprite sheet */\n x: number;\n /** Pixel offset from the top of the sprite sheet */\n y: number;\n /** Width of a single thumbnail cell */\n w: number;\n /** Height of a single thumbnail cell */\n h: number;\n}\n\nfunction parseVttTime(s: string): number {\n const parts = s.trim().split(\":\");\n if (parts.length === 3) {\n return +parts[0] * 3600 + +parts[1] * 60 + parseFloat(parts[2]);\n }\n return +parts[0] * 60 + parseFloat(parts[1]);\n}\n\nfunction resolveUrl(base: string, url: string): string {\n if (/^https?:\\/\\//i.test(url)) return url;\n try {\n return new URL(url, base).href;\n } catch {\n return url;\n }\n}\n\n/**\n * Parse a WebVTT thumbnail track into an array of cues.\n *\n * Supports the standard sprite-sheet format:\n * 00:00:00.000 --> 00:00:05.000\n * https://cdn.example.com/thumbs/s0.jpg#xywh=0,0,160,90\n *\n * @param text Raw VTT file text\n * @param baseUrl VTT file URL — used to resolve relative image paths\n */\nexport function parseThumbnailVtt(text: string, baseUrl = \"\"): ThumbnailCue[] {\n const cues: ThumbnailCue[] = [];\n const lines = text.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i].trim();\n\n if (line.includes(\"-->\")) {\n const arrow = line.indexOf(\"-->\");\n const start = parseVttTime(line.slice(0, arrow));\n const end = parseVttTime(line.slice(arrow + 3));\n i++;\n\n // Skip blank lines between timing and URL\n while (i < lines.length && !lines[i].trim()) i++;\n\n if (i < lines.length) {\n const urlLine = lines[i].trim();\n const hashIdx = urlLine.lastIndexOf(\"#xywh=\");\n let url = urlLine;\n let x = 0, y = 0, w = 160, h = 90;\n\n if (hashIdx !== -1) {\n url = urlLine.slice(0, hashIdx);\n const coords = urlLine.slice(hashIdx + 6).split(\",\").map(Number);\n x = coords[0] ?? 0;\n y = coords[1] ?? 0;\n w = coords[2] ?? 160;\n h = coords[3] ?? 90;\n }\n\n cues.push({ start, end, url: resolveUrl(baseUrl, url), x, y, w, h });\n }\n }\n\n i++;\n }\n\n return cues;\n}\n\n/**\n * Binary-search for the cue that covers `time` (seconds).\n * Returns null if no cue covers that timestamp.\n */\nexport function findThumbnailCue(\n cues: ThumbnailCue[],\n time: number,\n): ThumbnailCue | null {\n if (!cues.length) return null;\n\n let lo = 0;\n let hi = cues.length - 1;\n\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (cues[mid].end <= time) lo = mid + 1;\n else if (cues[mid].start > time) hi = mid - 1;\n else return cues[mid];\n }\n\n return null;\n}\n","\"use client\";\n\nimport React, { memo, useRef, useState, useEffect, useCallback, useMemo } from \"react\";\nimport type { VideoPlayerRef, BufferedRange } from \"../../lib/types\";\nimport { formatTime } from \"../../lib/format\";\nimport { parseThumbnailVtt, findThumbnailCue } from \"../../lib/vtt\";\nimport type { ThumbnailCue } from \"../../lib/vtt\";\n\nexport interface ProgressBarProps {\n videoRef: React.RefObject<HTMLVideoElement | null>;\n playerRef: VideoPlayerRef;\n enablePreview?: boolean;\n thumbnailVtt?: string;\n}\n\nconst ProgressBar: React.FC<ProgressBarProps> = memo(({\n videoRef,\n playerRef,\n enablePreview = true,\n thumbnailVtt,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const progressFilledRef = useRef<HTMLDivElement>(null);\n const scrubHandleRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n const hoverTimeTextRef = useRef<HTMLDivElement>(null);\n const hoverIndicatorRef = useRef<HTMLDivElement>(null);\n const thumbRef = useRef<HTMLDivElement>(null);\n\n // Only bufferedRanges stays in React state — it changes on the `progress`\n // event which fires infrequently (every few seconds during buffering).\n const [bufferedRanges, setBufferedRanges] = useState<BufferedRange[]>([]);\n\n // Imperative state — no React re-renders for any of these\n const isDraggingRef = useRef(false);\n const hoverPosRef = useRef(0);\n const hoverTimeRef = useRef(0);\n const lastCueRef = useRef<ThumbnailCue | null>(null);\n\n // VTT thumbnail cues — loaded once, looked up synchronously\n const thumbnailCuesRef = useRef<ThumbnailCue[]>([]);\n\n /**\n * Rect cache — getBoundingClientRect() is expensive; invalidate on resize only.\n */\n const rectCacheRef = useRef<DOMRect | null>(null);\n\n useEffect(() => {\n const invalidate = () => { rectCacheRef.current = null; };\n window.addEventListener(\"resize\", invalidate, { passive: true });\n return () => window.removeEventListener(\"resize\", invalidate);\n }, []);\n\n const getRect = useCallback((): DOMRect | null => {\n if (!rectCacheRef.current && containerRef.current) {\n rectCacheRef.current = containerRef.current.getBoundingClientRect();\n }\n return rectCacheRef.current;\n }, []);\n\n // ─── Load VTT thumbnail cues ────────────────────────────────────────────\n useEffect(() => {\n if (!thumbnailVtt) {\n thumbnailCuesRef.current = [];\n return;\n }\n let cancelled = false;\n fetch(thumbnailVtt)\n .then(r => r.text())\n .then(text => {\n if (!cancelled) thumbnailCuesRef.current = parseThumbnailVtt(text, thumbnailVtt);\n })\n .catch(() => {\n if (!cancelled) thumbnailCuesRef.current = [];\n });\n return () => { cancelled = true; };\n }, [thumbnailVtt]);\n\n // ─── Subscribe to timeupdate / durationchange ────────────────────────────\n // Updates the progress fill and scrub handle position imperatively —\n // zero React re-renders during playback.\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const updateProgress = () => {\n const dur = isFinite(video.duration) ? video.duration : 0;\n const ct = video.currentTime;\n const pct = dur > 0 ? (ct / dur) * 100 : 0;\n\n if (progressFilledRef.current)\n progressFilledRef.current.style.width = `${pct}%`;\n if (scrubHandleRef.current)\n scrubHandleRef.current.style.left = `${pct}%`;\n if (containerRef.current) {\n containerRef.current.setAttribute(\"aria-valuenow\", String(Math.round(ct)));\n containerRef.current.setAttribute(\"aria-valuemax\", String(Math.round(dur)));\n containerRef.current.setAttribute(\"aria-valuetext\", formatTime(ct));\n }\n };\n\n video.addEventListener(\"timeupdate\", updateProgress);\n video.addEventListener(\"durationchange\", updateProgress);\n video.addEventListener(\"seeked\", updateProgress);\n updateProgress(); // sync on mount\n\n return () => {\n video.removeEventListener(\"timeupdate\", updateProgress);\n video.removeEventListener(\"durationchange\", updateProgress);\n video.removeEventListener(\"seeked\", updateProgress);\n };\n }, [videoRef]);\n\n // ─── Subscribe to progress (buffered ranges) ────────────────────────────\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const updateBuffered = () => {\n const ranges: BufferedRange[] = [];\n for (let i = 0; i < video.buffered.length; i++) {\n ranges.push({ start: video.buffered.start(i), end: video.buffered.end(i) });\n }\n setBufferedRanges(ranges);\n };\n\n video.addEventListener(\"progress\", updateBuffered);\n return () => video.removeEventListener(\"progress\", updateBuffered);\n }, [videoRef]);\n\n // ─── Non-React drag-state helpers ────────────────────────────────────────\n const startDragging = useCallback(() => {\n isDraggingRef.current = true;\n scrubHandleRef.current?.classList.add(\"dragging\");\n }, []);\n\n const stopDragging = useCallback(() => {\n isDraggingRef.current = false;\n scrubHandleRef.current?.classList.remove(\"dragging\");\n }, []);\n\n // ─── Show / hide preview tooltip ─────────────────────────────────────────\n const showTooltip = useCallback(() => {\n if (!enablePreview) return;\n rectCacheRef.current = null; // invalidate rect on re-entry\n if (tooltipRef.current) tooltipRef.current.style.display = \"block\";\n if (hoverIndicatorRef.current) hoverIndicatorRef.current.style.display = \"block\";\n }, [enablePreview]);\n\n const hideTooltip = useCallback(() => {\n if (tooltipRef.current) tooltipRef.current.style.display = \"none\";\n if (hoverIndicatorRef.current) hoverIndicatorRef.current.style.display = \"none\";\n }, []);\n\n // ─── Apply thumbnail from VTT cue ────────────────────────────────────────\n const applyThumbnail = useCallback((time: number) => {\n if (!thumbRef.current || !thumbnailCuesRef.current.length) return;\n const cue = findThumbnailCue(thumbnailCuesRef.current, time);\n lastCueRef.current = cue;\n if (!cue) return;\n const el = thumbRef.current;\n el.style.backgroundImage = `url(${cue.url})`;\n el.style.backgroundPosition = `-${cue.x}px -${cue.y}px`;\n el.style.width = `${cue.w}px`;\n el.style.height = `${cue.h}px`;\n }, []);\n\n // ─── Geometry helpers ────────────────────────────────────────────────────\n const getTimeFromClientX = useCallback((clientX: number): number => {\n const rect = getRect();\n const dur = videoRef.current?.duration;\n if (!rect || rect.width === 0 || !dur || !isFinite(dur)) return 0;\n const pos = Math.max(0, Math.min(clientX - rect.left, rect.width));\n return (pos / rect.width) * dur;\n }, [getRect, videoRef]);\n\n const getPxFromClientX = useCallback((clientX: number): number => {\n const rect = getRect();\n if (!rect) return 0;\n return Math.max(0, Math.min(clientX - rect.left, rect.width));\n }, [getRect]);\n\n // ─── Keyboard handler ────────────────────────────────────────────────────\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {\n const video = videoRef.current;\n if (!video) return;\n const ct = video.currentTime;\n const dur = isFinite(video.duration) ? video.duration : 0;\n\n switch (e.key) {\n case \"ArrowLeft\":\n case \"ArrowRight\": {\n e.preventDefault();\n e.nativeEvent.stopImmediatePropagation();\n const step = e.shiftKey ? 10 : 5;\n playerRef.seek(e.key === \"ArrowLeft\"\n ? Math.max(0, ct - step)\n : Math.min(dur, ct + step));\n break;\n }\n case \"Home\":\n e.preventDefault();\n e.nativeEvent.stopImmediatePropagation();\n playerRef.seek(0);\n break;\n case \"End\":\n if (dur > 0) {\n e.preventDefault();\n e.nativeEvent.stopImmediatePropagation();\n playerRef.seek(dur);\n }\n break;\n }\n }, [videoRef, playerRef]);\n\n // ─── Mouse handlers ───────────────────────────────────────────────────────\n const handleMouseMove = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n const time = getTimeFromClientX(e.clientX);\n const px = getPxFromClientX(e.clientX);\n\n hoverPosRef.current = px;\n hoverTimeRef.current = time;\n\n if (hoverIndicatorRef.current) hoverIndicatorRef.current.style.left = `${px}px`;\n if (hoverTimeTextRef.current) hoverTimeTextRef.current.textContent = formatTime(time);\n\n\n applyThumbnail(time);\n\n if (tooltipRef.current) {\n const tooltipWidth = tooltipRef.current.offsetWidth;\n const containerWidth = getRect()?.width ?? 0;\n const halfWidth = tooltipWidth / 2;\n const clampedLeft = Math.max(halfWidth, Math.min(px, containerWidth - halfWidth));\n tooltipRef.current.style.left = `${clampedLeft}px`;\n }\n\n if (isDraggingRef.current) playerRef.seek(time);\n }, [playerRef, applyThumbnail, getTimeFromClientX, getPxFromClientX, getRect]);\n\n const handleMouseLeave = useCallback(() => {\n hideTooltip();\n stopDragging();\n }, [hideTooltip, stopDragging]);\n\n const handleMouseDown = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n startDragging();\n playerRef.seek(getTimeFromClientX(e.clientX));\n }, [startDragging, getTimeFromClientX, playerRef]);\n\n\n const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n if (!isDraggingRef.current) playerRef.seek(getTimeFromClientX(e.clientX));\n }, [getTimeFromClientX, playerRef]);\n\n // ─── Touch handlers ───────────────────────────────────────────────────────\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const onTouchMove = (e: TouchEvent) => {\n if (isDraggingRef.current) e.preventDefault();\n };\n container.addEventListener(\"touchmove\", onTouchMove, { passive: false });\n return () => container.removeEventListener(\"touchmove\", onTouchMove);\n }, []);\n\n const handleTouchStart = useCallback((e: React.TouchEvent<HTMLDivElement>) => {\n rectCacheRef.current = null;\n startDragging();\n playerRef.seek(getTimeFromClientX(e.touches[0].clientX));\n }, [startDragging, getTimeFromClientX, playerRef]);\n\n const handleTouchMove = useCallback((e: React.TouchEvent<HTMLDivElement>) => {\n if (!isDraggingRef.current) return;\n playerRef.seek(getTimeFromClientX(e.touches[0].clientX));\n }, [getTimeFromClientX, playerRef]);\n\n\n // Release drag if pointer leaves the window\n useEffect(() => {\n const up = () => stopDragging();\n window.addEventListener(\"mouseup\", up);\n return () => window.removeEventListener(\"mouseup\", up);\n }, [stopDragging]);\n\n // ─── Buffered segments (memoised — only re-renders on progress event) ────\n const bufferedSegments = useMemo(() => {\n const video = videoRef.current;\n const dur = video && isFinite(video.duration) ? video.duration : 0;\n if (dur <= 0 || !bufferedRanges.length) return null;\n return bufferedRanges.map((range, i) => {\n const start = (range.start / dur) * 100;\n const width = ((range.end - range.start) / dur) * 100;\n return (\n <div\n key={i}\n className=\"bufferedSegment\"\n style={{ left: `${start}%`, width: `${width}%` }}\n />\n );\n });\n }, [bufferedRanges, videoRef]);\n\n return (\n <div\n ref={containerRef}\n className=\"progressContainer\"\n onMouseMove={handleMouseMove}\n onMouseEnter={showTooltip}\n onMouseLeave={handleMouseLeave}\n onMouseDown={handleMouseDown}\n onMouseUp={stopDragging}\n onClick={handleClick}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={stopDragging}\n onKeyDown={handleKeyDown}\n role=\"slider\"\n aria-label=\"Video progress\"\n aria-valuemin={0}\n aria-valuemax={0}\n aria-valuenow={0}\n aria-valuetext=\"0:00\"\n tabIndex={0}\n >\n {/* Tooltip — always in DOM when preview enabled; shown/hidden imperatively */}\n {enablePreview && (\n <div\n ref={tooltipRef}\n className=\"previewTooltip\"\n style={{ left: 0, display: \"none\" }}\n aria-hidden=\"true\"\n >\n {thumbnailVtt && (\n <div ref={thumbRef} className=\"previewThumbnail\" />\n )}\n <div ref={hoverTimeTextRef} className=\"previewTime\" />\n </div>\n )}\n\n {/* Track */}\n <div className=\"progressBackground\">\n {bufferedSegments}\n <div ref={progressFilledRef} className=\"progressFilled\" style={{ width: \"0%\" }} />\n {enablePreview && (\n <div\n ref={hoverIndicatorRef}\n className=\"hoverIndicator\"\n style={{ left: 0, display: \"none\" }}\n aria-hidden=\"true\"\n />\n )}\n </div>\n\n {/* Scrub handle — class toggled imperatively for dragging state */}\n <div\n ref={scrubHandleRef}\n className=\"scrubHandle\"\n style={{ left: \"0%\" }}\n aria-hidden=\"true\"\n />\n </div>\n );\n});\n\nProgressBar.displayName = \"ProgressBar\";\n\nexport default ProgressBar;\n","\"use client\";\n\nimport { memo, useState, useRef, useEffect, useMemo } from \"react\";\nimport type { PlaybackRate, HLSQualityLevel } from \"../../lib/types\";\n\nexport interface SettingsMenuProps {\n currentRate: number;\n playbackRates: PlaybackRate[];\n onRateChange: (rate: PlaybackRate) => void;\n qualityLevels?: HLSQualityLevel[];\n currentQualityLevel?: number;\n onQualityChange?: (level: number) => void;\n}\n\ntype Tab = \"speed\" | \"quality\";\n\nconst SettingsMenu = memo<SettingsMenuProps>(({\n currentRate,\n playbackRates,\n onRateChange,\n qualityLevels = [],\n currentQualityLevel = -1,\n onQualityChange,\n}) => {\n const [open, setOpen] = useState(false);\n const [tab, setTab] = useState<Tab>(\"speed\");\n const containerRef = useRef<HTMLDivElement>(null);\n\n const hasQuality = qualityLevels.length > 0 && !!onQualityChange;\n\n // Close when clicking outside\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n if (open) document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n /**\n * Sort once when qualityLevels changes\n */\n const sortedLevels = useMemo(\n () => [...qualityLevels].sort((a, b) => b.bitrate - a.bitrate),\n [qualityLevels],\n );\n\n const currentQualityName = useMemo(() => {\n if (currentQualityLevel === -1) return \"Auto\";\n return qualityLevels.find((l) => l.id === currentQualityLevel)?.name ?? \"Auto\";\n }, [qualityLevels, currentQualityLevel]);\n\n return (\n <div ref={containerRef} className=\"settingsContainer\">\n <button\n onClick={() => setOpen((o) => !o)}\n className=\"controlButton\"\n aria-label=\"Settings\"\n title=\"Settings\"\n aria-expanded={open}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19.14 12.94c.04-.3.06-.61.06-.94s-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.49.49 0 0 0-.59-.22l-2.39.96a7.02 7.02 0 0 0-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54a6.88 6.88 0 0 0-1.61.94l-2.39-.96a.488.488 0 0 0-.59.22L2.74 8.87a.48.48 0 0 0 .12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54a6.88 6.88 0 0 0 1.61-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32a.47.47 0 0 0-.12-.61l-2.01-1.58zM12 15.6A3.6 3.6 0 0 1 8.4 12 3.6 3.6 0 0 1 12 8.4a3.6 3.6 0 0 1 3.6 3.6 3.6 3.6 0 0 1-3.6 3.6z\" />\n </svg>\n </button>\n\n {open && (\n <div className=\"settingsDropdown\" role=\"menu\">\n {hasQuality && (\n <div className=\"settingsTabs\">\n <button\n className={`settingsTab${tab === \"speed\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"speed\")}\n >\n Speed\n </button>\n <button\n className={`settingsTab${tab === \"quality\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"quality\")}\n >\n Quality\n </button>\n </div>\n )}\n\n {(!hasQuality || tab === \"speed\") && (\n <div>\n {!hasQuality && <div className=\"settingsPanelLabel\">Playback Speed</div>}\n {playbackRates.map((rate) => (\n <button\n key={rate}\n onClick={() => { onRateChange(rate); setOpen(false); }}\n className={`settingsOption${currentRate === rate ? \" active\" : \"\"}`}\n role=\"menuitemradio\"\n aria-checked={currentRate === rate}\n >\n {rate === 1 ? \"Normal\" : `${rate}×`}\n </button>\n ))}\n </div>\n )}\n\n {hasQuality && tab === \"quality\" && (\n <div>\n <button\n onClick={() => { onQualityChange!(-1); setOpen(false); }}\n className={`settingsOption${currentQualityLevel === -1 ? \" active\" : \"\"}`}\n role=\"menuitemradio\"\n aria-checked={currentQualityLevel === -1}\n >\n Auto {currentQualityLevel === -1 && currentQualityName !== \"Auto\"\n ? `(${currentQualityName})`\n : \"\"}\n </button>\n {sortedLevels.map((level) => (\n <button\n key={level.id}\n onClick={() => { onQualityChange!(level.id); setOpen(false); }}\n className={`settingsOption${currentQualityLevel === level.id ? \" active\" : \"\"}`}\n role=\"menuitemradio\"\n aria-checked={currentQualityLevel === level.id}\n >\n {level.name}\n {level.bitrate > 0 && (\n <span className=\"settingsOptionBadge\">\n {Math.round(level.bitrate / 1000)} kbps\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n );\n});\n\nSettingsMenu.displayName = \"SettingsMenu\";\nexport default SettingsMenu;\n","\"use client\";\n\nimport { memo, useRef, useEffect } from \"react\";\nimport { formatTime } from \"../../lib/format\";\n\nexport interface TimeDisplayProps {\n videoRef: React.RefObject<HTMLVideoElement | null>;\n isLive?: boolean;\n}\n\n/**\n * TimeDisplay subscribes directly to the video element's timeupdate and\n * durationchange events, updating the DOM via refs. It never re-renders\n * during playback — only when isLive changes (once per source change).\n */\nconst TimeDisplay = memo<TimeDisplayProps>(({ videoRef, isLive = false }) => {\n const currentRef = useRef<HTMLSpanElement>(null);\n const durationRef = useRef<HTMLSpanElement>(null);\n\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const updateTime = () => {\n if (currentRef.current)\n currentRef.current.textContent = formatTime(video.currentTime);\n };\n\n const updateDuration = () => {\n if (durationRef.current) {\n const dur = isFinite(video.duration) ? video.duration : 0;\n durationRef.current.textContent = ` / ${formatTime(dur)}`;\n }\n };\n\n video.addEventListener(\"timeupdate\", updateTime);\n video.addEventListener(\"durationchange\", updateDuration);\n video.addEventListener(\"seeked\", updateTime);\n\n updateTime();\n updateDuration();\n\n return () => {\n video.removeEventListener(\"timeupdate\", updateTime);\n video.removeEventListener(\"durationchange\", updateDuration);\n video.removeEventListener(\"seeked\", updateTime);\n };\n }, [videoRef, isLive]);\n\n if (isLive) {\n return (\n <span className=\"timeDisplay\" style={{ opacity: 0.7 }}>\n <span ref={currentRef}>0:00</span>\n </span>\n );\n }\n\n return (\n <span className=\"timeDisplay\">\n <span ref={currentRef}>0:00</span>\n <span ref={durationRef} style={{ opacity: 0.6 }}> / 0:00</span>\n </span>\n );\n});\n\nTimeDisplay.displayName = \"TimeDisplay\";\nexport default TimeDisplay;\n","\"use client\";\n\nimport React, { memo, useEffect, useRef, useState, useCallback, type ReactNode } from \"react\";\nimport type {\n PlaybackRate,\n VideoPlayerRef,\n HLSQualityLevel,\n ControlBarItem,\n} from \"../lib/types\";\nimport { ControlElements } from \"./control-elements\";\n\ninterface ControlsProps {\n videoRef: React.RefObject<HTMLVideoElement | null>;\n playerRef: VideoPlayerRef;\n playerContainerRef: React.RefObject<HTMLElement | null>;\n playbackRates: PlaybackRate[];\n enablePreview: boolean;\n thumbnailVtt?: string;\n isPlaying: boolean;\n volume: number;\n isMuted: boolean;\n playbackRate: number;\n isFullscreen: boolean;\n isPictureInPicture: boolean;\n isTheaterMode: boolean;\n isAudioMode: boolean;\n showAudioButton: boolean;\n audioModeIcon?: ReactNode;\n videoModeIcon?: ReactNode;\n audioModeLabel?: string;\n videoModeLabel?: string;\n isLive: boolean;\n qualityLevels: HLSQualityLevel[];\n currentQualityLevel: number;\n controlBarItems?: ControlBarItem[];\n autoHideControls: boolean;\n}\n\nexport const Controls = memo<ControlsProps>(function Controls({\n videoRef,\n playerRef,\n playerContainerRef,\n playbackRates,\n enablePreview,\n thumbnailVtt,\n isPlaying,\n volume,\n isMuted,\n playbackRate,\n isFullscreen,\n isPictureInPicture,\n isTheaterMode,\n isAudioMode,\n showAudioButton,\n audioModeIcon,\n videoModeIcon,\n audioModeLabel,\n videoModeLabel,\n isLive,\n qualityLevels,\n currentQualityLevel,\n controlBarItems,\n autoHideControls,\n}) {\n const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [showControls, setShowControls] = useState(true);\n\n /**\n * Stable ref capturing the values the keyboard handler needs.\n * isPlaying/volume/isMuted/isLive come from React state (rare changes).\n * currentTime/duration are read directly from the video element so the\n * keyboard shortcuts always see fresh values without subscribing to state.\n */\n const liveRef = useRef({ isPlaying, volume, isMuted, isLive });\n liveRef.current = { isPlaying, volume, isMuted, isLive };\n\n // ─── Auto-hide controls ──────────────────────────────────────────────────\n useEffect(() => {\n // Audio mode or disabled: always show, never hide\n if (isAudioMode || !autoHideControls) {\n setShowControls(true);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n return;\n }\n // Paused: always show\n if (!isPlaying) {\n setShowControls(true);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n return;\n }\n\n // Playing + video mode: show on hover, hide on mouse leave\n const el = playerContainerRef.current;\n if (!el) return;\n\n const handleShow = () => {\n setShowControls(true);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n // Also start a 3s inactivity timer while mouse is inside\n hideTimeoutRef.current = setTimeout(() => setShowControls(false), 3000);\n };\n\n const handleHide = () => {\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n setShowControls(false);\n };\n\n el.addEventListener(\"mousemove\", handleShow);\n el.addEventListener(\"mouseenter\", handleShow);\n el.addEventListener(\"mouseleave\", handleHide);\n el.addEventListener(\"touchstart\", handleShow, { passive: true });\n\n // Start hidden while playing\n setShowControls(false);\n\n return () => {\n el.removeEventListener(\"mousemove\", handleShow);\n el.removeEventListener(\"mouseenter\", handleShow);\n el.removeEventListener(\"mouseleave\", handleHide);\n el.removeEventListener(\"touchstart\", handleShow);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n };\n }, [isPlaying, isAudioMode, autoHideControls, playerContainerRef]);\n\n // ─── Keyboard shortcuts ─────────────────────────────────────────────────\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!playerContainerRef.current?.contains(document.activeElement)) return;\n\n const target = e.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\" || target.isContentEditable) return;\n\n const { isPlaying: playing, volume: vol, isLive: live } = liveRef.current;\n // Read time/duration directly from the video element — always fresh\n const ct = videoRef.current?.currentTime ?? 0;\n const dur = videoRef.current?.duration ?? 0;\n\n switch (e.code) {\n case \"Space\": case \"KeyK\":\n e.preventDefault();\n playing ? playerRef.pause() : playerRef.play();\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n playerRef.seek(Math.max(0, ct - 5));\n break;\n case \"ArrowRight\":\n e.preventDefault();\n playerRef.seek(Math.min(dur || Infinity, ct + 5));\n break;\n case \"ArrowUp\":\n e.preventDefault();\n playerRef.setVolume(Math.min(1, vol + 0.1));\n break;\n case \"ArrowDown\":\n e.preventDefault();\n playerRef.setVolume(Math.max(0, vol - 0.1));\n break;\n case \"KeyM\":\n e.preventDefault();\n playerRef.toggleMute();\n break;\n case \"KeyF\":\n e.preventDefault();\n playerRef.toggleFullscreen();\n break;\n case \"KeyP\":\n e.preventDefault();\n playerRef.togglePictureInPicture();\n break;\n case \"KeyT\":\n e.preventDefault();\n playerRef.toggleTheaterMode();\n break;\n case \"KeyL\":\n e.preventDefault();\n if (live) playerRef.seekToLive();\n break;\n case \"Digit0\": case \"Digit1\": case \"Digit2\": case \"Digit3\": case \"Digit4\":\n case \"Digit5\": case \"Digit6\": case \"Digit7\": case \"Digit8\": case \"Digit9\": {\n e.preventDefault();\n const pct = Number(e.code.replace(\"Digit\", \"\")) * 10;\n playerRef.seek((dur / 100) * pct);\n break;\n }\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [playerRef, playerContainerRef, videoRef]);\n\n // ─── Stable callbacks for child components ───────────────────────────────\n const handlePlay = useCallback(() => playerRef.play(), [playerRef]);\n const handlePause = useCallback(() => playerRef.pause(), [playerRef]);\n const handleVolumeChange = useCallback((v: number) => playerRef.setVolume(v), [playerRef]);\n const handleToggleMute = useCallback(() => playerRef.toggleMute(), [playerRef]);\n const handleRateChange = useCallback((r: PlaybackRate) => playerRef.setPlaybackRate(r), [playerRef]);\n const handleQualityChange = useCallback((l: number) => playerRef.setQualityLevel(l), [playerRef]);\n const handlePiP = useCallback(() => playerRef.togglePictureInPicture(), [playerRef]);\n const handleTheaterToggle = useCallback(() => playerRef.toggleTheaterMode(), [playerRef]);\n const handleAudioToggle = useCallback(() => playerRef.toggleAudioMode(), [playerRef]);\n const handleFullscreen = useCallback(() => playerRef.toggleFullscreen(), [playerRef]);\n const handleSeekToLive = useCallback(() => playerRef.seekToLive(), [playerRef]);\n\n return (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-end\",\n opacity: showControls ? 1 : 0,\n transition: \"opacity 0.3s\",\n pointerEvents: \"none\",\n zIndex: 2, // must be above the audio overlay (z-index: 1)\n }}\n >\n <div\n style={{\n background: \"linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 60%, transparent 100%)\",\n padding: \"48px 12px 12px\",\n pointerEvents: showControls ? \"auto\" : \"none\",\n }}\n role=\"region\"\n aria-label=\"Video player controls\"\n >\n {/* Progress bar */}\n <ControlElements.ProgressBar\n videoRef={videoRef}\n playerRef={playerRef}\n enablePreview={enablePreview}\n thumbnailVtt={thumbnailVtt}\n />\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 4, marginTop: 4 }}>\n {isPlaying ? (\n <ControlElements.PauseButton onClick={handlePause} />\n ) : (\n <ControlElements.PlayButton onClick={handlePlay} />\n )}\n\n <ControlElements.VolumeControl\n volume={volume}\n isMuted={isMuted}\n onVolumeChange={handleVolumeChange}\n onToggleMute={handleToggleMute}\n />\n\n {/* TimeDisplay — self-subscribes to timeupdate/durationchange on videoRef */}\n <ControlElements.TimeDisplay\n videoRef={videoRef}\n isLive={isLive}\n />\n\n <div style={{ flex: 1 }} />\n\n {isLive && (\n <GoLiveButton onClick={handleSeekToLive} />\n )}\n\n {/* Audio mode toggle — before Settings so it's easy to find */}\n {showAudioButton && (\n <AudioModeButton\n onClick={handleAudioToggle}\n isAudioMode={isAudioMode}\n audioModeIcon={audioModeIcon}\n videoModeIcon={videoModeIcon}\n audioModeLabel={audioModeLabel}\n videoModeLabel={videoModeLabel}\n />\n )}\n\n {/* Settings — speed always shown; quality tab appears for HLS streams */}\n <ControlElements.SettingsMenu\n currentRate={playbackRate}\n playbackRates={playbackRates}\n onRateChange={handleRateChange}\n qualityLevels={qualityLevels}\n currentQualityLevel={currentQualityLevel}\n onQualityChange={handleQualityChange}\n />\n\n {/* Custom control bar items injected by the consumer */}\n {controlBarItems?.map((item) => (\n <button\n key={item.key}\n className=\"controlButton\"\n aria-label={item.label}\n title={item.title ?? item.label}\n onClick={item.onClick}\n >\n {item.icon}\n </button>\n ))}\n <ControlElements.PiPButton onClick={handlePiP} isPiP={isPictureInPicture} />\n <ControlElements.TheaterButton onClick={handleTheaterToggle} isTheater={isTheaterMode} />\n <ControlElements.FullscreenButton onClick={handleFullscreen} isFullscreen={isFullscreen} />\n </div>\n </div>\n </div>\n );\n});\nControls.displayName = \"Controls\";\n\nconst AudioModeButton = memo(({\n onClick,\n isAudioMode,\n audioModeIcon,\n videoModeIcon,\n audioModeLabel,\n videoModeLabel,\n}: {\n onClick: () => void;\n isAudioMode: boolean;\n audioModeIcon?: ReactNode;\n videoModeIcon?: ReactNode;\n audioModeLabel?: string;\n videoModeLabel?: string;\n}) => {\n const label = isAudioMode ? (videoModeLabel ?? \"Video\") : (audioModeLabel ?? \"Audio\");\n const icon = isAudioMode\n ? (videoModeIcon ?? (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z\" />\n </svg>\n ))\n : (audioModeIcon ?? (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3a9 9 0 0 0-9 9v7c0 1.1.9 2 2 2h1a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1H4v-1a8 8 0 0 1 16 0v1h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h1a3 3 0 0 0 3-3v-4c0-4.97-4.03-9-9-9z\" />\n </svg>\n ));\n\n return (\n <button\n onClick={onClick}\n className=\"rvp-audio-toggle-btn\"\n aria-label={label}\n title={label}\n aria-pressed={isAudioMode}\n >\n {icon}\n {label}\n </button>\n );\n});\nAudioModeButton.displayName = \"AudioModeButton\";\n\nconst GoLiveButton = memo(({ onClick }: { onClick: () => void }) => (\n <button\n onClick={onClick}\n style={{\n background: \"none\",\n border: \"1px solid rgba(255,255,255,0.6)\",\n color: \"#fff\",\n borderRadius: 3,\n padding: \"2px 8px\",\n fontSize: 11,\n fontWeight: 700,\n cursor: \"pointer\",\n letterSpacing: \"0.06em\",\n }}\n title=\"Go to live (L)\"\n >\n GO LIVE\n </button>\n));\nGoLiveButton.displayName = \"GoLiveButton\";\n","\"use client\";\n\nimport React, { memo, useEffect, useRef, useState, useCallback } from \"react\";\nimport type { ContextMenuItem, VideoPlayerRef } from \"../lib/types\";\n\ninterface ContextMenuProps {\n x: number;\n y: number;\n isPlaying: boolean;\n src: string;\n videoRef: React.RefObject<HTMLVideoElement | null>;\n playerRef: VideoPlayerRef;\n onClose: () => void;\n contextMenuItems?: ContextMenuItem[];\n}\n\nexport const ContextMenu = memo<ContextMenuProps>(\n ({ x, y, isPlaying, src, videoRef, playerRef, onClose, contextMenuItems }) => {\n const menuRef = useRef<HTMLDivElement>(null);\n const [isLooping, setIsLooping] = useState(\n () => videoRef.current?.loop ?? false,\n );\n\n // Clamp position so menu never overflows the viewport\n const adjustedX = Math.min(x, window.innerWidth - 220);\n const adjustedY = Math.min(y, window.innerHeight - 290);\n\n useEffect(() => {\n const handleMouseDown = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node))\n onClose();\n };\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n const handleScroll = () => onClose();\n\n document.addEventListener(\"mousedown\", handleMouseDown);\n document.addEventListener(\"keydown\", handleKeyDown);\n window.addEventListener(\"scroll\", handleScroll, true);\n return () => {\n document.removeEventListener(\"mousedown\", handleMouseDown);\n document.removeEventListener(\"keydown\", handleKeyDown);\n window.removeEventListener(\"scroll\", handleScroll, true);\n };\n }, [onClose]);\n\n const handlePlayPause = useCallback(() => {\n isPlaying ? playerRef.pause() : playerRef.play();\n onClose();\n }, [isPlaying, playerRef, onClose]);\n\n const handleToggleLoop = useCallback(() => {\n const video = videoRef.current;\n if (!video) return;\n const next = !isLooping;\n video.loop = next;\n setIsLooping(next);\n }, [videoRef, isLooping]);\n\n const handleCopyUrl = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(src);\n } catch {}\n onClose();\n }, [src, onClose]);\n\n const handleCopyTimestamp = useCallback(async () => {\n const time = Math.floor(videoRef.current?.currentTime ?? 0);\n try {\n await navigator.clipboard.writeText(`${src}?t=${time}`);\n } catch {}\n onClose();\n }, [src, videoRef, onClose]);\n\n const handlePiP = useCallback(() => {\n playerRef.togglePictureInPicture();\n onClose();\n }, [playerRef, onClose]);\n\n return (\n <div\n ref={menuRef}\n className=\"contextMenu\"\n style={{ left: adjustedX, top: adjustedY }}\n >\n <button className=\"contextMenuItem\" onClick={handlePlayPause}>\n {isPlaying ? \"Pause\" : \"Play\"}\n </button>\n <button className=\"contextMenuItem\" onClick={handleToggleLoop}>\n <span>Loop</span>\n {isLooping && <span className=\"contextMenuCheck\">✓</span>}\n </button>\n\n <div className=\"contextMenuDivider\" />\n\n <button className=\"contextMenuItem\" onClick={handleCopyUrl}>\n Copy video URL\n </button>\n <button className=\"contextMenuItem\" onClick={handleCopyTimestamp}>\n Copy video URL at current time\n </button>\n\n <div className=\"contextMenuDivider\" />\n\n <button className=\"contextMenuItem\" onClick={handlePiP}>\n Picture-in-Picture\n </button>\n\n {contextMenuItems && contextMenuItems.length > 0 && (\n <>\n <div className=\"contextMenuDivider\" />\n {contextMenuItems.map((item, i) => (\n <button\n key={i}\n className=\"contextMenuItem\"\n onClick={() => { item.onClick(); onClose(); }}\n >\n {item.label}\n </button>\n ))}\n </>\n )}\n </div>\n );\n },\n);\n\nContextMenu.displayName = \"ContextMenu\";\n","\"use client\";\n\nimport React, { memo, type ReactNode } from \"react\";\n\ninterface AudioModeOverlayProps {\n poster?: string;\n logo?: string | ReactNode;\n audioModeFallback?: ReactNode;\n isBuffering?: boolean;\n onOverlayClick?: () => void;\n}\n\nexport const AudioModeOverlay = memo<AudioModeOverlayProps>(function AudioModeOverlay({\n poster,\n logo,\n audioModeFallback,\n isBuffering = false,\n onOverlayClick,\n}) {\n const spinner = isBuffering ? (\n <div className=\"rvp-audio-buffering-overlay\" aria-label=\"Buffering\">\n <div className=\"rvp-audio-spinner\" />\n </div>\n ) : null;\n\n const artwork = (() => {\n if (poster) {\n return (\n <div className=\"rvp-audio-artwork-container\">\n <img src={poster} alt=\"Artwork\" className=\"rvp-audio-artwork\" draggable={false} />\n </div>\n );\n }\n if (audioModeFallback) {\n return <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"center\" }}>{audioModeFallback}</div>;\n }\n if (logo) {\n return typeof logo === \"string\"\n ? <img src={logo} alt=\"Logo\" className=\"rvp-audio-logo\" draggable={false} />\n : <div className=\"rvp-audio-logo-node\">{logo as ReactNode}</div>;\n }\n return null;\n })();\n\n return (\n <div className=\"rvp-audio-overlay\" onClick={onOverlayClick} data-test=\"audio-mode-overlay\">\n {artwork}\n <span className=\"rvp-audio-label\">Audio Mode</span>\n {spinner}\n </div>\n );\n});\n\nAudioModeOverlay.displayName = \"AudioModeOverlay\";\n","import type { ReactNode } from \"react\";\nimport type { HlsConfig } from \"hls.js\";\n\n/**\n * Preset bandwidth thresholds (Kbps) for automatic audio mode switching.\n *\n * | Preset | Kbps | Typical connection |\n * |-----------|------|-------------------------|\n * | EXTREME | 100 | 2G / Edge |\n * | POOR | 300 | Slow 3G ← **default** |\n * | FAIR | 700 | 3G |\n * | GOOD | 1500 | 4G / Wi-Fi |\n *\n * Pass any of these (or a custom number) as `audioBandwidthThreshold`.\n * Set to `0` to disable automatic switching entirely.\n *\n * @example\n * import { AUDIO_BANDWIDTH_THRESHOLDS } from \"react-helios\";\n * <VideoPlayer audioBandwidthThreshold={AUDIO_BANDWIDTH_THRESHOLDS.FAIR} ... />\n */\nexport const AUDIO_BANDWIDTH_THRESHOLDS = {\n /** < 100 Kbps — very poor, 2G / Edge */\n EXTREME: 100,\n /** < 300 Kbps — poor, slow 3G (default) */\n POOR: 300,\n /** < 700 Kbps — fair, 3G */\n FAIR: 700,\n /** < 1500 Kbps — decent, 4G / Wi-Fi */\n GOOD: 1500,\n} as const;\n\nexport interface BufferedRange {\n start: number;\n end: number;\n}\n\nexport type VideoErrorCode =\n | \"MEDIA_ERR_ABORTED\"\n | \"MEDIA_ERR_NETWORK\"\n | \"MEDIA_ERR_DECODE\"\n | \"MEDIA_ERR_SRC_NOT_SUPPORTED\"\n | \"HLS_NETWORK_ERROR\"\n | \"HLS_FATAL_ERROR\"\n | \"UNKNOWN\";\n\nexport interface VideoError {\n code: VideoErrorCode;\n message: string;\n}\n\n/** Display name e.g. \"1080p\", \"720p\", \"Auto\" */\nexport interface HLSQualityLevel {\n id: number;\n height: number;\n width: number;\n bitrate: number;\n name: string;\n}\n\nexport interface SubtitleTrack {\n id: string;\n src: string;\n label: string;\n srclang: string;\n default?: boolean;\n}\n\nexport interface PlayerState {\n isPlaying: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n isMuted: boolean;\n playbackRate: number;\n bufferedRanges: BufferedRange[];\n isBuffering: boolean;\n error: VideoError | null;\n isFullscreen: boolean;\n isPictureInPicture: boolean;\n isTheaterMode: boolean;\n /** True when the player is in audio-only mode (video hidden, waveform shown). */\n isAudioMode: boolean;\n isLive: boolean;\n qualityLevels: HLSQualityLevel[];\n currentQualityLevel: number;\n}\n\nexport type PlaybackRate = 0.25 | 0.5 | 0.75 | 1 | 1.25 | 1.5 | 1.75 | 2;\n\nexport interface VideoPlayerRef {\n play: () => Promise<void>;\n pause: () => void;\n seek: (time: number) => void;\n setVolume: (volume: number) => void;\n toggleMute: () => void;\n setPlaybackRate: (rate: PlaybackRate) => void;\n setQualityLevel: (level: number) => void;\n seekToLive: () => void;\n toggleFullscreen: () => Promise<void>;\n togglePictureInPicture: () => Promise<void>;\n toggleTheaterMode: () => void;\n /** Toggle audio-only mode. Can also be triggered programmatically from outside the player. */\n toggleAudioMode: () => void;\n getState: () => PlayerState;\n getVideoElement: () => HTMLVideoElement | null;\n}\n\nexport interface ContextMenuItem {\n label: string;\n onClick: () => void;\n}\n\nexport interface ControlBarItem {\n key: string;\n icon: ReactNode;\n label: string;\n title?: string;\n onClick: () => void;\n}\n\nexport interface VideoPlayerOptions {\n // Playback\n autoplay?: boolean;\n muted?: boolean;\n loop?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n playbackRates?: PlaybackRate[];\n // HLS\n enableHLS?: boolean;\n hlsConfig?: Partial<HlsConfig>;\n // Preview\n enablePreview?: boolean;\n thumbnailVtt?: string;\n // UI\n autoHideControls?: boolean;\n // Subtitles\n subtitles?: SubtitleTrack[];\n crossOrigin?: \"anonymous\" | \"use-credentials\";\n // Audio mode\n logo?: string | ReactNode;\n audioSrc?: string;\n showAudioButton?: boolean;\n audioModeIcon?: ReactNode;\n videoModeIcon?: ReactNode;\n /**\n * Custom content shown in audio mode when no `poster` is provided.\n * Replaces the default animated-gradient + waveform fallback entirely.\n * The `logo` prop is still rendered on top of this if also provided.\n */\n audioModeFallback?: ReactNode;\n /** Label shown next to the icon when in video mode (click → switches to audio). Default: \"Audio\" */\n audioModeLabel?: string;\n /** Label shown next to the icon when in audio mode (click → switches to video). Default: \"Video\" */\n videoModeLabel?: string;\n defaultAudioMode?: boolean;\n audioBandwidthThreshold?: number;\n // Callbacks\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onError?: (error: VideoError) => void;\n onTimeUpdate?: (time: number) => void;\n onDurationChange?: (duration: number) => void;\n onBuffering?: (isBuffering: boolean) => void;\n onTheaterModeChange?: (isTheater: boolean) => void;\n onAudioModeChange?: (isAudio: boolean) => void;\n // Custom\n contextMenuItems?: ContextMenuItem[];\n controlBarItems?: ControlBarItem[];\n}\n\nexport interface VideoPlayerProps {\n src: string;\n poster?: string;\n className?: string;\n controls?: boolean;\n options?: VideoPlayerOptions;\n}\n\n"]}
1
+ {"version":3,"sources":["../src/components/VideoPlayer.tsx","../src/lib/format.ts","../src/lib/hls.ts","../src/hooks/useVideoPlayer.ts","../src/components/control-elements/index.ts","../src/components/control-elements/control-buttons.tsx","../src/components/control-elements/volume-control.tsx","../src/lib/vtt.ts","../src/components/control-elements/progress-bar.tsx","../src/components/control-elements/settings-menu.tsx","../src/components/control-elements/time-display.tsx","../src/components/Controls.tsx","../src/components/ContextMenu.tsx","../src/components/AudioModeOverlay.tsx","../src/lib/types.ts"],"names":["formatTime","seconds","total","h","m","isHLSUrl","url","getMimeType","lower","buildQualityLevels","levels","l","i","DEFAULT_STATE","useVideoPlayer","videoRef","src","options","hlsRef","useRef","fullscreenContainerRef","lastVolumeRef","networkRetriesRef","optionsRef","state","setState","useState","stateRef","bwSamplesRef","fragCountRef","autoSwitchedRef","manualCooldownActiveRef","manualCooldownTimerRef","recoveryTimerRef","recoveryProbePendingRef","getActiveMedia","useCallback","opts","useEffect","video","prev","HLS","hls","Events","_","data","switchLevel","fragData","loadMs","fragBwKbps","threshold","scheduleRecoveryProbe","samples","avg","s","v","interval","MAX_RETRIES","delay","err","fatalErr","audio","handlePlay","handlePause","handleEnded","handleTimeUpdate","handleDurationChange","dur","live","handleVolumeChange","vol","handleRateChange","handleError","e","handleWaiting","handleCanPlay","handlePlaying","handleFullscreenChange","fs","handlePiPChange","pos","wasPlaying","play","media","pause","seek","time","setVolume","volume","toggleMute","restore","setPlaybackRate","rate","setQualityLevel","level","seekToLive","livePos","toggleFullscreen","container","togglePictureInPicture","toggleTheaterMode","next","toggleAudioMode","getState","currentTime","bufferedRanges","getVideoElement","ref","useMemo","control_elements_exports","__export","ControlElements","FullscreenButton","PauseButton","PiPButton","PlayButton","progress_bar_default","settings_menu_default","TheaterButton","time_display_default","volume_control_default","memo","onClick","jsx","isFullscreen","isPiP","isTheater","VolumeControl","isMuted","onVolumeChange","onToggleMute","showSlider","setShowSlider","displayVolume","percentage","sliderBackground","jsxs","parseVttTime","parts","resolveUrl","base","parseThumbnailVtt","text","baseUrl","cues","lines","line","arrow","start","end","urlLine","hashIdx","x","y","w","coords","findThumbnailCue","lo","hi","mid","ProgressBar","playerRef","enablePreview","thumbnailVtt","containerRef","progressFilledRef","scrubHandleRef","tooltipRef","hoverTimeTextRef","hoverIndicatorRef","thumbRef","setBufferedRanges","isDraggingRef","hoverPosRef","hoverTimeRef","lastCueRef","thumbnailCuesRef","rectCacheRef","invalidate","getRect","cancelled","r","updateProgress","ct","pct","updateBuffered","ranges","startDragging","stopDragging","showTooltip","hideTooltip","applyThumbnail","cue","el","getTimeFromClientX","clientX","rect","getPxFromClientX","handleKeyDown","step","handleMouseMove","px","tooltipWidth","containerWidth","halfWidth","clampedLeft","handleMouseLeave","handleMouseDown","handleClick","onTouchMove","handleTouchStart","handleTouchMove","up","bufferedSegments","range","width","SettingsMenu","currentRate","playbackRates","onRateChange","qualityLevels","currentQualityLevel","onQualityChange","open","setOpen","tab","setTab","hasQuality","handler","sortedLevels","a","b","currentQualityName","o","TimeDisplay","isLive","currentRef","durationRef","updateTime","updateDuration","Controls","playerContainerRef","isPlaying","playbackRate","isPictureInPicture","isTheaterMode","isAudioMode","showAudioButton","audioModeIcon","videoModeIcon","audioModeLabel","videoModeLabel","controlBarItems","autoHideControls","hideTimeoutRef","showControls","setShowControls","liveRef","handleShow","handleHide","target","playing","handleToggleMute","handleQualityChange","handlePiP","handleTheaterToggle","handleAudioToggle","handleFullscreen","handleSeekToLive","GoLiveButton","AudioModeButton","item","label","ContextMenu","onClose","contextMenuItems","menuRef","isLooping","setIsLooping","adjustedX","adjustedY","handleScroll","handlePlayPause","handleToggleLoop","handleCopyUrl","handleCopyTimestamp","Fragment","AudioModeOverlay","poster","logo","audioModeFallback","isBuffering","onOverlayClick","VideoPlayer","forwardRef","props","forwardedRef","className","controls","autoplay","muted","loop","preload","enableHLS","hlsConfig","subtitles","crossOrigin","audioSrc","defaultAudioMode","audioBandwidthThreshold","audioModeSwitchLevel","audioModeRecoveryInterval","onPlay","onPause","onEnded","onError","onTimeUpdate","onDurationChange","onBuffering","onTheaterModeChange","onAudioModeChange","audioRef","activeMediaRef","React","contextMenu","setContextMenu","handleVideoClick","handleDoubleClick","handleContextMenu","track","VideoPlayer_default","AUDIO_BANDWIDTH_THRESHOLDS","AUDIO_SWITCH_LEVELS"],"mappings":"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","file":"index.mjs","sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useEffect, useRef, useCallback, useState } from \"react\";\nimport type { VideoPlayerProps, VideoPlayerRef } from \"../lib/types\";\nimport { useVideoPlayer } from \"../hooks/useVideoPlayer\";\nimport { Controls } from \"./Controls\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { AudioModeOverlay } from \"./AudioModeOverlay\";\n\nconst VideoPlayer = forwardRef<VideoPlayerRef, VideoPlayerProps>(\n (props, forwardedRef) => {\n const { src, poster, className, controls = true, options = {} } = props;\n\n const {\n autoplay = false,\n muted = false,\n loop = false,\n preload = \"metadata\",\n playbackRates = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],\n enableHLS = true,\n enablePreview = true,\n thumbnailVtt,\n hlsConfig,\n autoHideControls = true,\n subtitles,\n crossOrigin,\n logo,\n audioModeFallback,\n audioSrc,\n showAudioButton,\n audioModeIcon,\n videoModeIcon,\n audioModeLabel,\n videoModeLabel,\n defaultAudioMode,\n audioBandwidthThreshold,\n audioModeSwitchLevel,\n audioModeRecoveryInterval,\n onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n onDurationChange,\n onBuffering,\n onTheaterModeChange,\n onAudioModeChange,\n contextMenuItems,\n controlBarItems,\n } = options;\n\n const videoRef = useRef<HTMLVideoElement | null>(null);\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n\n const { state, ref: playerRef, fullscreenContainerRef } = useVideoPlayer(\n videoRef,\n src,\n {\n autoplay,\n muted,\n loop,\n playbackRates,\n enableHLS,\n hlsConfig,\n defaultAudioMode,\n audioBandwidthThreshold,\n audioModeSwitchLevel,\n audioModeRecoveryInterval,\n onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n onDurationChange,\n onBuffering,\n onTheaterModeChange,\n onAudioModeChange,\n audioRef,\n audioSrc,\n },\n );\n\n // Always keep activeMediaRef pointing to the playing element so Controls/ProgressBar\n // can subscribe to the right element's events without React re-renders\n const activeMediaRef = useRef<HTMLMediaElement | null>(null);\n React.useLayoutEffect(() => {\n activeMediaRef.current =\n state.isAudioMode && audioSrc && audioRef.current\n ? audioRef.current\n : videoRef.current;\n }, [state.isAudioMode, audioSrc]);\n // initialise synchronously so it's set before first paint\n if (activeMediaRef.current === null) {\n activeMediaRef.current = videoRef.current;\n }\n\n const [contextMenu, setContextMenu] = useState<{ x: number; y: number } | null>(null);\n\n useEffect(() => {\n fullscreenContainerRef.current = containerRef.current;\n }, [fullscreenContainerRef]);\n\n React.useImperativeHandle(forwardedRef, () => playerRef, [playerRef]);\n\n const handleVideoClick = useCallback(() => {\n // Focus the container so keyboard shortcuts activate for this player\n containerRef.current?.focus();\n if (state.isPlaying) playerRef.pause();\n else playerRef.play();\n }, [state.isPlaying, playerRef]);\n\n const handleDoubleClick = useCallback(() => {\n playerRef.toggleFullscreen();\n }, [playerRef]);\n\n const handleContextMenu = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n setContextMenu({ x: e.clientX, y: e.clientY });\n }, []);\n\n\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n style={{\n position: \"relative\",\n width: \"100%\",\n backgroundColor: \"#000\",\n aspectRatio: \"16 / 9\",\n userSelect: \"none\",\n outline: \"none\",\n }}\n className={className}\n data-test=\"video-player-container\"\n data-theater={state.isTheaterMode ? \"true\" : undefined}\n onContextMenu={handleContextMenu}\n >\n <video\n ref={videoRef}\n poster={poster}\n preload={preload}\n crossOrigin={crossOrigin}\n onClick={handleVideoClick}\n onDoubleClick={handleDoubleClick}\n playsInline\n style={{\n width: \"100%\",\n height: \"100%\",\n display: \"block\",\n cursor: \"pointer\",\n // Keep the element in the DOM so audio keeps playing; just hide it visually\n visibility: state.isAudioMode ? \"hidden\" : \"visible\",\n }}\n data-test=\"video-element\"\n >\n {subtitles?.map((track) => (\n <track\n key={track.id}\n kind=\"subtitles\"\n src={track.src}\n label={track.label}\n srcLang={track.srclang}\n default={track.default}\n />\n ))}\n </video>\n\n {/* Hidden audio element — owns playback in audio mode, video is paused */}\n {audioSrc && (\n <audio\n ref={audioRef}\n preload=\"none\"\n style={{ display: \"none\" }}\n aria-hidden=\"true\"\n />\n )}\n\n {/* Audio mode overlay — sits above video, below controls (DOM order) */}\n {state.isAudioMode && (\n <AudioModeOverlay\n poster={poster}\n logo={logo}\n audioModeFallback={audioModeFallback}\n isBuffering={state.isBuffering}\n onOverlayClick={handleVideoClick}\n />\n )}\n\n {controls && (\n <Controls\n videoRef={activeMediaRef}\n playerRef={playerRef}\n playerContainerRef={containerRef}\n playbackRates={playbackRates}\n enablePreview={enablePreview}\n thumbnailVtt={state.isAudioMode ? undefined : thumbnailVtt}\n isPlaying={state.isPlaying}\n volume={state.volume}\n isMuted={state.isMuted}\n playbackRate={state.playbackRate}\n isFullscreen={state.isFullscreen}\n isPictureInPicture={state.isPictureInPicture}\n isTheaterMode={state.isTheaterMode}\n isAudioMode={state.isAudioMode}\n showAudioButton={showAudioButton ?? !!audioSrc}\n audioModeIcon={audioModeIcon}\n videoModeIcon={videoModeIcon}\n audioModeLabel={audioModeLabel}\n videoModeLabel={videoModeLabel}\n isLive={state.isLive}\n qualityLevels={state.qualityLevels}\n currentQualityLevel={state.currentQualityLevel}\n controlBarItems={controlBarItems}\n autoHideControls={autoHideControls}\n />\n )}\n\n {contextMenu && (\n <ContextMenu\n x={contextMenu.x}\n y={contextMenu.y}\n isPlaying={state.isPlaying}\n src={src}\n videoRef={videoRef}\n playerRef={playerRef}\n onClose={() => setContextMenu(null)}\n contextMenuItems={contextMenuItems}\n />\n )}\n\n {/* LIVE badge */}\n {state.isLive && (\n <div\n style={{\n position: \"absolute\",\n top: 12,\n left: 12,\n backgroundColor: \"#e53935\",\n color: \"#fff\",\n fontSize: 11,\n fontWeight: 700,\n letterSpacing: \"0.08em\",\n padding: \"2px 8px\",\n borderRadius: 3,\n pointerEvents: \"none\",\n }}\n >\n LIVE\n </div>\n )}\n\n {/* Buffering spinner */}\n {state.isBuffering && !state.error && !state.isAudioMode && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 12,\n color: \"#fff\",\n pointerEvents: \"none\",\n }}\n data-test=\"buffering-indicator\"\n >\n <div\n style={{\n width: 48,\n height: 48,\n border: \"4px solid rgba(255,255,255,0.25)\",\n borderTop: \"4px solid #fff\",\n borderRadius: \"50%\",\n animation: \"rvp-spin 0.8s linear infinite\",\n }}\n />\n </div>\n )}\n\n {/* Error overlay */}\n {state.error && (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: \"rgba(0,0,0,0.85)\",\n color: \"#fff\",\n padding: 24,\n }}\n data-test=\"error-overlay\"\n >\n <div style={{ textAlign: \"center\", maxWidth: 400 }}>\n <div style={{ fontSize: 36, marginBottom: 12 }}>⚠</div>\n <h3 style={{ margin: \"0 0 8px\", fontSize: 18 }}>\n {state.error.code === \"MEDIA_ERR_SRC_NOT_SUPPORTED\"\n ? \"Unsupported Format\"\n : state.error.code.startsWith(\"HLS\")\n ? \"Stream Error\"\n : \"Playback Error\"}\n </h3>\n <p style={{ margin: 0, fontSize: 13, opacity: 0.75 }}>\n {state.error.message}\n </p>\n </div>\n </div>\n )}\n </div>\n );\n },\n);\n\nVideoPlayer.displayName = \"VideoPlayer\";\n\nexport default VideoPlayer;\n","/**\n * Format seconds → MM:SS or HH:MM:SS\n */\nexport function formatTime(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"0:00\";\n\n const total = Math.floor(seconds);\n const h = Math.floor(total / 3600);\n const m = Math.floor((total % 3600) / 60);\n const s = total % 60;\n\n if (h > 0) {\n return `${h}:${String(m).padStart(2, \"0\")}:${String(s).padStart(2, \"0\")}`;\n }\n return `${m}:${String(s).padStart(2, \"0\")}`;\n}\n\n/**\n * Detect an HLS stream URL regardless of query-string parameters.\n */\nexport function isHLSUrl(url: string): boolean {\n try {\n const pathname = new URL(url, \"https://x\").pathname.toLowerCase();\n return (\n pathname.endsWith(\".m3u8\") ||\n /\\/hls\\//i.test(url) ||\n /\\/stream\\.m3u8/i.test(url)\n );\n } catch {\n return url.toLowerCase().includes(\".m3u8\");\n }\n}\n\n/**\n * Return the MIME type for a given video URL.\n */\nexport function getMimeType(url: string): string {\n if (isHLSUrl(url)) return \"application/x-mpegURL\";\n\n const lower = url.toLowerCase().split(\"?\")[0];\n if (lower.endsWith(\".mp4\")) return \"video/mp4\";\n if (lower.endsWith(\".webm\")) return \"video/webm\";\n if (lower.endsWith(\".ogv\") || lower.endsWith(\".ogg\")) return \"video/ogg\";\n if (lower.endsWith(\".mov\")) return \"video/quicktime\";\n\n return \"video/mp4\";\n}\n","import HLS, { type HlsConfig, Events } from \"hls.js\";\nimport type { HLSQualityLevel, PlayerError } from \"./types\";\n\nconst MAX_NETWORK_RETRIES = 3;\n\n/**\n * Initialize an HLS.js instance with sensible production defaults.\n * Returns null when HLS.js is not supported (caller should fall back to native).\n */\nexport function initializeHLS(\n video: HTMLVideoElement,\n hlsUrl: string,\n config?: Partial<HlsConfig>,\n): HLS | null {\n if (!HLS.isSupported()) {\n return null;\n }\n\n const hls = new HLS({\n autoStartLoad: true,\n startLevel: -1, // start with auto ABR\n capLevelOnFPSDrop: true,\n capLevelToPlayerSize: true,\n enableWorker: true,\n\n // ABR tuning\n abrEwmaFastLive: 3,\n abrEwmaSlowLive: 9,\n abrEwmaFastVoD: 3,\n abrEwmaSlowVoD: 9,\n abrBandWidthFactor: 0.95,\n\n // Buffer tuning\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000, // 60 MB\n\n // Low-latency live\n liveBackBufferLength: 30,\n liveSyncDurationCount: 3,\n\n ...config,\n });\n\n hls.attachMedia(video);\n hls.loadSource(hlsUrl);\n\n return hls;\n}\n\n/**\n * Map HLS.js level objects to our own quality-level shape.\n */\nexport function buildQualityLevels(levels: HLS[\"levels\"]): HLSQualityLevel[] {\n return levels.map((l, i) => ({\n id: i,\n height: l.height ?? 0,\n width: l.width ?? 0,\n bitrate: l.bitrate ?? 0,\n name: l.height ? `${l.height}p` : `Level ${i + 1}`,\n }));\n}\n\n/**\n * Attach a robust error-recovery handler to an HLS instance.\n * Returns the retry-count object so callers can inspect / reset it.\n */\nexport function attachHLSErrorHandler(\n hls: HLS,\n onFatalError: (err: PlayerError) => void,\n): { retries: number } {\n const state = { retries: 0 };\n\n hls.on(Events.ERROR, (_, data) => {\n if (!data.fatal) {\n // Non-fatal: log and let HLS.js auto-recover\n console.warn(\"[hls] non-fatal error:\", data.type, data.details);\n return;\n }\n\n switch (data.type) {\n case HLS.ErrorTypes.NETWORK_ERROR:\n if (state.retries < MAX_NETWORK_RETRIES) {\n state.retries += 1;\n console.warn(\n `[hls] network error – retry ${state.retries}/${MAX_NETWORK_RETRIES}`,\n );\n // Exponential back-off before retrying\n setTimeout(() => hls.startLoad(), 1000 * state.retries);\n } else {\n console.error(\"[hls] fatal network error after retries:\", data);\n onFatalError({\n code: \"HLS_NETWORK_ERROR\",\n message: \"Failed to load video stream after multiple retries.\",\n details: data.details,\n });\n }\n break;\n\n case HLS.ErrorTypes.MEDIA_ERROR:\n console.warn(\"[hls] media error – attempting recovery\");\n hls.recoverMediaError();\n break;\n\n default:\n console.error(\"[hls] unrecoverable fatal error:\", data);\n hls.destroy();\n onFatalError({\n code: \"HLS_FATAL_ERROR\",\n message: \"An unrecoverable HLS error occurred.\",\n details: data.details,\n });\n }\n });\n\n return state;\n}\n\n/** Safely destroy an HLS instance */\nexport function destroyHLS(hls: HLS | null): void {\n hls?.destroy();\n}\n","\"use client\";\n\nimport { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport HLS, { Events } from \"hls.js\";\nimport type {\n PlayerState,\n VideoPlayerRef,\n PlaybackRate,\n HLSQualityLevel,\n VideoError,\n VideoErrorCode,\n} from \"../lib/types\";\nimport type { HlsConfig } from \"hls.js\";\nimport { isHLSUrl } from \"../lib/format\";\nimport { buildQualityLevels } from \"../lib/hls\";\n\ninterface UseVideoPlayerOptions {\n autoplay?: boolean;\n muted?: boolean;\n loop?: boolean;\n playbackRates?: PlaybackRate[];\n enableHLS?: boolean;\n hlsConfig?: Partial<HlsConfig>;\n defaultAudioMode?: boolean;\n /** Kbps — switch to audio mode below this bandwidth. 0 = disabled. @default 300 */\n audioBandwidthThreshold?: number;\n /** HLS quality level — switch to audio mode at this level or below. -1 = disabled. @default undefined */\n audioModeSwitchLevel?: number;\n /** Ms between recovery probes while auto-switched to audio mode. @default 30000 */\n audioModeRecoveryInterval?: number;\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onError?: (error: VideoError) => void;\n onTimeUpdate?: (currentTime: number) => void;\n onDurationChange?: (duration: number) => void;\n onBuffering?: (isBuffering: boolean) => void;\n onTheaterModeChange?: (isTheater: boolean) => void;\n onAudioModeChange?: (isAudio: boolean) => void;\n audioRef?: React.RefObject<HTMLAudioElement | null>;\n audioSrc?: string;\n}\n\nconst DEFAULT_STATE: PlayerState = {\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n volume: 1,\n isMuted: false,\n playbackRate: 1,\n isFullscreen: false,\n isPictureInPicture: false,\n isTheaterMode: false,\n isAudioMode: false,\n isBuffering: false,\n bufferedRanges: [],\n error: null,\n isLive: false,\n qualityLevels: [],\n currentQualityLevel: -1,\n};\n\nexport function useVideoPlayer(\n videoRef: React.RefObject<HTMLVideoElement | null>,\n src: string,\n options: UseVideoPlayerOptions = {},\n) {\n const hlsRef = useRef<HLS | null>(null);\n const fullscreenContainerRef = useRef<HTMLElement | null>(null);\n const lastVolumeRef = useRef<number>(1);\n const networkRetriesRef = useRef<number>(0);\n\n // ── Stable refs so effects never need options/state in their dep arrays ──────\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const [state, setState] = useState<PlayerState>({\n ...DEFAULT_STATE,\n isMuted: options.muted ?? false,\n volume: options.muted ? 0 : 1,\n isAudioMode: options.defaultAudioMode ?? false,\n });\n\n const stateRef = useRef(state);\n stateRef.current = state;\n\n // ── Audio mode / bandwidth detection ─────────────────────────────────────\n /** Rolling window of the last 5 HLS bandwidth samples (Kbps). */\n const bwSamplesRef = useRef<number[]>([]);\n /** Counts loaded fragments — level-based switch is suppressed until ≥ 3. */\n const fragCountRef = useRef<number>(0);\n /** True when the current audio-mode switch was triggered automatically. */\n const autoSwitchedRef = useRef<boolean>(false);\n /** While true, auto-detection is suppressed (user just manually toggled). */\n const manualCooldownActiveRef = useRef<boolean>(false);\n const manualCooldownTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n /** Timer that fires the next bandwidth recovery probe while in auto audio mode. */\n const recoveryTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n /** True while a recovery probe fragment load is in-flight. */\n const recoveryProbePendingRef = useRef<boolean>(false);\n\n /** Returns the currently-active media element (audio in audio mode, video otherwise). */\n const getActiveMedia = useCallback((): HTMLMediaElement | null => {\n const opts = optionsRef.current;\n if (stateRef.current.isAudioMode && opts.audioSrc && opts.audioRef?.current) {\n return opts.audioRef.current;\n }\n return videoRef.current;\n }, [videoRef]);\n\n // ─── Source / HLS initialisation ────────────────────────────────────────────\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n networkRetriesRef.current = 0;\n\n // Reset bandwidth samples and cooldown for the new source\n bwSamplesRef.current = [];\n fragCountRef.current = 0;\n autoSwitchedRef.current = false;\n manualCooldownActiveRef.current = false;\n if (manualCooldownTimerRef.current) {\n clearTimeout(manualCooldownTimerRef.current);\n manualCooldownTimerRef.current = null;\n }\n if (recoveryTimerRef.current) {\n clearTimeout(recoveryTimerRef.current);\n recoveryTimerRef.current = null;\n }\n recoveryProbePendingRef.current = false;\n\n setState((prev) => ({\n ...prev,\n currentTime: 0,\n duration: 0,\n error: null,\n isBuffering: false,\n isLive: false,\n qualityLevels: [],\n currentQualityLevel: -1,\n isAudioMode: optionsRef.current.defaultAudioMode ?? false,\n }));\n\n if (!src) return;\n\n const opts = optionsRef.current;\n\n if (opts.enableHLS !== false && isHLSUrl(src)) {\n if (video.canPlayType(\"application/vnd.apple.mpegurl\")) {\n // Native HLS (Safari) – no HLS.js instance needed\n video.src = src;\n video.load();\n if (opts.autoplay) video.play().catch(() => {});\n } else if (HLS.isSupported()) {\n const hls = new HLS({\n autoStartLoad: true,\n startLevel: -1,\n capLevelToPlayerSize: true,\n capLevelOnFPSDrop: true,\n enableWorker: true,\n maxBufferLength: 30,\n maxMaxBufferLength: 600,\n maxBufferSize: 60 * 1000 * 1000,\n liveBackBufferLength: 30,\n liveSyncDurationCount: 3,\n ...opts.hlsConfig,\n });\n\n hls.attachMedia(video);\n hls.loadSource(src);\n\n hls.on(Events.MANIFEST_PARSED, (_, data) => {\n const levels: HLSQualityLevel[] = buildQualityLevels(data.levels);\n setState((prev) => ({\n ...prev,\n qualityLevels: levels,\n currentQualityLevel: -1,\n }));\n if (optionsRef.current.autoplay) video.play().catch(() => {});\n });\n\n hls.on(Events.LEVEL_SWITCHED, (_, data) => {\n setState((prev) => ({ ...prev, currentQualityLevel: data.level }));\n\n // ── Level-based auto-switch ──────────────────────────────────────\n const opts = optionsRef.current;\n const switchLevel = opts.audioModeSwitchLevel;\n if (\n switchLevel === undefined ||\n switchLevel < 0 ||\n !opts.audioSrc ||\n manualCooldownActiveRef.current ||\n fragCountRef.current < 3 // ignore initial level ramp-up on page load\n ) return;\n\n setState((prev) => {\n if (!prev.isAudioMode && data.level <= switchLevel) {\n autoSwitchedRef.current = true;\n optionsRef.current.onAudioModeChange?.(true);\n return { ...prev, isAudioMode: true };\n }\n return prev;\n });\n });\n\n hls.on(Events.FRAG_LOADED, (_, fragData) => {\n const opts = optionsRef.current;\n\n // Only auto-switch if an audio source is actually provided\n if (!opts.audioSrc) return;\n\n fragCountRef.current += 1;\n\n // ── Measure actual per-fragment bandwidth ────────────────────────\n // hls.bandwidthEstimate is an EWMA that reacts slowly — if the page\n // loaded on fast WiFi the estimate stays high for many fragments.\n // Instead measure each fragment directly: bytes × 8 / load-time(ms) = Kbps\n const loadMs = fragData.stats.loading.end - fragData.stats.loading.start;\n const fragBwKbps = loadMs > 0 && fragData.stats.total > 0\n ? (fragData.stats.total * 8) / loadMs\n : 0;\n\n const threshold = opts.audioBandwidthThreshold ?? 300;\n\n // ── Recovery probe path ──────────────────────────────────────────\n if (recoveryProbePendingRef.current) {\n recoveryProbePendingRef.current = false;\n if (fragBwKbps > 0 && threshold && fragBwKbps > threshold * 1.5) {\n // Bandwidth has recovered — switch back to video\n autoSwitchedRef.current = false;\n hls.startLoad();\n optionsRef.current.onAudioModeChange?.(false);\n setState((prev) => ({ ...prev, isAudioMode: false }));\n } else {\n // Still poor — stop loading, schedule next probe\n hls.stopLoad();\n scheduleRecoveryProbe();\n }\n return;\n }\n\n // ── Normal bandwidth-based auto-switch ───────────────────────────\n if (!threshold) return; // 0 = disabled\n if (manualCooldownActiveRef.current) return;\n if (fragBwKbps <= 0) return;\n\n const samples = bwSamplesRef.current;\n samples.push(fragBwKbps);\n if (samples.length > 5) samples.shift();\n if (samples.length < 2) return; // need at least 2 samples to avoid noise\n\n const avg = samples.reduce((s, v) => s + v, 0) / samples.length;\n\n setState((prev) => {\n if (!prev.isAudioMode && avg < threshold) {\n autoSwitchedRef.current = true;\n optionsRef.current.onAudioModeChange?.(true);\n return { ...prev, isAudioMode: true };\n }\n return prev;\n });\n });\n\n // Helper: schedule a recovery bandwidth probe\n const scheduleRecoveryProbe = () => {\n if (recoveryTimerRef.current) clearTimeout(recoveryTimerRef.current);\n const interval = optionsRef.current.audioModeRecoveryInterval ?? 30_000;\n recoveryTimerRef.current = setTimeout(() => {\n if (!autoSwitchedRef.current || !stateRef.current.isAudioMode) return;\n recoveryProbePendingRef.current = true;\n hls.startLoad(); // loads one fragment → FRAG_LOADED fires → we evaluate\n }, interval);\n };\n\n const MAX_RETRIES = 3;\n hls.on(Events.ERROR, (_, data) => {\n if (!data.fatal) {\n console.warn(\"[hls] non-fatal:\", data.details);\n return;\n }\n switch (data.type) {\n case HLS.ErrorTypes.NETWORK_ERROR:\n if (networkRetriesRef.current < MAX_RETRIES) {\n networkRetriesRef.current += 1;\n const delay = 1000 * networkRetriesRef.current;\n console.warn(\n `[hls] network error – retry ${networkRetriesRef.current}/${MAX_RETRIES} in ${delay}ms`,\n );\n // Guard against retry firing after this HLS instance was replaced/destroyed\n setTimeout(() => {\n if (hlsRef.current === hls) hls.startLoad();\n }, delay);\n } else {\n const err: VideoError = {\n code: \"HLS_NETWORK_ERROR\",\n message: \"Failed to load stream after multiple retries.\",\n };\n setState((prev) => ({ ...prev, error: err }));\n optionsRef.current.onError?.(err);\n }\n break;\n case HLS.ErrorTypes.MEDIA_ERROR:\n console.warn(\"[hls] media error – recovering\");\n hls.recoverMediaError();\n break;\n default: {\n hls.destroy();\n hlsRef.current = null;\n const fatalErr: VideoError = {\n code: \"HLS_FATAL_ERROR\",\n message: \"An unrecoverable HLS error occurred.\",\n };\n setState((prev) => ({ ...prev, error: fatalErr }));\n optionsRef.current.onError?.(fatalErr);\n break;\n }\n }\n });\n\n hlsRef.current = hls;\n }\n } else {\n // Regular video (mp4, webm, etc.)\n video.src = src;\n video.load();\n if (opts.autoplay) video.play().catch(() => {});\n }\n\n return () => {\n if (hlsRef.current) {\n hlsRef.current.destroy();\n hlsRef.current = null;\n }\n if (manualCooldownTimerRef.current) {\n clearTimeout(manualCooldownTimerRef.current);\n manualCooldownTimerRef.current = null;\n }\n if (recoveryTimerRef.current) {\n clearTimeout(recoveryTimerRef.current);\n recoveryTimerRef.current = null;\n }\n recoveryProbePendingRef.current = false;\n // Reset audio element when source changes\n const audio = optionsRef.current.audioRef?.current;\n if (audio) {\n audio.pause();\n audio.removeAttribute(\"src\");\n audio.load();\n }\n };\n }, [src, videoRef]);\n\n // ─── Video element event listeners ──────────────────────────────────────────\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n if (optionsRef.current.muted) video.muted = true;\n if (optionsRef.current.loop) video.loop = true;\n\n const handlePlay = () => {\n setState((prev) => ({ ...prev, isPlaying: true }));\n optionsRef.current.onPlay?.();\n };\n const handlePause = () => {\n setState((prev) => ({ ...prev, isPlaying: false }));\n optionsRef.current.onPause?.();\n };\n const handleEnded = () => {\n setState((prev) => ({ ...prev, isPlaying: false }));\n optionsRef.current.onEnded?.();\n };\n const handleTimeUpdate = () => {\n // In audio mode the audio element drives time updates instead\n if (stateRef.current.isAudioMode && optionsRef.current.audioSrc) return;\n optionsRef.current.onTimeUpdate?.(video.currentTime);\n };\n const handleDurationChange = () => {\n const dur = video.duration;\n const live = !Number.isFinite(dur);\n setState((prev) => ({ ...prev, duration: live ? 0 : dur, isLive: live }));\n if (!live) optionsRef.current.onDurationChange?.(dur);\n };\n const handleVolumeChange = () => {\n const vol = video.volume;\n if (vol > 0 && !video.muted) lastVolumeRef.current = vol;\n setState((prev) => ({\n ...prev,\n volume: vol,\n isMuted: video.muted || vol === 0,\n }));\n };\n const handleRateChange = () => {\n setState((prev) => ({ ...prev, playbackRate: video.playbackRate }));\n };\n const handleError = () => {\n const e = video.error;\n if (!e) return;\n const codeMap: Partial<Record<number, VideoErrorCode>> = {\n 1: \"MEDIA_ERR_ABORTED\",\n 2: \"MEDIA_ERR_NETWORK\",\n 3: \"MEDIA_ERR_DECODE\",\n 4: \"MEDIA_ERR_SRC_NOT_SUPPORTED\",\n };\n const err: VideoError = {\n code: codeMap[e.code] ?? \"UNKNOWN\",\n message: e.message || \"Unknown media error\",\n };\n setState((prev) => ({ ...prev, error: err }));\n optionsRef.current.onError?.(err);\n };\n const handleWaiting = () => {\n setState((prev) => ({ ...prev, isBuffering: true }));\n optionsRef.current.onBuffering?.(true);\n };\n const handleCanPlay = () => {\n setState((prev) => ({ ...prev, isBuffering: false }));\n optionsRef.current.onBuffering?.(false);\n };\n const handlePlaying = () =>\n setState((prev) => ({ ...prev, isBuffering: false }));\n const handleFullscreenChange = () => {\n const fs = !!(\n document.fullscreenElement || (document as any).webkitFullscreenElement\n );\n setState((prev) => ({ ...prev, isFullscreen: fs }));\n };\n const handlePiPChange = () => {\n setState((prev) => ({\n ...prev,\n isPictureInPicture: document.pictureInPictureElement === video,\n }));\n };\n\n video.addEventListener(\"play\", handlePlay);\n video.addEventListener(\"pause\", handlePause);\n video.addEventListener(\"ended\", handleEnded);\n video.addEventListener(\"timeupdate\", handleTimeUpdate);\n video.addEventListener(\"durationchange\", handleDurationChange);\n video.addEventListener(\"volumechange\", handleVolumeChange);\n video.addEventListener(\"ratechange\", handleRateChange);\n video.addEventListener(\"error\", handleError);\n video.addEventListener(\"waiting\", handleWaiting);\n video.addEventListener(\"canplay\", handleCanPlay);\n video.addEventListener(\"playing\", handlePlaying);\n document.addEventListener(\"fullscreenchange\", handleFullscreenChange);\n document.addEventListener(\"webkitfullscreenchange\", handleFullscreenChange);\n video.addEventListener(\"enterpictureinpicture\", handlePiPChange);\n video.addEventListener(\"leavepictureinpicture\", handlePiPChange);\n\n return () => {\n video.removeEventListener(\"play\", handlePlay);\n video.removeEventListener(\"pause\", handlePause);\n video.removeEventListener(\"ended\", handleEnded);\n video.removeEventListener(\"timeupdate\", handleTimeUpdate);\n video.removeEventListener(\"durationchange\", handleDurationChange);\n video.removeEventListener(\"volumechange\", handleVolumeChange);\n video.removeEventListener(\"ratechange\", handleRateChange);\n video.removeEventListener(\"error\", handleError);\n video.removeEventListener(\"waiting\", handleWaiting);\n video.removeEventListener(\"canplay\", handleCanPlay);\n video.removeEventListener(\"playing\", handlePlaying);\n document.removeEventListener(\"fullscreenchange\", handleFullscreenChange);\n document.removeEventListener(\n \"webkitfullscreenchange\",\n handleFullscreenChange,\n );\n video.removeEventListener(\"enterpictureinpicture\", handlePiPChange);\n video.removeEventListener(\"leavepictureinpicture\", handlePiPChange);\n };\n }, [videoRef]); // stable – options accessed via optionsRef\n\n // ─── Audio element event listeners ──────────────────────────────────────────\n useEffect(() => {\n const audio = optionsRef.current.audioRef?.current;\n if (!audio || !optionsRef.current.audioSrc) return;\n\n const handlePlay = () => {\n setState((prev) => ({ ...prev, isPlaying: true }));\n optionsRef.current.onPlay?.();\n };\n const handlePause = () => {\n setState((prev) => ({ ...prev, isPlaying: false }));\n optionsRef.current.onPause?.();\n };\n const handleEnded = () => {\n setState((prev) => ({ ...prev, isPlaying: false }));\n optionsRef.current.onEnded?.();\n };\n const handleWaiting = () => {\n setState((prev) => ({ ...prev, isBuffering: true }));\n optionsRef.current.onBuffering?.(true);\n };\n const handleCanPlay = () => {\n setState((prev) => ({ ...prev, isBuffering: false }));\n optionsRef.current.onBuffering?.(false);\n };\n const handlePlaying = () =>\n setState((prev) => ({ ...prev, isBuffering: false }));\n const handleTimeUpdate = () => {\n if (!stateRef.current.isAudioMode) return;\n optionsRef.current.onTimeUpdate?.(audio.currentTime);\n };\n const handleDurationChange = () => {\n const dur = audio.duration;\n if (isFinite(dur)) {\n setState((prev) => ({ ...prev, duration: dur }));\n optionsRef.current.onDurationChange?.(dur);\n }\n };\n const handleError = () => {\n const err: VideoError = { code: \"MEDIA_ERR_NETWORK\", message: \"Audio source failed to load.\" };\n setState((prev) => ({ ...prev, error: err }));\n optionsRef.current.onError?.(err);\n };\n\n audio.addEventListener(\"play\", handlePlay);\n audio.addEventListener(\"pause\", handlePause);\n audio.addEventListener(\"ended\", handleEnded);\n audio.addEventListener(\"waiting\", handleWaiting);\n audio.addEventListener(\"canplay\", handleCanPlay);\n audio.addEventListener(\"playing\", handlePlaying);\n audio.addEventListener(\"timeupdate\", handleTimeUpdate);\n audio.addEventListener(\"durationchange\", handleDurationChange);\n audio.addEventListener(\"error\", handleError);\n\n return () => {\n audio.removeEventListener(\"play\", handlePlay);\n audio.removeEventListener(\"pause\", handlePause);\n audio.removeEventListener(\"ended\", handleEnded);\n audio.removeEventListener(\"waiting\", handleWaiting);\n audio.removeEventListener(\"canplay\", handleCanPlay);\n audio.removeEventListener(\"playing\", handlePlaying);\n audio.removeEventListener(\"timeupdate\", handleTimeUpdate);\n audio.removeEventListener(\"durationchange\", handleDurationChange);\n audio.removeEventListener(\"error\", handleError);\n };\n }, [src]); // re-bind when content changes\n\n // ─── Sync between video and audio on mode switch ─────────────────────────────\n useEffect(() => {\n const opts = optionsRef.current;\n const video = videoRef.current;\n const audio = opts.audioRef?.current;\n if (!video || !audio || !opts.audioSrc) return;\n\n if (state.isAudioMode) {\n // Entering audio mode — pause video (stops decoding), hand off to audio element\n const pos = video.currentTime;\n const wasPlaying = !video.paused;\n video.pause();\n // Stop HLS from buffering video in the background — saves bandwidth for audio\n hlsRef.current?.stopLoad();\n if (!audio.getAttribute(\"src\")) audio.src = opts.audioSrc;\n audio.currentTime = pos;\n audio.volume = video.volume;\n audio.muted = video.muted;\n audio.playbackRate = video.playbackRate;\n if (wasPlaying) audio.play().catch(() => {});\n // Schedule bandwidth recovery probes if this was an automatic switch\n if (autoSwitchedRef.current) {\n if (recoveryTimerRef.current) clearTimeout(recoveryTimerRef.current);\n const interval = opts.audioModeRecoveryInterval ?? 30_000;\n recoveryTimerRef.current = setTimeout(() => {\n if (!autoSwitchedRef.current || !stateRef.current.isAudioMode) return;\n recoveryProbePendingRef.current = true;\n hlsRef.current?.startLoad();\n }, interval);\n }\n } else {\n // Leaving audio mode — hand off back to video element\n const pos = audio.currentTime;\n const wasPlaying = !audio.paused;\n audio.pause();\n // Cancel any pending recovery probe\n if (recoveryTimerRef.current) {\n clearTimeout(recoveryTimerRef.current);\n recoveryTimerRef.current = null;\n }\n recoveryProbePendingRef.current = false;\n // Resume HLS video loading\n hlsRef.current?.startLoad();\n video.currentTime = pos;\n video.volume = audio.volume;\n if (wasPlaying) video.play().catch(() => {});\n }\n }, [state.isAudioMode, videoRef]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // ─── Control methods (all stable via useCallback with empty or minimal deps) ─\n const play = useCallback(async () => {\n const media = getActiveMedia();\n if (!media) return;\n try {\n await media.play();\n } catch (err: unknown) {\n if (err instanceof Error && err.name !== \"AbortError\")\n console.error(\"[player] play() failed:\", err);\n }\n }, [getActiveMedia]);\n\n const pause = useCallback(() => {\n getActiveMedia()?.pause();\n }, [getActiveMedia]);\n\n const seek = useCallback(\n (time: number) => {\n const media = getActiveMedia();\n if (!media) return;\n media.currentTime = Math.max(0, Math.min(time, media.duration || time));\n },\n [getActiveMedia],\n );\n\n const setVolume = useCallback(\n (volume: number) => {\n const media = getActiveMedia();\n if (!media) return;\n const v = Math.max(0, Math.min(volume, 1));\n if (v > 0) lastVolumeRef.current = v;\n media.volume = v;\n media.muted = v === 0;\n },\n [getActiveMedia],\n );\n\n const toggleMute = useCallback(() => {\n const media = getActiveMedia();\n if (!media) return;\n if (media.muted || media.volume === 0) {\n const restore = lastVolumeRef.current > 0 ? lastVolumeRef.current : 1;\n media.volume = restore;\n media.muted = false;\n } else {\n lastVolumeRef.current = media.volume;\n media.muted = true;\n }\n }, [getActiveMedia]);\n\n const setPlaybackRate = useCallback(\n (rate: PlaybackRate) => {\n // Apply to both so rate is preserved across mode switches\n const video = videoRef.current;\n if (video) video.playbackRate = rate;\n const audio = optionsRef.current.audioRef?.current;\n if (audio) audio.playbackRate = rate;\n },\n [videoRef],\n );\n\n const setQualityLevel = useCallback((level: number) => {\n const hls = hlsRef.current;\n if (!hls) return;\n hls.currentLevel = level;\n setState((prev) => ({ ...prev, currentQualityLevel: level }));\n }, []);\n\n const seekToLive = useCallback(() => {\n const hls = hlsRef.current;\n const video = videoRef.current;\n if (!hls || !video) return;\n const livePos = hls.liveSyncPosition;\n if (livePos != null && Number.isFinite(livePos))\n video.currentTime = livePos;\n }, [videoRef]);\n\n const toggleFullscreen = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n const container = fullscreenContainerRef.current ?? video.parentElement;\n if (!container) return;\n try {\n if (\n !document.fullscreenElement &&\n !(document as any).webkitFullscreenElement\n ) {\n if (container.requestFullscreen) await container.requestFullscreen();\n else (container as any).webkitRequestFullscreen?.();\n } else {\n if (document.exitFullscreen) await document.exitFullscreen();\n else (document as any).webkitExitFullscreen?.();\n }\n } catch (err) {\n console.error(\"[player] fullscreen toggle failed:\", err);\n }\n }, [videoRef]);\n\n const togglePictureInPicture = useCallback(async () => {\n const video = videoRef.current;\n if (!video) return;\n try {\n if (document.pictureInPictureElement)\n await document.exitPictureInPicture();\n else await video.requestPictureInPicture();\n } catch (err) {\n console.error(\"[player] PiP toggle failed:\", err);\n }\n }, [videoRef]);\n\n const toggleTheaterMode = useCallback(() => {\n const next = !stateRef.current.isTheaterMode;\n setState((prev) => ({ ...prev, isTheaterMode: next }));\n optionsRef.current.onTheaterModeChange?.(next);\n }, []);\n\n const toggleAudioMode = useCallback(() => {\n // Clear any running cooldown\n if (manualCooldownTimerRef.current) clearTimeout(manualCooldownTimerRef.current);\n\n // Mark as a manual override — suppress auto-detection for 60 s\n autoSwitchedRef.current = false;\n manualCooldownActiveRef.current = true;\n manualCooldownTimerRef.current = setTimeout(() => {\n manualCooldownActiveRef.current = false;\n // Clear samples so auto-detection starts fresh after cooldown\n bwSamplesRef.current = [];\n }, 60_000);\n\n const next = !stateRef.current.isAudioMode;\n setState((prev) => ({ ...prev, isAudioMode: next }));\n optionsRef.current.onAudioModeChange?.(next);\n }, []);\n\n const getState = useCallback((): PlayerState => {\n const media = getActiveMedia();\n const currentTime = media?.currentTime ?? 0;\n const bufferedRanges: import(\"../lib/types\").BufferedRange[] = [];\n if (media) {\n for (let i = 0; i < media.buffered.length; i++) {\n bufferedRanges.push({ start: media.buffered.start(i), end: media.buffered.end(i) });\n }\n }\n return { ...stateRef.current, currentTime, bufferedRanges };\n }, [getActiveMedia]);\n\n const getVideoElement = useCallback(\n (): HTMLVideoElement | null => videoRef.current ?? null,\n [videoRef],\n );\n\n const ref = useMemo<VideoPlayerRef>(\n () => ({\n play,\n pause,\n seek,\n setVolume,\n toggleMute,\n setPlaybackRate,\n setQualityLevel,\n seekToLive,\n toggleFullscreen,\n togglePictureInPicture,\n toggleTheaterMode,\n toggleAudioMode,\n getState,\n getVideoElement,\n }),\n [\n play,\n pause,\n seek,\n setVolume,\n toggleMute,\n setPlaybackRate,\n setQualityLevel,\n seekToLive,\n toggleFullscreen,\n togglePictureInPicture,\n toggleTheaterMode,\n toggleAudioMode,\n getState,\n getVideoElement,\n ],\n );\n\n return { state, ref, hlsRef, fullscreenContainerRef };\n}\n","import {\n PlayButton,\n PauseButton,\n FullscreenButton,\n PiPButton,\n TheaterButton,\n} from \"./control-buttons\";\nimport VolumeControl from \"./volume-control\";\nimport ProgressBar from \"./progress-bar\";\nimport SettingsMenu from \"./settings-menu\";\nimport TimeDisplay from \"./time-display\";\n\nexport type {\n PlayButtonProps,\n PauseButtonProps,\n FullscreenButtonProps,\n PiPButtonProps,\n TheaterButtonProps,\n} from \"./control-buttons\";\n\nexport type { VolumeControlProps } from \"./volume-control\";\nexport type { ProgressBarProps } from \"./progress-bar\";\nexport type { SettingsMenuProps } from \"./settings-menu\";\nexport type { TimeDisplayProps } from \"./time-display\";\n\nexport {\n PlayButton,\n PauseButton,\n FullscreenButton,\n PiPButton,\n TheaterButton,\n} from \"./control-buttons\";\n\nexport { default as VolumeControl } from \"./volume-control\";\nexport { default as ProgressBar } from \"./progress-bar\";\nexport { default as SettingsMenu } from \"./settings-menu\";\nexport { default as TimeDisplay } from \"./time-display\";\n\nexport const ControlElements = {\n PlayButton,\n PauseButton,\n FullscreenButton,\n PiPButton,\n TheaterButton,\n VolumeControl,\n ProgressBar,\n SettingsMenu,\n TimeDisplay,\n};\n","\"use client\";\n\nimport { memo } from \"react\";\n\nexport interface PlayButtonProps { onClick: () => void; }\nexport interface PauseButtonProps { onClick: () => void; }\nexport interface FullscreenButtonProps { onClick: () => void; isFullscreen?: boolean; }\nexport interface PiPButtonProps { onClick: () => void; isPiP?: boolean; }\n\nexport const PlayButton = memo<PlayButtonProps>(({ onClick }) => (\n <button onClick={onClick} className=\"controlButton\" aria-label=\"Play\" title=\"Play (Space)\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n </button>\n));\nPlayButton.displayName = \"PlayButton\";\n\nexport const PauseButton = memo<PauseButtonProps>(({ onClick }) => (\n <button onClick={onClick} className=\"controlButton\" aria-label=\"Pause\" title=\"Pause (Space)\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M6 4h4v16H6V4zm8 0h4v16h-4V4z\" />\n </svg>\n </button>\n));\nPauseButton.displayName = \"PauseButton\";\n\nexport const FullscreenButton = memo<FullscreenButtonProps>(({ onClick, isFullscreen = false }) => (\n <button\n onClick={onClick}\n className=\"controlButton\"\n aria-label={isFullscreen ? \"Exit Fullscreen\" : \"Fullscreen\"}\n title={isFullscreen ? \"Exit Fullscreen (F)\" : \"Fullscreen (F)\"}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n {isFullscreen ? (\n <path d=\"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z\" />\n ) : (\n <path d=\"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z\" />\n )}\n </svg>\n </button>\n));\nFullscreenButton.displayName = \"FullscreenButton\";\n\nexport const PiPButton = memo<PiPButtonProps>(({ onClick, isPiP = false }) => (\n <button\n onClick={onClick}\n className=\"controlButton\"\n aria-label={isPiP ? \"Exit Picture-in-Picture\" : \"Picture-in-Picture\"}\n title={isPiP ? \"Exit Picture-in-Picture (P)\" : \"Picture-in-Picture (P)\"}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19 11h-8v6h8v-6zm4 8V4.98C23 3.88 22.1 3 21 3H3c-1.1 0-2 .88-2 1.98V19c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2zm-2 .02H3V5h18v14.02z\" />\n </svg>\n </button>\n));\nPiPButton.displayName = \"PiPButton\";\n\nexport interface TheaterButtonProps { onClick: () => void; isTheater?: boolean; }\n\nexport const TheaterButton = memo<TheaterButtonProps>(({ onClick, isTheater = false }) => (\n <button\n onClick={onClick}\n className=\"controlButton\"\n aria-label={isTheater ? \"Exit Theater Mode\" : \"Theater Mode\"}\n title={isTheater ? \"Exit Theater Mode (T)\" : \"Theater Mode (T)\"}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n {isTheater ? (\n /* Exit theater: narrower inner rectangle — signals \"shrink back\" */\n <path d=\"M19 7H5c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zm0 8H5V9h14v6z\" />\n ) : (\n /* Enter theater: full-width rectangle — signals \"expand wide\" */\n <path d=\"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z\" />\n )}\n </svg>\n </button>\n));\nTheaterButton.displayName = \"TheaterButton\";\n\nexport default { PlayButton, PauseButton, FullscreenButton, PiPButton, TheaterButton };\n","\"use client\";\n\nimport { memo, useState, useMemo } from \"react\";\n\nexport interface VolumeControlProps {\n volume: number;\n isMuted: boolean;\n onVolumeChange: (volume: number) => void;\n onToggleMute: () => void;\n}\n\n\nconst VolumeControl = memo<VolumeControlProps>(({\n volume,\n isMuted,\n onVolumeChange,\n onToggleMute,\n}) => {\n const [showSlider, setShowSlider] = useState(false);\n const displayVolume = isMuted ? 0 : volume;\n const percentage = displayVolume * 100;\n\n const sliderBackground = useMemo(\n () =>\n `linear-gradient(to right, #60a5fa 0%, #60a5fa ${percentage}%, rgba(255,255,255,0.3) ${percentage}%, rgba(255,255,255,0.3) 100%)`,\n [percentage],\n );\n\n return (\n <div\n className=\"volumeContainer\"\n onMouseEnter={() => setShowSlider(true)}\n onMouseLeave={() => setShowSlider(false)}\n >\n <button\n onClick={onToggleMute}\n className=\"controlButton\"\n aria-label={isMuted ? \"Unmute\" : \"Mute\"}\n title={isMuted ? \"Unmute (M)\" : \"Mute (M)\"}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n {displayVolume === 0 ? (\n <path d=\"M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C23.16 14.42 24 13.3 24 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z\" />\n ) : displayVolume < 0.5 ? (\n <path d=\"M7 9v6h4l5 5V4l-5 5H7z\" />\n ) : (\n <path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\" />\n )}\n </svg>\n </button>\n\n {showSlider && (\n <input\n type=\"range\"\n min=\"0\"\n max=\"100\"\n value={percentage}\n onChange={(e) => onVolumeChange(Number(e.target.value) / 100)}\n className=\"volumeSlider\"\n style={{ background: sliderBackground }}\n aria-label=\"Volume\"\n aria-valuenow={Math.round(percentage)}\n />\n )}\n </div>\n );\n});\n\nVolumeControl.displayName = \"VolumeControl\";\nexport default VolumeControl;\n","export interface ThumbnailCue {\n start: number;\n end: number;\n /** Absolute URL to the sprite image */\n url: string;\n /** Pixel offset from the left of the sprite sheet */\n x: number;\n /** Pixel offset from the top of the sprite sheet */\n y: number;\n /** Width of a single thumbnail cell */\n w: number;\n /** Height of a single thumbnail cell */\n h: number;\n}\n\nfunction parseVttTime(s: string): number {\n const parts = s.trim().split(\":\");\n if (parts.length === 3) {\n return +parts[0] * 3600 + +parts[1] * 60 + parseFloat(parts[2]);\n }\n return +parts[0] * 60 + parseFloat(parts[1]);\n}\n\nfunction resolveUrl(base: string, url: string): string {\n if (/^https?:\\/\\//i.test(url)) return url;\n try {\n return new URL(url, base).href;\n } catch {\n return url;\n }\n}\n\n/**\n * Parse a WebVTT thumbnail track into an array of cues.\n *\n * Supports the standard sprite-sheet format:\n * 00:00:00.000 --> 00:00:05.000\n * https://cdn.example.com/thumbs/s0.jpg#xywh=0,0,160,90\n *\n * @param text Raw VTT file text\n * @param baseUrl VTT file URL — used to resolve relative image paths\n */\nexport function parseThumbnailVtt(text: string, baseUrl = \"\"): ThumbnailCue[] {\n const cues: ThumbnailCue[] = [];\n const lines = text.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n let i = 0;\n\n while (i < lines.length) {\n const line = lines[i].trim();\n\n if (line.includes(\"-->\")) {\n const arrow = line.indexOf(\"-->\");\n const start = parseVttTime(line.slice(0, arrow));\n const end = parseVttTime(line.slice(arrow + 3));\n i++;\n\n // Skip blank lines between timing and URL\n while (i < lines.length && !lines[i].trim()) i++;\n\n if (i < lines.length) {\n const urlLine = lines[i].trim();\n const hashIdx = urlLine.lastIndexOf(\"#xywh=\");\n let url = urlLine;\n let x = 0, y = 0, w = 160, h = 90;\n\n if (hashIdx !== -1) {\n url = urlLine.slice(0, hashIdx);\n const coords = urlLine.slice(hashIdx + 6).split(\",\").map(Number);\n x = coords[0] ?? 0;\n y = coords[1] ?? 0;\n w = coords[2] ?? 160;\n h = coords[3] ?? 90;\n }\n\n cues.push({ start, end, url: resolveUrl(baseUrl, url), x, y, w, h });\n }\n }\n\n i++;\n }\n\n return cues;\n}\n\n/**\n * Binary-search for the cue that covers `time` (seconds).\n * Returns null if no cue covers that timestamp.\n */\nexport function findThumbnailCue(\n cues: ThumbnailCue[],\n time: number,\n): ThumbnailCue | null {\n if (!cues.length) return null;\n\n let lo = 0;\n let hi = cues.length - 1;\n\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (cues[mid].end <= time) lo = mid + 1;\n else if (cues[mid].start > time) hi = mid - 1;\n else return cues[mid];\n }\n\n return null;\n}\n","\"use client\";\n\nimport React, { memo, useRef, useState, useEffect, useCallback, useMemo } from \"react\";\nimport type { VideoPlayerRef, BufferedRange } from \"../../lib/types\";\nimport { formatTime } from \"../../lib/format\";\nimport { parseThumbnailVtt, findThumbnailCue } from \"../../lib/vtt\";\nimport type { ThumbnailCue } from \"../../lib/vtt\";\n\nexport interface ProgressBarProps {\n videoRef: React.RefObject<HTMLMediaElement | null>;\n playerRef: VideoPlayerRef;\n enablePreview?: boolean;\n thumbnailVtt?: string;\n}\n\nconst ProgressBar: React.FC<ProgressBarProps> = memo(({\n videoRef,\n playerRef,\n enablePreview = true,\n thumbnailVtt,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const progressFilledRef = useRef<HTMLDivElement>(null);\n const scrubHandleRef = useRef<HTMLDivElement>(null);\n const tooltipRef = useRef<HTMLDivElement>(null);\n const hoverTimeTextRef = useRef<HTMLDivElement>(null);\n const hoverIndicatorRef = useRef<HTMLDivElement>(null);\n const thumbRef = useRef<HTMLDivElement>(null);\n\n // Only bufferedRanges stays in React state — it changes on the `progress`\n // event which fires infrequently (every few seconds during buffering).\n const [bufferedRanges, setBufferedRanges] = useState<BufferedRange[]>([]);\n\n // Imperative state — no React re-renders for any of these\n const isDraggingRef = useRef(false);\n const hoverPosRef = useRef(0);\n const hoverTimeRef = useRef(0);\n const lastCueRef = useRef<ThumbnailCue | null>(null);\n\n // VTT thumbnail cues — loaded once, looked up synchronously\n const thumbnailCuesRef = useRef<ThumbnailCue[]>([]);\n\n /**\n * Rect cache — getBoundingClientRect() is expensive; invalidate on resize only.\n */\n const rectCacheRef = useRef<DOMRect | null>(null);\n\n useEffect(() => {\n const invalidate = () => { rectCacheRef.current = null; };\n window.addEventListener(\"resize\", invalidate, { passive: true });\n return () => window.removeEventListener(\"resize\", invalidate);\n }, []);\n\n const getRect = useCallback((): DOMRect | null => {\n if (!rectCacheRef.current && containerRef.current) {\n rectCacheRef.current = containerRef.current.getBoundingClientRect();\n }\n return rectCacheRef.current;\n }, []);\n\n // ─── Load VTT thumbnail cues ────────────────────────────────────────────\n useEffect(() => {\n if (!thumbnailVtt) {\n thumbnailCuesRef.current = [];\n return;\n }\n let cancelled = false;\n fetch(thumbnailVtt)\n .then(r => r.text())\n .then(text => {\n if (!cancelled) thumbnailCuesRef.current = parseThumbnailVtt(text, thumbnailVtt);\n })\n .catch(() => {\n if (!cancelled) thumbnailCuesRef.current = [];\n });\n return () => { cancelled = true; };\n }, [thumbnailVtt]);\n\n // ─── Subscribe to timeupdate / durationchange ────────────────────────────\n // Updates the progress fill and scrub handle position imperatively —\n // zero React re-renders during playback.\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const updateProgress = () => {\n const dur = isFinite(video.duration) ? video.duration : 0;\n const ct = video.currentTime;\n const pct = dur > 0 ? (ct / dur) * 100 : 0;\n\n if (progressFilledRef.current)\n progressFilledRef.current.style.width = `${pct}%`;\n if (scrubHandleRef.current)\n scrubHandleRef.current.style.left = `${pct}%`;\n if (containerRef.current) {\n containerRef.current.setAttribute(\"aria-valuenow\", String(Math.round(ct)));\n containerRef.current.setAttribute(\"aria-valuemax\", String(Math.round(dur)));\n containerRef.current.setAttribute(\"aria-valuetext\", formatTime(ct));\n }\n };\n\n video.addEventListener(\"timeupdate\", updateProgress);\n video.addEventListener(\"durationchange\", updateProgress);\n video.addEventListener(\"seeked\", updateProgress);\n updateProgress(); // sync on mount\n\n return () => {\n video.removeEventListener(\"timeupdate\", updateProgress);\n video.removeEventListener(\"durationchange\", updateProgress);\n video.removeEventListener(\"seeked\", updateProgress);\n };\n }, [videoRef]);\n\n // ─── Subscribe to progress (buffered ranges) ────────────────────────────\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const updateBuffered = () => {\n const ranges: BufferedRange[] = [];\n for (let i = 0; i < video.buffered.length; i++) {\n ranges.push({ start: video.buffered.start(i), end: video.buffered.end(i) });\n }\n setBufferedRanges(ranges);\n };\n\n video.addEventListener(\"progress\", updateBuffered);\n return () => video.removeEventListener(\"progress\", updateBuffered);\n }, [videoRef]);\n\n // ─── Non-React drag-state helpers ────────────────────────────────────────\n const startDragging = useCallback(() => {\n isDraggingRef.current = true;\n scrubHandleRef.current?.classList.add(\"dragging\");\n }, []);\n\n const stopDragging = useCallback(() => {\n isDraggingRef.current = false;\n scrubHandleRef.current?.classList.remove(\"dragging\");\n }, []);\n\n // ─── Show / hide preview tooltip ─────────────────────────────────────────\n const showTooltip = useCallback(() => {\n if (!enablePreview) return;\n rectCacheRef.current = null; // invalidate rect on re-entry\n if (tooltipRef.current) tooltipRef.current.style.display = \"block\";\n if (hoverIndicatorRef.current) hoverIndicatorRef.current.style.display = \"block\";\n }, [enablePreview]);\n\n const hideTooltip = useCallback(() => {\n if (tooltipRef.current) tooltipRef.current.style.display = \"none\";\n if (hoverIndicatorRef.current) hoverIndicatorRef.current.style.display = \"none\";\n }, []);\n\n // ─── Apply thumbnail from VTT cue ────────────────────────────────────────\n const applyThumbnail = useCallback((time: number) => {\n if (!thumbRef.current || !thumbnailCuesRef.current.length) return;\n const cue = findThumbnailCue(thumbnailCuesRef.current, time);\n lastCueRef.current = cue;\n if (!cue) return;\n const el = thumbRef.current;\n el.style.backgroundImage = `url(${cue.url})`;\n el.style.backgroundPosition = `-${cue.x}px -${cue.y}px`;\n el.style.width = `${cue.w}px`;\n el.style.height = `${cue.h}px`;\n }, []);\n\n // ─── Geometry helpers ────────────────────────────────────────────────────\n const getTimeFromClientX = useCallback((clientX: number): number => {\n const rect = getRect();\n const dur = videoRef.current?.duration;\n if (!rect || rect.width === 0 || !dur || !isFinite(dur)) return 0;\n const pos = Math.max(0, Math.min(clientX - rect.left, rect.width));\n return (pos / rect.width) * dur;\n }, [getRect, videoRef]);\n\n const getPxFromClientX = useCallback((clientX: number): number => {\n const rect = getRect();\n if (!rect) return 0;\n return Math.max(0, Math.min(clientX - rect.left, rect.width));\n }, [getRect]);\n\n // ─── Keyboard handler ────────────────────────────────────────────────────\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {\n const video = videoRef.current;\n if (!video) return;\n const ct = video.currentTime;\n const dur = isFinite(video.duration) ? video.duration : 0;\n\n switch (e.key) {\n case \"ArrowLeft\":\n case \"ArrowRight\": {\n e.preventDefault();\n e.nativeEvent.stopImmediatePropagation();\n const step = e.shiftKey ? 10 : 5;\n playerRef.seek(e.key === \"ArrowLeft\"\n ? Math.max(0, ct - step)\n : Math.min(dur, ct + step));\n break;\n }\n case \"Home\":\n e.preventDefault();\n e.nativeEvent.stopImmediatePropagation();\n playerRef.seek(0);\n break;\n case \"End\":\n if (dur > 0) {\n e.preventDefault();\n e.nativeEvent.stopImmediatePropagation();\n playerRef.seek(dur);\n }\n break;\n }\n }, [videoRef, playerRef]);\n\n // ─── Mouse handlers ───────────────────────────────────────────────────────\n const handleMouseMove = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n const time = getTimeFromClientX(e.clientX);\n const px = getPxFromClientX(e.clientX);\n\n hoverPosRef.current = px;\n hoverTimeRef.current = time;\n\n if (hoverIndicatorRef.current) hoverIndicatorRef.current.style.left = `${px}px`;\n if (hoverTimeTextRef.current) hoverTimeTextRef.current.textContent = formatTime(time);\n\n\n applyThumbnail(time);\n\n if (tooltipRef.current) {\n const tooltipWidth = tooltipRef.current.offsetWidth;\n const containerWidth = getRect()?.width ?? 0;\n const halfWidth = tooltipWidth / 2;\n const clampedLeft = Math.max(halfWidth, Math.min(px, containerWidth - halfWidth));\n tooltipRef.current.style.left = `${clampedLeft}px`;\n }\n\n if (isDraggingRef.current) playerRef.seek(time);\n }, [playerRef, applyThumbnail, getTimeFromClientX, getPxFromClientX, getRect]);\n\n const handleMouseLeave = useCallback(() => {\n hideTooltip();\n stopDragging();\n }, [hideTooltip, stopDragging]);\n\n const handleMouseDown = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n startDragging();\n playerRef.seek(getTimeFromClientX(e.clientX));\n }, [startDragging, getTimeFromClientX, playerRef]);\n\n\n const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n if (!isDraggingRef.current) playerRef.seek(getTimeFromClientX(e.clientX));\n }, [getTimeFromClientX, playerRef]);\n\n // ─── Touch handlers ───────────────────────────────────────────────────────\n useEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n const onTouchMove = (e: TouchEvent) => {\n if (isDraggingRef.current) e.preventDefault();\n };\n container.addEventListener(\"touchmove\", onTouchMove, { passive: false });\n return () => container.removeEventListener(\"touchmove\", onTouchMove);\n }, []);\n\n const handleTouchStart = useCallback((e: React.TouchEvent<HTMLDivElement>) => {\n rectCacheRef.current = null;\n startDragging();\n playerRef.seek(getTimeFromClientX(e.touches[0].clientX));\n }, [startDragging, getTimeFromClientX, playerRef]);\n\n const handleTouchMove = useCallback((e: React.TouchEvent<HTMLDivElement>) => {\n if (!isDraggingRef.current) return;\n playerRef.seek(getTimeFromClientX(e.touches[0].clientX));\n }, [getTimeFromClientX, playerRef]);\n\n\n // Release drag if pointer leaves the window\n useEffect(() => {\n const up = () => stopDragging();\n window.addEventListener(\"mouseup\", up);\n return () => window.removeEventListener(\"mouseup\", up);\n }, [stopDragging]);\n\n // ─── Buffered segments (memoised — only re-renders on progress event) ────\n const bufferedSegments = useMemo(() => {\n const video = videoRef.current;\n const dur = video && isFinite(video.duration) ? video.duration : 0;\n if (dur <= 0 || !bufferedRanges.length) return null;\n return bufferedRanges.map((range, i) => {\n const start = (range.start / dur) * 100;\n const width = ((range.end - range.start) / dur) * 100;\n return (\n <div\n key={i}\n className=\"bufferedSegment\"\n style={{ left: `${start}%`, width: `${width}%` }}\n />\n );\n });\n }, [bufferedRanges, videoRef]);\n\n return (\n <div\n ref={containerRef}\n className=\"progressContainer\"\n onMouseMove={handleMouseMove}\n onMouseEnter={showTooltip}\n onMouseLeave={handleMouseLeave}\n onMouseDown={handleMouseDown}\n onMouseUp={stopDragging}\n onClick={handleClick}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={stopDragging}\n onKeyDown={handleKeyDown}\n role=\"slider\"\n aria-label=\"Video progress\"\n aria-valuemin={0}\n aria-valuemax={0}\n aria-valuenow={0}\n aria-valuetext=\"0:00\"\n tabIndex={0}\n >\n {/* Tooltip — always in DOM when preview enabled; shown/hidden imperatively */}\n {enablePreview && (\n <div\n ref={tooltipRef}\n className=\"previewTooltip\"\n style={{ left: 0, display: \"none\" }}\n aria-hidden=\"true\"\n >\n {thumbnailVtt && (\n <div ref={thumbRef} className=\"previewThumbnail\" />\n )}\n <div ref={hoverTimeTextRef} className=\"previewTime\" />\n </div>\n )}\n\n {/* Track */}\n <div className=\"progressBackground\">\n {bufferedSegments}\n <div ref={progressFilledRef} className=\"progressFilled\" style={{ width: \"0%\" }} />\n {enablePreview && (\n <div\n ref={hoverIndicatorRef}\n className=\"hoverIndicator\"\n style={{ left: 0, display: \"none\" }}\n aria-hidden=\"true\"\n />\n )}\n </div>\n\n {/* Scrub handle — class toggled imperatively for dragging state */}\n <div\n ref={scrubHandleRef}\n className=\"scrubHandle\"\n style={{ left: \"0%\" }}\n aria-hidden=\"true\"\n />\n </div>\n );\n});\n\nProgressBar.displayName = \"ProgressBar\";\n\nexport default ProgressBar;\n","\"use client\";\n\nimport { memo, useState, useRef, useEffect, useMemo } from \"react\";\nimport type { PlaybackRate, HLSQualityLevel } from \"../../lib/types\";\n\nexport interface SettingsMenuProps {\n currentRate: number;\n playbackRates: PlaybackRate[];\n onRateChange: (rate: PlaybackRate) => void;\n qualityLevels?: HLSQualityLevel[];\n currentQualityLevel?: number;\n onQualityChange?: (level: number) => void;\n}\n\ntype Tab = \"speed\" | \"quality\";\n\nconst SettingsMenu = memo<SettingsMenuProps>(({\n currentRate,\n playbackRates,\n onRateChange,\n qualityLevels = [],\n currentQualityLevel = -1,\n onQualityChange,\n}) => {\n const [open, setOpen] = useState(false);\n const [tab, setTab] = useState<Tab>(\"speed\");\n const containerRef = useRef<HTMLDivElement>(null);\n\n const hasQuality = qualityLevels.length > 0 && !!onQualityChange;\n\n // Close when clicking outside\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (containerRef.current && !containerRef.current.contains(e.target as Node)) {\n setOpen(false);\n }\n };\n if (open) document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n /**\n * Sort once when qualityLevels changes\n */\n const sortedLevels = useMemo(\n () => [...qualityLevels].sort((a, b) => b.bitrate - a.bitrate),\n [qualityLevels],\n );\n\n const currentQualityName = useMemo(() => {\n if (currentQualityLevel === -1) return \"Auto\";\n return qualityLevels.find((l) => l.id === currentQualityLevel)?.name ?? \"Auto\";\n }, [qualityLevels, currentQualityLevel]);\n\n return (\n <div ref={containerRef} className=\"settingsContainer\">\n <button\n onClick={() => setOpen((o) => !o)}\n className=\"controlButton\"\n aria-label=\"Settings\"\n title=\"Settings\"\n aria-expanded={open}\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19.14 12.94c.04-.3.06-.61.06-.94s-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.49.49 0 0 0-.59-.22l-2.39.96a7.02 7.02 0 0 0-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54a6.88 6.88 0 0 0-1.61.94l-2.39-.96a.488.488 0 0 0-.59.22L2.74 8.87a.48.48 0 0 0 .12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54a6.88 6.88 0 0 0 1.61-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32a.47.47 0 0 0-.12-.61l-2.01-1.58zM12 15.6A3.6 3.6 0 0 1 8.4 12 3.6 3.6 0 0 1 12 8.4a3.6 3.6 0 0 1 3.6 3.6 3.6 3.6 0 0 1-3.6 3.6z\" />\n </svg>\n </button>\n\n {open && (\n <div className=\"settingsDropdown\" role=\"menu\">\n {hasQuality && (\n <div className=\"settingsTabs\">\n <button\n className={`settingsTab${tab === \"speed\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"speed\")}\n >\n Speed\n </button>\n <button\n className={`settingsTab${tab === \"quality\" ? \" active\" : \"\"}`}\n onClick={() => setTab(\"quality\")}\n >\n Quality\n </button>\n </div>\n )}\n\n {(!hasQuality || tab === \"speed\") && (\n <div>\n {!hasQuality && <div className=\"settingsPanelLabel\">Playback Speed</div>}\n {playbackRates.map((rate) => (\n <button\n key={rate}\n onClick={() => { onRateChange(rate); setOpen(false); }}\n className={`settingsOption${currentRate === rate ? \" active\" : \"\"}`}\n role=\"menuitemradio\"\n aria-checked={currentRate === rate}\n >\n {rate === 1 ? \"Normal\" : `${rate}×`}\n </button>\n ))}\n </div>\n )}\n\n {hasQuality && tab === \"quality\" && (\n <div>\n <button\n onClick={() => { onQualityChange!(-1); setOpen(false); }}\n className={`settingsOption${currentQualityLevel === -1 ? \" active\" : \"\"}`}\n role=\"menuitemradio\"\n aria-checked={currentQualityLevel === -1}\n >\n Auto {currentQualityLevel === -1 && currentQualityName !== \"Auto\"\n ? `(${currentQualityName})`\n : \"\"}\n </button>\n {sortedLevels.map((level) => (\n <button\n key={level.id}\n onClick={() => { onQualityChange!(level.id); setOpen(false); }}\n className={`settingsOption${currentQualityLevel === level.id ? \" active\" : \"\"}`}\n role=\"menuitemradio\"\n aria-checked={currentQualityLevel === level.id}\n >\n {level.name}\n {level.bitrate > 0 && (\n <span className=\"settingsOptionBadge\">\n {Math.round(level.bitrate / 1000)} kbps\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n );\n});\n\nSettingsMenu.displayName = \"SettingsMenu\";\nexport default SettingsMenu;\n","\"use client\";\n\nimport { memo, useRef, useEffect } from \"react\";\nimport { formatTime } from \"../../lib/format\";\n\nexport interface TimeDisplayProps {\n videoRef: React.RefObject<HTMLMediaElement | null>;\n isLive?: boolean;\n}\n\n/**\n * TimeDisplay subscribes directly to the video element's timeupdate and\n * durationchange events, updating the DOM via refs. It never re-renders\n * during playback — only when isLive changes (once per source change).\n */\nconst TimeDisplay = memo<TimeDisplayProps>(({ videoRef, isLive = false }) => {\n const currentRef = useRef<HTMLSpanElement>(null);\n const durationRef = useRef<HTMLSpanElement>(null);\n\n useEffect(() => {\n const video = videoRef.current;\n if (!video) return;\n\n const updateTime = () => {\n if (currentRef.current)\n currentRef.current.textContent = formatTime(video.currentTime);\n };\n\n const updateDuration = () => {\n if (durationRef.current) {\n const dur = isFinite(video.duration) ? video.duration : 0;\n durationRef.current.textContent = ` / ${formatTime(dur)}`;\n }\n };\n\n video.addEventListener(\"timeupdate\", updateTime);\n video.addEventListener(\"durationchange\", updateDuration);\n video.addEventListener(\"seeked\", updateTime);\n\n updateTime();\n updateDuration();\n\n return () => {\n video.removeEventListener(\"timeupdate\", updateTime);\n video.removeEventListener(\"durationchange\", updateDuration);\n video.removeEventListener(\"seeked\", updateTime);\n };\n }, [videoRef, isLive]);\n\n if (isLive) {\n return (\n <span className=\"timeDisplay\" style={{ opacity: 0.7 }}>\n <span ref={currentRef}>0:00</span>\n </span>\n );\n }\n\n return (\n <span className=\"timeDisplay\">\n <span ref={currentRef}>0:00</span>\n <span ref={durationRef} style={{ opacity: 0.6 }}> / 0:00</span>\n </span>\n );\n});\n\nTimeDisplay.displayName = \"TimeDisplay\";\nexport default TimeDisplay;\n","\"use client\";\n\nimport React, { memo, useEffect, useRef, useState, useCallback, type ReactNode } from \"react\";\nimport type {\n PlaybackRate,\n VideoPlayerRef,\n HLSQualityLevel,\n ControlBarItem,\n} from \"../lib/types\";\nimport { ControlElements } from \"./control-elements\";\n\ninterface ControlsProps {\n videoRef: React.RefObject<HTMLMediaElement | null>;\n playerRef: VideoPlayerRef;\n playerContainerRef: React.RefObject<HTMLElement | null>;\n playbackRates: PlaybackRate[];\n enablePreview: boolean;\n thumbnailVtt?: string;\n isPlaying: boolean;\n volume: number;\n isMuted: boolean;\n playbackRate: number;\n isFullscreen: boolean;\n isPictureInPicture: boolean;\n isTheaterMode: boolean;\n isAudioMode: boolean;\n showAudioButton: boolean;\n audioModeIcon?: ReactNode;\n videoModeIcon?: ReactNode;\n audioModeLabel?: string;\n videoModeLabel?: string;\n isLive: boolean;\n qualityLevels: HLSQualityLevel[];\n currentQualityLevel: number;\n controlBarItems?: ControlBarItem[];\n autoHideControls: boolean;\n}\n\nexport const Controls = memo<ControlsProps>(function Controls({\n videoRef,\n playerRef,\n playerContainerRef,\n playbackRates,\n enablePreview,\n thumbnailVtt,\n isPlaying,\n volume,\n isMuted,\n playbackRate,\n isFullscreen,\n isPictureInPicture,\n isTheaterMode,\n isAudioMode,\n showAudioButton,\n audioModeIcon,\n videoModeIcon,\n audioModeLabel,\n videoModeLabel,\n isLive,\n qualityLevels,\n currentQualityLevel,\n controlBarItems,\n autoHideControls,\n}) {\n const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [showControls, setShowControls] = useState(true);\n\n /**\n * Stable ref capturing the values the keyboard handler needs.\n * isPlaying/volume/isMuted/isLive come from React state (rare changes).\n * currentTime/duration are read directly from the video element so the\n * keyboard shortcuts always see fresh values without subscribing to state.\n */\n const liveRef = useRef({ isPlaying, volume, isMuted, isLive });\n liveRef.current = { isPlaying, volume, isMuted, isLive };\n\n // ─── Auto-hide controls ──────────────────────────────────────────────────\n useEffect(() => {\n // Audio mode or disabled: always show, never hide\n if (isAudioMode || !autoHideControls) {\n setShowControls(true);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n return;\n }\n // Paused: always show\n if (!isPlaying) {\n setShowControls(true);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n return;\n }\n\n // Playing + video mode: show on hover, hide on mouse leave\n const el = playerContainerRef.current;\n if (!el) return;\n\n const handleShow = () => {\n setShowControls(true);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n // Also start a 3s inactivity timer while mouse is inside\n hideTimeoutRef.current = setTimeout(() => setShowControls(false), 3000);\n };\n\n const handleHide = () => {\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n setShowControls(false);\n };\n\n el.addEventListener(\"mousemove\", handleShow);\n el.addEventListener(\"mouseenter\", handleShow);\n el.addEventListener(\"mouseleave\", handleHide);\n el.addEventListener(\"touchstart\", handleShow, { passive: true });\n\n // Start hidden while playing\n setShowControls(false);\n\n return () => {\n el.removeEventListener(\"mousemove\", handleShow);\n el.removeEventListener(\"mouseenter\", handleShow);\n el.removeEventListener(\"mouseleave\", handleHide);\n el.removeEventListener(\"touchstart\", handleShow);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n };\n }, [isPlaying, isAudioMode, autoHideControls, playerContainerRef]);\n\n // ─── Keyboard shortcuts ─────────────────────────────────────────────────\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!playerContainerRef.current?.contains(document.activeElement)) return;\n\n const target = e.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\" || target.isContentEditable) return;\n\n const { isPlaying: playing, volume: vol, isLive: live } = liveRef.current;\n // Read time/duration directly from the video element — always fresh\n const ct = videoRef.current?.currentTime ?? 0;\n const dur = videoRef.current?.duration ?? 0;\n\n switch (e.code) {\n case \"Space\": case \"KeyK\":\n e.preventDefault();\n playing ? playerRef.pause() : playerRef.play();\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n playerRef.seek(Math.max(0, ct - 5));\n break;\n case \"ArrowRight\":\n e.preventDefault();\n playerRef.seek(Math.min(dur || Infinity, ct + 5));\n break;\n case \"ArrowUp\":\n e.preventDefault();\n playerRef.setVolume(Math.min(1, vol + 0.1));\n break;\n case \"ArrowDown\":\n e.preventDefault();\n playerRef.setVolume(Math.max(0, vol - 0.1));\n break;\n case \"KeyM\":\n e.preventDefault();\n playerRef.toggleMute();\n break;\n case \"KeyF\":\n e.preventDefault();\n playerRef.toggleFullscreen();\n break;\n case \"KeyP\":\n e.preventDefault();\n playerRef.togglePictureInPicture();\n break;\n case \"KeyT\":\n e.preventDefault();\n playerRef.toggleTheaterMode();\n break;\n case \"KeyL\":\n e.preventDefault();\n if (live) playerRef.seekToLive();\n break;\n case \"Digit0\": case \"Digit1\": case \"Digit2\": case \"Digit3\": case \"Digit4\":\n case \"Digit5\": case \"Digit6\": case \"Digit7\": case \"Digit8\": case \"Digit9\": {\n e.preventDefault();\n const pct = Number(e.code.replace(\"Digit\", \"\")) * 10;\n playerRef.seek((dur / 100) * pct);\n break;\n }\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [playerRef, playerContainerRef, videoRef]);\n\n // ─── Stable callbacks for child components ───────────────────────────────\n const handlePlay = useCallback(() => playerRef.play(), [playerRef]);\n const handlePause = useCallback(() => playerRef.pause(), [playerRef]);\n const handleVolumeChange = useCallback((v: number) => playerRef.setVolume(v), [playerRef]);\n const handleToggleMute = useCallback(() => playerRef.toggleMute(), [playerRef]);\n const handleRateChange = useCallback((r: PlaybackRate) => playerRef.setPlaybackRate(r), [playerRef]);\n const handleQualityChange = useCallback((l: number) => playerRef.setQualityLevel(l), [playerRef]);\n const handlePiP = useCallback(() => playerRef.togglePictureInPicture(), [playerRef]);\n const handleTheaterToggle = useCallback(() => playerRef.toggleTheaterMode(), [playerRef]);\n const handleAudioToggle = useCallback(() => playerRef.toggleAudioMode(), [playerRef]);\n const handleFullscreen = useCallback(() => playerRef.toggleFullscreen(), [playerRef]);\n const handleSeekToLive = useCallback(() => playerRef.seekToLive(), [playerRef]);\n\n return (\n <div\n style={{\n position: \"absolute\",\n inset: 0,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"flex-end\",\n opacity: showControls ? 1 : 0,\n transition: \"opacity 0.3s\",\n pointerEvents: \"none\",\n zIndex: 2, // must be above the audio overlay (z-index: 1)\n }}\n >\n <div\n style={{\n background: \"linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 60%, transparent 100%)\",\n padding: \"48px 12px 12px\",\n pointerEvents: showControls ? \"auto\" : \"none\",\n }}\n role=\"region\"\n aria-label=\"Video player controls\"\n >\n {/* Progress bar */}\n <ControlElements.ProgressBar\n videoRef={videoRef}\n playerRef={playerRef}\n enablePreview={enablePreview}\n thumbnailVtt={thumbnailVtt}\n />\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 4, marginTop: 4 }}>\n {isPlaying ? (\n <ControlElements.PauseButton onClick={handlePause} />\n ) : (\n <ControlElements.PlayButton onClick={handlePlay} />\n )}\n\n <ControlElements.VolumeControl\n volume={volume}\n isMuted={isMuted}\n onVolumeChange={handleVolumeChange}\n onToggleMute={handleToggleMute}\n />\n\n {/* TimeDisplay — self-subscribes to timeupdate/durationchange on videoRef */}\n <ControlElements.TimeDisplay\n videoRef={videoRef}\n isLive={isLive}\n />\n\n <div style={{ flex: 1 }} />\n\n {isLive && (\n <GoLiveButton onClick={handleSeekToLive} />\n )}\n\n {/* Audio mode toggle — before Settings so it's easy to find */}\n {showAudioButton && (\n <AudioModeButton\n onClick={handleAudioToggle}\n isAudioMode={isAudioMode}\n audioModeIcon={audioModeIcon}\n videoModeIcon={videoModeIcon}\n audioModeLabel={audioModeLabel}\n videoModeLabel={videoModeLabel}\n />\n )}\n\n {/* Settings — speed always shown; quality tab appears for HLS streams */}\n <ControlElements.SettingsMenu\n currentRate={playbackRate}\n playbackRates={playbackRates}\n onRateChange={handleRateChange}\n qualityLevels={qualityLevels}\n currentQualityLevel={currentQualityLevel}\n onQualityChange={handleQualityChange}\n />\n\n {/* Custom control bar items injected by the consumer */}\n {controlBarItems?.map((item) => (\n <button\n key={item.key}\n className=\"controlButton\"\n aria-label={item.label}\n title={item.title ?? item.label}\n onClick={item.onClick}\n >\n {item.icon}\n </button>\n ))}\n <ControlElements.PiPButton onClick={handlePiP} isPiP={isPictureInPicture} />\n <ControlElements.TheaterButton onClick={handleTheaterToggle} isTheater={isTheaterMode} />\n <ControlElements.FullscreenButton onClick={handleFullscreen} isFullscreen={isFullscreen} />\n </div>\n </div>\n </div>\n );\n});\nControls.displayName = \"Controls\";\n\nconst AudioModeButton = memo(({\n onClick,\n isAudioMode,\n audioModeIcon,\n videoModeIcon,\n audioModeLabel,\n videoModeLabel,\n}: {\n onClick: () => void;\n isAudioMode: boolean;\n audioModeIcon?: ReactNode;\n videoModeIcon?: ReactNode;\n audioModeLabel?: string;\n videoModeLabel?: string;\n}) => {\n const label = isAudioMode ? (videoModeLabel ?? \"Video\") : (audioModeLabel ?? \"Audio\");\n const icon = isAudioMode\n ? (videoModeIcon ?? (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z\" />\n </svg>\n ))\n : (audioModeIcon ?? (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M12 3a9 9 0 0 0-9 9v7c0 1.1.9 2 2 2h1a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1H4v-1a8 8 0 0 1 16 0v1h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h1a3 3 0 0 0 3-3v-4c0-4.97-4.03-9-9-9z\" />\n </svg>\n ));\n\n return (\n <button\n onClick={onClick}\n className=\"rvp-audio-toggle-btn\"\n aria-label={label}\n title={label}\n aria-pressed={isAudioMode}\n >\n {icon}\n {label}\n </button>\n );\n});\nAudioModeButton.displayName = \"AudioModeButton\";\n\nconst GoLiveButton = memo(({ onClick }: { onClick: () => void }) => (\n <button\n onClick={onClick}\n style={{\n background: \"none\",\n border: \"1px solid rgba(255,255,255,0.6)\",\n color: \"#fff\",\n borderRadius: 3,\n padding: \"2px 8px\",\n fontSize: 11,\n fontWeight: 700,\n cursor: \"pointer\",\n letterSpacing: \"0.06em\",\n }}\n title=\"Go to live (L)\"\n >\n GO LIVE\n </button>\n));\nGoLiveButton.displayName = \"GoLiveButton\";\n","\"use client\";\n\nimport React, { memo, useEffect, useRef, useState, useCallback } from \"react\";\nimport type { ContextMenuItem, VideoPlayerRef } from \"../lib/types\";\n\ninterface ContextMenuProps {\n x: number;\n y: number;\n isPlaying: boolean;\n src: string;\n videoRef: React.RefObject<HTMLVideoElement | null>;\n playerRef: VideoPlayerRef;\n onClose: () => void;\n contextMenuItems?: ContextMenuItem[];\n}\n\nexport const ContextMenu = memo<ContextMenuProps>(\n ({ x, y, isPlaying, src, videoRef, playerRef, onClose, contextMenuItems }) => {\n const menuRef = useRef<HTMLDivElement>(null);\n const [isLooping, setIsLooping] = useState(\n () => videoRef.current?.loop ?? false,\n );\n\n // Clamp position so menu never overflows the viewport\n const adjustedX = Math.min(x, window.innerWidth - 220);\n const adjustedY = Math.min(y, window.innerHeight - 290);\n\n useEffect(() => {\n const handleMouseDown = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node))\n onClose();\n };\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n const handleScroll = () => onClose();\n\n document.addEventListener(\"mousedown\", handleMouseDown);\n document.addEventListener(\"keydown\", handleKeyDown);\n window.addEventListener(\"scroll\", handleScroll, true);\n return () => {\n document.removeEventListener(\"mousedown\", handleMouseDown);\n document.removeEventListener(\"keydown\", handleKeyDown);\n window.removeEventListener(\"scroll\", handleScroll, true);\n };\n }, [onClose]);\n\n const handlePlayPause = useCallback(() => {\n isPlaying ? playerRef.pause() : playerRef.play();\n onClose();\n }, [isPlaying, playerRef, onClose]);\n\n const handleToggleLoop = useCallback(() => {\n const video = videoRef.current;\n if (!video) return;\n const next = !isLooping;\n video.loop = next;\n setIsLooping(next);\n }, [videoRef, isLooping]);\n\n const handleCopyUrl = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(src);\n } catch {}\n onClose();\n }, [src, onClose]);\n\n const handleCopyTimestamp = useCallback(async () => {\n const time = Math.floor(videoRef.current?.currentTime ?? 0);\n try {\n await navigator.clipboard.writeText(`${src}?t=${time}`);\n } catch {}\n onClose();\n }, [src, videoRef, onClose]);\n\n const handlePiP = useCallback(() => {\n playerRef.togglePictureInPicture();\n onClose();\n }, [playerRef, onClose]);\n\n return (\n <div\n ref={menuRef}\n className=\"contextMenu\"\n style={{ left: adjustedX, top: adjustedY }}\n >\n <button className=\"contextMenuItem\" onClick={handlePlayPause}>\n {isPlaying ? \"Pause\" : \"Play\"}\n </button>\n <button className=\"contextMenuItem\" onClick={handleToggleLoop}>\n <span>Loop</span>\n {isLooping && <span className=\"contextMenuCheck\">✓</span>}\n </button>\n\n <div className=\"contextMenuDivider\" />\n\n <button className=\"contextMenuItem\" onClick={handleCopyUrl}>\n Copy video URL\n </button>\n <button className=\"contextMenuItem\" onClick={handleCopyTimestamp}>\n Copy video URL at current time\n </button>\n\n <div className=\"contextMenuDivider\" />\n\n <button className=\"contextMenuItem\" onClick={handlePiP}>\n Picture-in-Picture\n </button>\n\n {contextMenuItems && contextMenuItems.length > 0 && (\n <>\n <div className=\"contextMenuDivider\" />\n {contextMenuItems.map((item, i) => (\n <button\n key={i}\n className=\"contextMenuItem\"\n onClick={() => { item.onClick(); onClose(); }}\n >\n {item.label}\n </button>\n ))}\n </>\n )}\n </div>\n );\n },\n);\n\nContextMenu.displayName = \"ContextMenu\";\n","\"use client\";\n\nimport React, { memo, type ReactNode } from \"react\";\n\ninterface AudioModeOverlayProps {\n poster?: string;\n logo?: string | ReactNode;\n audioModeFallback?: ReactNode;\n isBuffering?: boolean;\n onOverlayClick?: () => void;\n}\n\nexport const AudioModeOverlay = memo<AudioModeOverlayProps>(function AudioModeOverlay({\n poster,\n logo,\n audioModeFallback,\n isBuffering = false,\n onOverlayClick,\n}) {\n const spinner = isBuffering ? (\n <div className=\"rvp-audio-buffering-overlay\" aria-label=\"Buffering\">\n <div className=\"rvp-audio-spinner\" />\n </div>\n ) : null;\n\n const artwork = (() => {\n if (poster) {\n return (\n <div className=\"rvp-audio-artwork-container\">\n <img src={poster} alt=\"Artwork\" className=\"rvp-audio-artwork\" draggable={false} />\n </div>\n );\n }\n if (audioModeFallback) {\n return <div style={{ display: \"flex\", alignItems: \"center\", justifyContent: \"center\" }}>{audioModeFallback}</div>;\n }\n if (logo) {\n return typeof logo === \"string\"\n ? <img src={logo} alt=\"Logo\" className=\"rvp-audio-logo\" draggable={false} />\n : <div className=\"rvp-audio-logo-node\">{logo as ReactNode}</div>;\n }\n return null;\n })();\n\n return (\n <div className=\"rvp-audio-overlay\" onClick={onOverlayClick} data-test=\"audio-mode-overlay\">\n {artwork}\n <span className=\"rvp-audio-label\">Audio Mode</span>\n {spinner}\n </div>\n );\n});\n\nAudioModeOverlay.displayName = \"AudioModeOverlay\";\n","import type { ReactNode } from \"react\";\nimport type { HlsConfig } from \"hls.js\";\n\n/**\n * Preset bandwidth thresholds (Kbps) for automatic audio mode switching.\n *\n * | Preset | Kbps | Typical connection |\n * |-----------|------|--------------------------------|\n * | EXTREME | 100 | 2G / Edge |\n * | POOR | 300 | Slow 3G |\n * | FAIR | 800 | Marginal 3G ← **recommended** |\n * | GOOD | 1500 | Weak 4G / congested Wi-Fi |\n *\n * Pass any of these (or a custom number) as `audioBandwidthThreshold`.\n * Set to `0` to disable bandwidth-based switching entirely.\n *\n * @example\n * import { AUDIO_BANDWIDTH_THRESHOLDS } from \"react-helios\";\n * <VideoPlayer options={{ audioBandwidthThreshold: AUDIO_BANDWIDTH_THRESHOLDS.FAIR }} />\n */\nexport const AUDIO_BANDWIDTH_THRESHOLDS = {\n /** < 100 Kbps — very poor, 2G / Edge */\n EXTREME: 100,\n /** < 300 Kbps — poor, slow 3G */\n POOR: 300,\n /** < 800 Kbps — marginal 3G ← **recommended default** */\n FAIR: 800,\n /** < 1500 Kbps — weak 4G / congested Wi-Fi */\n GOOD: 1500,\n} as const;\n\n/**\n * Preset HLS quality level indices for automatic audio mode switching.\n *\n * When HLS.js drops to this level or below (due to poor bandwidth), the player\n * automatically switches to audio mode. Level `0` is always the lowest quality\n * available in the manifest.\n *\n * | Preset | Value | Meaning |\n * |----------------|-------|-----------------------------------------------|\n * | LOWEST | 0 | Switch when at the very lowest quality ← **recommended** |\n * | SECOND_LOWEST | 1 | Switch one level above the lowest |\n * | DISABLED | -1 | Disable level-based switching entirely |\n *\n * Works alongside `audioBandwidthThreshold` — whichever fires first wins.\n *\n * @example\n * import { AUDIO_SWITCH_LEVELS } from \"react-helios\";\n * <VideoPlayer options={{ audioModeSwitchLevel: AUDIO_SWITCH_LEVELS.LOWEST }} />\n */\nexport const AUDIO_SWITCH_LEVELS = {\n /** Switch when HLS.js is at the lowest available quality (recommended default). */\n LOWEST: 0,\n /** Switch when HLS.js drops to the second-lowest quality. */\n SECOND_LOWEST: 1,\n /** Disable level-based auto-switching. */\n DISABLED: -1,\n} as const;\n\nexport interface BufferedRange {\n start: number;\n end: number;\n}\n\nexport type VideoErrorCode =\n | \"MEDIA_ERR_ABORTED\"\n | \"MEDIA_ERR_NETWORK\"\n | \"MEDIA_ERR_DECODE\"\n | \"MEDIA_ERR_SRC_NOT_SUPPORTED\"\n | \"HLS_NETWORK_ERROR\"\n | \"HLS_FATAL_ERROR\"\n | \"UNKNOWN\";\n\nexport interface VideoError {\n code: VideoErrorCode;\n message: string;\n}\n\n/** Display name e.g. \"1080p\", \"720p\", \"Auto\" */\nexport interface HLSQualityLevel {\n id: number;\n height: number;\n width: number;\n bitrate: number;\n name: string;\n}\n\nexport interface SubtitleTrack {\n id: string;\n src: string;\n label: string;\n srclang: string;\n default?: boolean;\n}\n\nexport interface PlayerState {\n isPlaying: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n isMuted: boolean;\n playbackRate: number;\n bufferedRanges: BufferedRange[];\n isBuffering: boolean;\n error: VideoError | null;\n isFullscreen: boolean;\n isPictureInPicture: boolean;\n isTheaterMode: boolean;\n /** True when the player is in audio-only mode (video hidden, waveform shown). */\n isAudioMode: boolean;\n isLive: boolean;\n qualityLevels: HLSQualityLevel[];\n currentQualityLevel: number;\n}\n\nexport type PlaybackRate = 0.25 | 0.5 | 0.75 | 1 | 1.25 | 1.5 | 1.75 | 2;\n\nexport interface VideoPlayerRef {\n play: () => Promise<void>;\n pause: () => void;\n seek: (time: number) => void;\n setVolume: (volume: number) => void;\n toggleMute: () => void;\n setPlaybackRate: (rate: PlaybackRate) => void;\n setQualityLevel: (level: number) => void;\n seekToLive: () => void;\n toggleFullscreen: () => Promise<void>;\n togglePictureInPicture: () => Promise<void>;\n toggleTheaterMode: () => void;\n /** Toggle audio-only mode. Can also be triggered programmatically from outside the player. */\n toggleAudioMode: () => void;\n getState: () => PlayerState;\n getVideoElement: () => HTMLVideoElement | null;\n}\n\nexport interface ContextMenuItem {\n label: string;\n onClick: () => void;\n}\n\nexport interface ControlBarItem {\n key: string;\n icon: ReactNode;\n label: string;\n title?: string;\n onClick: () => void;\n}\n\nexport interface VideoPlayerOptions {\n // Playback\n autoplay?: boolean;\n muted?: boolean;\n loop?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n playbackRates?: PlaybackRate[];\n // HLS\n enableHLS?: boolean;\n hlsConfig?: Partial<HlsConfig>;\n // Preview\n enablePreview?: boolean;\n thumbnailVtt?: string;\n // UI\n autoHideControls?: boolean;\n // Subtitles\n subtitles?: SubtitleTrack[];\n crossOrigin?: \"anonymous\" | \"use-credentials\";\n // Audio mode\n logo?: string | ReactNode;\n audioSrc?: string;\n showAudioButton?: boolean;\n audioModeIcon?: ReactNode;\n videoModeIcon?: ReactNode;\n /**\n * Custom content shown in audio mode when no `poster` is provided.\n * Replaces the default animated-gradient + waveform fallback entirely.\n * The `logo` prop is still rendered on top of this if also provided.\n */\n audioModeFallback?: ReactNode;\n /** Label shown next to the icon when in video mode (click → switches to audio). Default: \"Audio\" */\n audioModeLabel?: string;\n /** Label shown next to the icon when in audio mode (click → switches to video). Default: \"Video\" */\n videoModeLabel?: string;\n defaultAudioMode?: boolean;\n /**\n * Kbps — switch to audio mode when rolling average bandwidth drops below this value.\n * `0` disables bandwidth-based switching. Default: `300` (slow 3G).\n * Works alongside `audioModeSwitchLevel` — whichever fires first wins.\n */\n audioBandwidthThreshold?: number;\n /**\n * HLS quality level index — switch to audio mode when HLS.js drops to this level or below.\n * `0` = lowest quality (recommended default). `-1` disables level-based switching.\n * Works alongside `audioBandwidthThreshold` — whichever fires first wins.\n */\n audioModeSwitchLevel?: number;\n /**\n * Milliseconds between automatic recovery probes while in auto-switched audio mode.\n * The player briefly resumes video loading to sample bandwidth, then switches back\n * to video if conditions have improved. Default: `30000` (30 seconds).\n */\n audioModeRecoveryInterval?: number;\n // Callbacks\n onPlay?: () => void;\n onPause?: () => void;\n onEnded?: () => void;\n onError?: (error: VideoError) => void;\n onTimeUpdate?: (time: number) => void;\n onDurationChange?: (duration: number) => void;\n onBuffering?: (isBuffering: boolean) => void;\n onTheaterModeChange?: (isTheater: boolean) => void;\n onAudioModeChange?: (isAudio: boolean) => void;\n // Custom\n contextMenuItems?: ContextMenuItem[];\n controlBarItems?: ControlBarItem[];\n}\n\nexport interface VideoPlayerProps {\n src: string;\n poster?: string;\n className?: string;\n controls?: boolean;\n options?: VideoPlayerOptions;\n}\n\n"]}