react-helios 2.4.0 → 2.5.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.
- package/README.md +177 -71
- package/dist/index.d.mts +34 -52
- package/dist/index.d.ts +34 -52
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +135 -0
- package/package.json +5 -3
- package/dist/index.css +0 -2
- package/dist/index.css.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -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","handleProgress","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","handleMouseEnter","handleMouseLeave","handleMouseDown","handleMouseUp","handleClick","onTouchMove","handleTouchStart","handleTouchMove","handleTouchEnd","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","controlBarItems","hideTimeoutRef","showControls","setShowControls","liveRef","reset","target","playing","handleToggleMute","handleQualityChange","handlePiP","handleTheaterToggle","handleAudioToggle","handleFullscreen","handleSeekToLive","GoLiveButton","item","AudioModeButton","ContextMenu","onClose","contextMenuItems","menuRef","isLooping","setIsLooping","adjustedX","adjustedY","handleScroll","handlePlayPause","handleToggleLoop","handleCopyUrl","handleCopyTimestamp","Fragment","BAR_INDICES","AudioModeOverlay","poster","logo","artworkNode","VideoPlayer","forwardRef","autoplay","muted","loop","controls","preload","className","enableHLS","hlsConfig","subtitles","crossOrigin","defaultAudioMode","audioBandwidthThreshold","onPlay","onPause","onEnded","onError","onTimeUpdate","onDurationChange","onBuffering","onTheaterModeChange","onAudioModeChange","forwardedRef","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 (\n {\n src,\n poster,\n autoplay = false,\n muted = false,\n loop = false,\n controls = true,\n preload = \"metadata\",\n playbackRates = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],\n className,\n enableHLS = true,\n enablePreview = true,\n thumbnailVtt,\n hlsConfig,\n subtitles,\n crossOrigin,\n logo,\n showAudioButton = true,\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 },\n forwardedRef,\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 isPlaying={state.isPlaying}\n />\n )}\n\n {controls && (\n <Controls\n videoRef={videoRef}\n playerRef={playerRef}\n playerContainerRef={containerRef}\n playbackRates={playbackRates}\n enablePreview={enablePreview}\n thumbnailVtt={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}\n isLive={state.isLive}\n qualityLevels={state.qualityLevels}\n currentQualityLevel={state.currentQualityLevel}\n controlBarItems={controlBarItems}\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 <style>{`@keyframes rvp-spin { to { transform: rotate(360deg); } }`}</style>\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 handleProgress = () => {\n // bufferedRanges are NOT stored in React state — ProgressBar subscribes\n // to the video element's progress event directly.\n };\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 video.addEventListener(\"progress\", handleProgress);\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 video.removeEventListener(\"progress\", handleProgress);\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 handleMouseEnter = useCallback(() => {\n showTooltip();\n }, [showTooltip]);\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 const handleMouseUp = useCallback(() => stopDragging(), [stopDragging]);\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 const handleTouchEnd = useCallback(() => stopDragging(), [stopDragging]);\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={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onClick={handleClick}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\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 } 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 isLive: boolean;\n qualityLevels: HLSQualityLevel[];\n currentQualityLevel: number;\n controlBarItems?: ControlBarItem[];\n}\n\nexport const Controls: React.FC<ControlsProps> = ({\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 isLive,\n qualityLevels,\n currentQualityLevel,\n controlBarItems,\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 if (!isPlaying) {\n setShowControls(true);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n return;\n }\n\n const reset = () => {\n setShowControls(true);\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n hideTimeoutRef.current = setTimeout(() => setShowControls(false), 3000);\n };\n\n const el = playerContainerRef.current;\n if (el) {\n el.addEventListener(\"mousemove\", reset);\n el.addEventListener(\"mouseenter\", reset);\n el.addEventListener(\"mouseleave\", () => {\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n });\n el.addEventListener(\"touchstart\", reset, { passive: true });\n }\n reset();\n\n return () => {\n if (el) {\n el.removeEventListener(\"mousemove\", reset);\n el.removeEventListener(\"mouseenter\", reset);\n el.removeEventListener(\"mouseleave\", () => { });\n el.removeEventListener(\"touchstart\", reset);\n }\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n };\n }, [isPlaying, 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 }}\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 — self-subscribes to timeupdate/progress on videoRef */}\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 {/* 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\n {showAudioButton && (\n <AudioModeButton onClick={handleAudioToggle} isAudioMode={isAudioMode} />\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};\n\nconst AudioModeButton = memo(({ onClick, isAudioMode }: { onClick: () => void; isAudioMode: boolean }) => (\n <button\n onClick={onClick}\n className=\"controlButton\"\n aria-label={isAudioMode ? \"Exit audio mode\" : \"Audio only mode\"}\n title={isAudioMode ? \"Exit audio mode\" : \"Audio only mode\"}\n aria-pressed={isAudioMode}\n >\n {isAudioMode ? (\n // Video-camera icon — \"switch back to video\"\n <svg width=\"20\" height=\"20\" 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 // Headphones icon — \"switch to audio\"\n <svg width=\"20\" height=\"20\" 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 </button>\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, { type ReactNode } from \"react\";\nimport \"../styles/AudioMode.css\";\n\n// 20 bars — stagger driven by CSS var(--bar-index) so no JS randomness needed\nconst BAR_INDICES = Array.from({ length: 20 }, (_, i) => i);\n\ninterface AudioModeOverlayProps {\n /** Video poster URL — highest-priority artwork source. */\n poster?: string;\n /**\n * Fallback artwork when no poster is available.\n * - string → rendered as a white-tinted logo image\n * - ReactNode → rendered as-is (coloured white via CSS)\n */\n logo?: string | ReactNode;\n /** Used to pause / resume the waveform animation. */\n isPlaying: boolean;\n}\n\nexport const AudioModeOverlay: React.FC<AudioModeOverlayProps> = ({\n poster,\n logo,\n isPlaying,\n}) => {\n // Resolve artwork node using priority order: poster → logo\n const artworkNode = (() => {\n if (poster) {\n return (\n <img\n src={poster}\n alt=\"Video artwork\"\n className=\"rvp-audio-artwork\"\n draggable={false}\n />\n );\n }\n if (logo) {\n if (typeof logo === \"string\") {\n return (\n <img\n src={logo}\n alt=\"Logo\"\n className=\"rvp-audio-logo\"\n draggable={false}\n />\n );\n }\n return <div className=\"rvp-audio-logo-node\">{logo as ReactNode}</div>;\n }\n return null;\n })();\n\n return (\n <div className=\"rvp-audio-overlay\" data-test=\"audio-mode-overlay\">\n <div className=\"rvp-audio-content\">\n {/* Artwork (optional) */}\n {artworkNode && (\n <div className=\"rvp-audio-artwork-wrapper\">{artworkNode}</div>\n )}\n\n {/* AUDIO ONLY label */}\n <div className=\"rvp-audio-badge\" aria-label=\"Audio only mode\">\n {/* Headphones icon */}\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\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 Audio Only\n </div>\n\n {/* Animated equalizer waveform */}\n <div\n className={`rvp-audio-equalizer${isPlaying ? \" rvp-audio-equalizer--playing\" : \"\"}`}\n aria-hidden=\"true\"\n >\n {BAR_INDICES.map((i) => (\n <div\n key={i}\n className=\"rvp-audio-bar\"\n style={{ \"--bar-index\": i } as React.CSSProperties}\n />\n ))}\n </div>\n </div>\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 VideoPlayerProps {\n src: string;\n poster?: string;\n autoplay?: boolean;\n muted?: boolean;\n loop?: boolean;\n controls?: boolean;\n preload?: \"none\" | \"metadata\" | \"auto\";\n playbackRates?: PlaybackRate[];\n className?: string;\n enableHLS?: boolean;\n enablePreview?: boolean;\n /**\n * URL to a WebVTT thumbnail track for sprite-sheet preview on the progress bar.\n *\n * The VTT file should map time ranges to sprite-sheet coordinates using the\n * standard `#xywh=x,y,w,h` fragment format:\n *\n * ```\n * WEBVTT\n *\n * 00:00:00.000 --> 00:00:05.000\n * https://cdn.example.com/thumbs/storyboard0.jpg#xywh=0,0,160,90\n * ```\n *\n * When provided, hovering the progress bar shows a thumbnail instead of\n * requiring a second video decode. If omitted, only the timestamp tooltip\n * is shown.\n */\n thumbnailVtt?: string;\n hlsConfig?: Partial<HlsConfig>;\n subtitles?: SubtitleTrack[];\n crossOrigin?: \"anonymous\" | \"use-credentials\";\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 /**\n * Image URL or ReactNode shown as artwork in audio mode.\n * Priority: `poster` prop → `logo` string/ReactNode → waveform-only.\n * If a string URL is provided the image is rendered white-normalised (filter invert)\n * so it stands out on the dark background.\n */\n logo?: string | ReactNode;\n /**\n * Show the headphones / audio-mode toggle button in the control bar.\n * @default true\n */\n showAudioButton?: boolean;\n /**\n * Start the player in audio-only mode on mount.\n * @default false\n */\n defaultAudioMode?: boolean;\n /**\n * Bandwidth threshold in **Kbps**. When the measured download speed falls below\n * this value the player automatically switches to audio mode.\n * Use the exported `AUDIO_BANDWIDTH_THRESHOLDS` presets for convenience.\n * Set to `0` to disable automatic switching.\n * Only applies to HLS streams (where hls.js measures real segment bandwidth).\n * @default 300 (AUDIO_BANDWIDTH_THRESHOLDS.POOR)\n */\n audioBandwidthThreshold?: number;\n /** Fired whenever audio mode is toggled — either automatically or by the user. */\n onAudioModeChange?: (isAudio: boolean) => void;\n contextMenuItems?: ContextMenuItem[];\n controlBarItems?: ControlBarItem[];\n}\n\n/** Internal error type used by the HLS module */\nexport interface PlayerError {\n code: string;\n message: string;\n details?: unknown;\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","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"]}
|