react-helios 2.0.1 → 2.1.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 +68 -4
- package/dist/index.d.mts +59 -48
- package/dist/index.d.ts +59 -48
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -2
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +15 -9
- package/dist/styles.d.ts +1 -0
- package/package.json +11 -5
- package/dist/index.css +0 -2
- package/dist/index.css.map +0 -1
package/dist/index.js.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/components/control-elements/progress-bar.tsx","../src/components/control-elements/settings-menu.tsx","../src/components/control-elements/time-display.tsx","../src/components/Controls.tsx"],"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","useEffect","video","prev","opts","HLS","hls","Events","_","data","MAX_RETRIES","delay","err","fatalErr","handlePlay","handlePause","handleEnded","handleTimeUpdate","handleDurationChange","dur","live","handleVolumeChange","vol","handleRateChange","handleError","e","handleWaiting","handleCanPlay","handlePlaying","handleProgress","ranges","handleFullscreenChange","fs","handlePiPChange","play","useCallback","pause","seek","time","setVolume","volume","v","toggleMute","restore","setPlaybackRate","rate","setQualityLevel","level","seekToLive","livePos","toggleFullscreen","container","togglePictureInPicture","getState","getVideoElement","ref","useMemo","control_elements_exports","__export","ControlElements","FullscreenButton","PauseButton","PiPButton","PlayButton","progress_bar_default","settings_menu_default","time_display_default","volume_control_default","memo","onClick","jsx","isFullscreen","isPiP","VolumeControl","isMuted","onVolumeChange","onToggleMute","showSlider","setShowSlider","displayVolume","percentage","sliderBackground","jsxs","ProgressBar","playerRef","currentTime","duration","bufferedRanges","enablePreview","containerRef","previewVideoRef","canvasRef","isDragging","setIsDragging","hoverTime","setHoverTime","hoverPos","setHoverPos","showPreview","setShowPreview","previewLoaded","setPreviewLoaded","updateTimeoutRef","lastSeekTimeRef","rafRef","isDraggingRef","rectCacheRef","invalidate","getRect","mainVideo","previewVideo","videoSrc","onReady","onErr","onTouchMove","updatePreview","canvas","now","drawn","drawFrame","ctx","getTimeFromClientX","clientX","rect","getPxFromClientX","handleKeyDown","step","newTime","handleMouseMove","px","handleMouseEnter","handleMouseLeave","handleMouseDown","handleMouseUp","handleClick","handleTouchStart","handleTouchMove","handleTouchEnd","up","progress","bufferedSegments","range","start","width","SettingsMenu","currentRate","playbackRates","onRateChange","qualityLevels","currentQualityLevel","onQualityChange","open","setOpen","tab","setTab","hasQuality","handler","sortedLevels","a","b","currentQualityName","o","TimeDisplay","isLive","Controls","playerContainerRef","isPlaying","playbackRate","isPictureInPicture","hideTimeoutRef","showControls","setShowControls","liveRef","reset","el","target","playing","ct","pct","handleToggleMute","r","handleQualityChange","handlePiP","handleFullscreen","handleSeekToLive","GoLiveButton","VideoPlayer","forwardRef","poster","autoplay","muted","loop","controls","preload","className","enableHLS","hlsConfig","subtitles","crossOrigin","onPlay","onPause","onEnded","onError","onTimeUpdate","onDurationChange","onBuffering","forwardedRef","React","handleVideoClick","handleDoubleClick","isHLSSrc","track","VideoPlayer_default"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport type { VideoPlayerProps, VideoPlayerRef } from \"../lib/types\";\nimport { useVideoPlayer } from \"../hooks/useVideoPlayer\";\nimport { Controls } from \"./Controls\";\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 hlsConfig,\n subtitles,\n crossOrigin,\n onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n onDurationChange,\n onBuffering,\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 onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n onDurationChange,\n onBuffering,\n },\n );\n\n useEffect(() => {\n fullscreenContainerRef.current = containerRef.current;\n }, [fullscreenContainerRef]);\n\n /**\n * useImperativeHandle only fires once after mount – not 60× per second.\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 /** Precompute once per src change, not on every render */\n const isHLSSrc = useMemo(\n () => enableHLS && !!src && src.toLowerCase().includes(\".m3u8\"),\n [enableHLS, src],\n );\n\n /**\n * Pass FLAT state props to Controls instead of the whole state object.\n * With React.memo on each control sub-component this ensures that\n * buttons / volume / settings only re-render when THEIR props change –\n * not on every timeupdate tick.\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 >\n <video\n ref={videoRef}\n poster={poster}\n preload={preload}\n crossOrigin={crossOrigin}\n onClick={handleVideoClick}\n onDoubleClick={handleDoubleClick}\n playsInline\n style={{ width: \"100%\", height: \"100%\", display: \"block\", cursor: \"pointer\" }}\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 {controls && (\n <Controls\n playerRef={playerRef}\n playerContainerRef={containerRef}\n playbackRates={playbackRates}\n enablePreview={enablePreview && !isHLSSrc}\n isPlaying={state.isPlaying}\n currentTime={state.currentTime}\n duration={state.duration}\n volume={state.volume}\n isMuted={state.isMuted}\n playbackRate={state.playbackRate}\n isFullscreen={state.isFullscreen}\n isPictureInPicture={state.isPictureInPicture}\n isLive={state.isLive}\n qualityLevels={state.qualityLevels}\n currentQualityLevel={state.currentQualityLevel}\n bufferedRanges={state.bufferedRanges}\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 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}\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 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 });\n\n const stateRef = useRef(state);\n stateRef.current = state;\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 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 }));\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 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 };\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 // Only notify external callback – internal state is updated but\n // onTimeUpdate is called outside setState to avoid extra renders.\n setState((prev) => ({ ...prev, currentTime: video.currentTime }));\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 const ranges: Array<{ start: number; end: number }> = [];\n for (let i = 0; i < video.buffered.length; i++) {\n ranges.push({\n start: video.buffered.start(i),\n end: video.buffered.end(i),\n });\n }\n setState((prev) => ({ ...prev, bufferedRanges: ranges }));\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 /**\n * getState reads from stateRef so it doesn't need `state` in its deps.\n * This keeps it stable (same function reference) across all renders,\n * which in turn keeps the VideoPlayerRef object stable (via useMemo).\n */\n const getState = useCallback(\n (): PlayerState => ({ ...stateRef.current }),\n [],\n );\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 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 getState,\n getVideoElement,\n ],\n );\n\n return { state, ref, hlsRef, fullscreenContainerRef };\n}\n","import {\n PlayButton,\n PauseButton,\n FullscreenButton,\n PiPButton,\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} 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} 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 VolumeControl,\n ProgressBar,\n SettingsMenu,\n TimeDisplay,\n};\n","\"use client\";\n\nimport { memo } from \"react\";\nimport \"../../styles/ControlElements.css\";\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\n/**\n * All button components are wrapped in React.memo.\n * They receive stable callback refs (useCallback in Controls), so they\n * only re-render when their specific props (isFullscreen, isPiP, etc.)\n * actually change – not on every timeupdate tick.\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 default { PlayButton, PauseButton, FullscreenButton, PiPButton };\n","\"use client\";\n\nimport { memo, useState, useMemo } from \"react\";\nimport \"../../styles/ControlElements.css\";\n\nexport interface VolumeControlProps {\n volume: number;\n isMuted: boolean;\n onVolumeChange: (volume: number) => void;\n onToggleMute: () => void;\n}\n\n/**\n * VolumeControl wrapped in React.memo.\n * volume and isMuted don't change during timeupdate → 0 re-renders during\n * normal playback when the user isn't touching volume controls.\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 /**\n * Memoize the gradient background string so it's not recreated on every\n * render of the parent that happens to pass the same volume value.\n * This is a micro-optimisation but relevant because the gradient string\n * is computed on every slider render.\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","\"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 \"../../styles/ProgressBar.css\";\n\nexport interface ProgressBarProps {\n playerRef: VideoPlayerRef;\n currentTime: number;\n duration: number;\n bufferedRanges: BufferedRange[];\n enablePreview?: boolean;\n}\n\nconst ProgressBar: React.FC<ProgressBarProps> = memo(({\n playerRef,\n currentTime,\n duration,\n bufferedRanges,\n enablePreview = true,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const previewVideoRef = useRef<HTMLVideoElement>(null);\n const canvasRef = useRef<HTMLCanvasElement>(null);\n\n const [isDragging, setIsDragging] = useState(false);\n const [hoverTime, setHoverTime] = useState(0);\n const [hoverPos, setHoverPos] = useState(0);\n const [showPreview, setShowPreview] = useState(false);\n const [previewLoaded, setPreviewLoaded] = useState(false);\n\n const updateTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastSeekTimeRef = useRef<number>(0);\n const rafRef = useRef<number | null>(null);\n const isDraggingRef = useRef(false);\n isDraggingRef.current = isDragging;\n\n /**\n * Cache the bounding rect so mouse-move doesn't trigger layout reflow\n * on every pixel. Invalidated whenever the window is resized.\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 // ─── Preview video setup ────────────────────────────────────────────────\n useEffect(() => {\n if (!enablePreview) return;\n\n const mainVideo = playerRef.getVideoElement();\n const previewVideo = previewVideoRef.current;\n if (!mainVideo || !previewVideo) return;\n\n const videoSrc = mainVideo.currentSrc || mainVideo.src;\n if (!videoSrc) return;\n\n previewVideo.src = videoSrc;\n previewVideo.muted = true;\n previewVideo.preload = \"auto\";\n previewVideo.crossOrigin = mainVideo.crossOrigin;\n\n const onReady = () => setPreviewLoaded(true);\n const onErr = () => { console.warn(\"[preview] failed to load\"); setPreviewLoaded(false); };\n\n previewVideo.addEventListener(\"loadedmetadata\", onReady);\n previewVideo.addEventListener(\"loadeddata\", onReady);\n previewVideo.addEventListener(\"error\", onErr);\n\n return () => {\n previewVideo.removeEventListener(\"loadedmetadata\", onReady);\n previewVideo.removeEventListener(\"loadeddata\", onReady);\n previewVideo.removeEventListener(\"error\", onErr);\n previewVideo.removeAttribute(\"src\");\n previewVideo.load();\n setPreviewLoaded(false);\n };\n }, [playerRef, enablePreview]);\n\n\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 // ─── Draw preview frame ─────────────────────────────────────────────────\n const updatePreview = useCallback((time: number) => {\n if (!enablePreview || !previewLoaded) return;\n\n const previewVideo = previewVideoRef.current;\n const canvas = canvasRef.current;\n if (!previewVideo || !canvas) return;\n\n // Throttle to ~10 seeks/s\n const now = Date.now();\n if (now - lastSeekTimeRef.current < 100) return;\n lastSeekTimeRef.current = now;\n\n if (updateTimeoutRef.current) clearTimeout(updateTimeoutRef.current);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n\n let drawn = false;\n\n const drawFrame = () => {\n if (drawn) return;\n if (previewVideo.readyState >= 2) {\n drawn = true;\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n rafRef.current = requestAnimationFrame(() => {\n const ctx = canvas.getContext(\"2d\", { alpha: false, willReadFrequently: false });\n if (!ctx) return;\n canvas.width = 160;\n canvas.height = 90;\n ctx.drawImage(previewVideo, 0, 0, 160, 90);\n });\n }\n };\n\n previewVideo.currentTime = time;\n previewVideo.addEventListener(\"seeked\", drawFrame, { once: true });\n\n updateTimeoutRef.current = setTimeout(() => {\n if (!drawn) drawFrame();\n }, 200);\n }, [enablePreview, previewLoaded]);\n\n // ─── Geometry helpers (no layout thrash) ───────────────────────────────\n const getTimeFromClientX = useCallback((clientX: number): number => {\n const rect = getRect();\n if (!rect || rect.width === 0) return 0;\n const pos = Math.max(0, Math.min(clientX - rect.left, rect.width));\n return (pos / rect.width) * duration;\n }, [getRect, duration]);\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\n const handleKeyDown = useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {\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 const newTime = e.key === \"ArrowLeft\"\n ? Math.max(0, currentTime - step)\n : Math.min(duration || 0, currentTime + step);\n playerRef.seek(newTime);\n break;\n }\n case \"Home\":\n e.preventDefault();\n e.nativeEvent.stopImmediatePropagation();\n playerRef.seek(0);\n break;\n case \"End\":\n if (duration > 0) {\n e.preventDefault();\n e.nativeEvent.stopImmediatePropagation();\n playerRef.seek(duration);\n }\n break;\n }\n }, [currentTime, duration, playerRef]);\n\n // ─── Mouse / touch handlers ─────────────────────────────────────────────\n const handleMouseMove = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n const time = getTimeFromClientX(e.clientX);\n const px = getPxFromClientX(e.clientX);\n setHoverTime(time);\n setHoverPos(px);\n\n if (isDragging) {\n playerRef.seek(time);\n } else if (enablePreview && previewLoaded) {\n updatePreview(time);\n }\n }, [isDragging, enablePreview, previewLoaded, playerRef, updatePreview, getTimeFromClientX, getPxFromClientX]);\n\n const handleMouseEnter = useCallback(() => {\n rectCacheRef.current = null;\n setShowPreview(true);\n }, []);\n\n const handleMouseLeave = useCallback(() => {\n setShowPreview(false);\n setIsDragging(false);\n }, []);\n\n const handleMouseDown = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n setIsDragging(true);\n playerRef.seek(getTimeFromClientX(e.clientX));\n }, [getTimeFromClientX, playerRef]);\n\n const handleMouseUp = useCallback(() => setIsDragging(false), []);\n\n const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {\n if (!isDragging) playerRef.seek(getTimeFromClientX(e.clientX));\n }, [isDragging, getTimeFromClientX, playerRef]);\n\n\n const handleTouchStart = useCallback((e: React.TouchEvent<HTMLDivElement>) => {\n rectCacheRef.current = null;\n setIsDragging(true);\n playerRef.seek(getTimeFromClientX(e.touches[0].clientX));\n }, [getTimeFromClientX, playerRef]);\n\n const handleTouchMove = useCallback((e: React.TouchEvent<HTMLDivElement>) => {\n if (!isDragging) return;\n playerRef.seek(getTimeFromClientX(e.touches[0].clientX));\n }, [isDragging, getTimeFromClientX, playerRef]);\n\n const handleTouchEnd = useCallback(() => setIsDragging(false), []);\n\n useEffect(() => {\n const up = () => setIsDragging(false);\n window.addEventListener(\"mouseup\", up);\n return () => window.removeEventListener(\"mouseup\", up);\n }, []);\n\n // Cleanup\n useEffect(() => {\n return () => {\n if (updateTimeoutRef.current) clearTimeout(updateTimeoutRef.current);\n if (rafRef.current) cancelAnimationFrame(rafRef.current);\n };\n }, []);\n\n const progress = duration > 0 ? (currentTime / duration) * 100 : 0;\n\n const bufferedSegments = useMemo(() => {\n if (duration <= 0) return null;\n return bufferedRanges.map((range, i) => {\n const start = (range.start / duration) * 100;\n const width = ((range.end - range.start) / duration) * 100;\n return (\n <div\n key={i}\n className=\"bufferedSegment\"\n style={{ left: `${start}%`, width: `${width}%` }}\n />\n );\n });\n }, [bufferedRanges, duration]);\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={Math.round(duration)}\n aria-valuenow={Math.round(currentTime)}\n aria-valuetext={formatTime(currentTime)}\n tabIndex={0}\n >\n {/* Hidden preview video */}\n {enablePreview && (\n <video ref={previewVideoRef} className=\"previewVideo\" playsInline muted preload=\"auto\" aria-hidden=\"true\" />\n )}\n\n {/* Preview thumbnail tooltip */}\n {enablePreview && showPreview && previewLoaded && (\n <div className=\"previewTooltip\" style={{ left: hoverPos }} aria-hidden=\"true\">\n <canvas ref={canvasRef} className=\"previewCanvas\" />\n <div className=\"previewTime\">{formatTime(hoverTime)}</div>\n </div>\n )}\n\n {/* Track background (overflow:hidden – keeps buffered/filled bars clipped) */}\n <div className=\"progressBackground\">\n {bufferedSegments}\n <div className=\"progressFilled\" style={{ width: `${progress}%` }} />\n {showPreview && (\n <div className=\"hoverIndicator\" style={{ left: hoverPos }} aria-hidden=\"true\" />\n )}\n </div>\n\n\n <div\n className={`scrubHandle${isDragging ? \" dragging\" : \"\"}`}\n style={{ left: `${progress}%` }}\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\";\nimport \"../../styles/ControlElements.css\";\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\n/**\n * SettingsMenu wrapped in React.memo.\n * playbackRate and qualityLevel rarely change → this component skips\n * almost all re-renders during normal playback.\n *\n * sortedLevels is memoized so the .sort() only runs when qualityLevels\n * actually changes (usually once after manifest is parsed).\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 – not on every render.\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 } from \"react\";\nimport { formatTime } from \"../../lib/format\";\nimport \"../../styles/ControlElements.css\";\n\nexport interface TimeDisplayProps {\n currentTime: number;\n duration: number;\n isLive?: boolean;\n}\n\n/**\n * TimeDisplay re-renders every timeupdate tick (currentTime changes).\n * Wrapped in memo anyway so that if its specific props haven't changed\n * (e.g. when only volume changes) it skips the render.\n */\nconst TimeDisplay = memo<TimeDisplayProps>(({ currentTime, duration, isLive = false }) => {\n if (isLive) {\n return (\n <span className=\"timeDisplay\" style={{ opacity: 0.7 }}>\n {formatTime(currentTime)}\n </span>\n );\n }\n return (\n <span className=\"timeDisplay\">\n {formatTime(currentTime)}\n <span style={{ opacity: 0.6 }}> / {formatTime(duration)}</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 BufferedRange,\n} from \"../lib/types\";\nimport { ControlElements } from \"./control-elements\";\n\ninterface ControlsProps {\n playerRef: VideoPlayerRef;\n /** Ref to the outer player container; used to scope keyboard shortcuts to the focused player */\n playerContainerRef: React.RefObject<HTMLElement | null>;\n playbackRates: PlaybackRate[];\n enablePreview: boolean;\n isPlaying: boolean;\n currentTime: number;\n duration: number;\n volume: number;\n isMuted: boolean;\n playbackRate: number;\n isFullscreen: boolean;\n isPictureInPicture: boolean;\n isLive: boolean;\n qualityLevels: HLSQualityLevel[];\n currentQualityLevel: number;\n bufferedRanges: BufferedRange[];\n}\n\n/**\n * Controls is intentionally NOT wrapped in React.memo here – it receives\n * currentTime which changes every tick, so memo wouldn't help at this level.\n * Instead, all its CHILDREN are memoized so they skip renders when their\n * specific props haven't changed.\n */\nexport const Controls: React.FC<ControlsProps> = ({\n playerRef,\n playerContainerRef,\n playbackRates,\n enablePreview,\n isPlaying,\n currentTime,\n duration,\n volume,\n isMuted,\n playbackRate,\n isFullscreen,\n isPictureInPicture,\n isLive,\n qualityLevels,\n currentQualityLevel,\n bufferedRanges,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const hideTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const [showControls, setShowControls] = useState(true);\n\n /**\n * A ref that always holds the latest state values.\n * The keyboard handler reads from this ref so the effect only needs\n * playerRef as a dependency – it NEVER re-registers on every timeupdate.\n *\n */\n const liveRef = useRef({\n isPlaying, currentTime, duration, volume, isMuted, isLive,\n });\n liveRef.current = { isPlaying, currentTime, duration, 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 = containerRef.current;\n if (el) {\n el.addEventListener(\"mousemove\", reset);\n el.addEventListener(\"mouseenter\", reset);\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(\"touchstart\", reset);\n }\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n };\n }, [isPlaying]);\n\n // ─── Keyboard shortcuts ─────────────────────────────────────────────────\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n // Only handle keyboard events when this player container has focus,\n // preventing shortcuts from firing on all players simultaneously.\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 // Read latest values from the ref – no state in closure\n const { isPlaying: playing, currentTime: ct, duration: dur, volume: vol, isLive: live } = liveRef.current;\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 \"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]); // ← state read via liveRef; container ref for focus check\n\n // ─── Stable callbacks for child components ───────────────────────────────\n // These are memoized so child React.memo components don't re-render due\n // to new function references on every render.\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 handleFullscreen = useCallback(() => playerRef.toggleFullscreen(), [playerRef]);\n const handleSeekToLive = useCallback(() => playerRef.seekToLive(), [playerRef]);\n\n return (\n <div\n ref={containerRef}\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: showControls ? \"auto\" : \"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 }}\n role=\"region\"\n aria-label=\"Video player controls\"\n >\n {/* Progress bar – re-renders on every tick, intentionally */}\n <ControlElements.ProgressBar\n playerRef={playerRef}\n currentTime={currentTime}\n duration={duration}\n bufferedRanges={bufferedRanges}\n enablePreview={enablePreview}\n />\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 4, marginTop: 4 }}>\n {/* Play/Pause – memoized; only re-renders when isPlaying changes */}\n {isPlaying ? (\n <ControlElements.PauseButton onClick={handlePause} />\n ) : (\n <ControlElements.PlayButton onClick={handlePlay} />\n )}\n\n {/* Volume – memoized; skips timeupdate renders */}\n <ControlElements.VolumeControl\n volume={volume}\n isMuted={isMuted}\n onVolumeChange={handleVolumeChange}\n onToggleMute={handleToggleMute}\n />\n\n {/* Time – re-renders on every tick (needs currentTime) */}\n <ControlElements.TimeDisplay\n currentTime={currentTime}\n duration={duration}\n isLive={isLive}\n />\n\n <div style={{ flex: 1 }} />\n\n {/* GO LIVE – memoized; only shown for live streams */}\n {isLive && (\n <GoLiveButton onClick={handleSeekToLive} />\n )}\n\n {/* Settings – memoized; skips timeupdate renders */}\n <ControlElements.SettingsMenu\n currentRate={playbackRate}\n playbackRates={playbackRates}\n onRateChange={handleRateChange}\n qualityLevels={qualityLevels}\n currentQualityLevel={currentQualityLevel}\n onQualityChange={handleQualityChange}\n />\n\n {/* PiP */}\n <ControlElements.PiPButton onClick={handlePiP} isPiP={isPictureInPicture} />\n\n {/* Fullscreen */}\n <ControlElements.FullscreenButton onClick={handleFullscreen} isFullscreen={isFullscreen} />\n </div>\n </div>\n </div>\n );\n};\n\n/**\n * GO LIVE button – only rendered for live streams.\n * Stable onClick prop (useCallback in parent) prevents unnecessary re-renders.\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"]}
|
|
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"],"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","useEffect","video","prev","opts","HLS","hls","Events","_","data","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","v","toggleMute","restore","setPlaybackRate","rate","setQualityLevel","level","seekToLive","livePos","toggleFullscreen","container","togglePictureInPicture","getState","currentTime","bufferedRanges","getVideoElement","ref","useMemo","control_elements_exports","__export","ControlElements","FullscreenButton","PauseButton","PiPButton","PlayButton","progress_bar_default","settings_menu_default","time_display_default","volume_control_default","memo","onClick","jsx","isFullscreen","isPiP","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","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","hideTimeoutRef","showControls","setShowControls","liveRef","reset","target","playing","handleToggleMute","handleQualityChange","handlePiP","handleFullscreen","handleSeekToLive","GoLiveButton","VideoPlayer","forwardRef","poster","autoplay","muted","loop","controls","preload","className","enableHLS","hlsConfig","subtitles","crossOrigin","onPlay","onPause","onEnded","onError","onTimeUpdate","onDurationChange","onBuffering","forwardedRef","React","handleVideoClick","handleDoubleClick","track","VideoPlayer_default"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport React, { forwardRef, useEffect, useRef, useCallback } from \"react\";\nimport type { VideoPlayerProps, VideoPlayerRef } from \"../lib/types\";\nimport { useVideoPlayer } from \"../hooks/useVideoPlayer\";\nimport { Controls } from \"./Controls\";\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 onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n onDurationChange,\n onBuffering,\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 onPlay,\n onPause,\n onEnded,\n onError,\n onTimeUpdate,\n onDurationChange,\n onBuffering,\n },\n );\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\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 >\n <video\n ref={videoRef}\n poster={poster}\n preload={preload}\n crossOrigin={crossOrigin}\n onClick={handleVideoClick}\n onDoubleClick={handleDoubleClick}\n playsInline\n style={{ width: \"100%\", height: \"100%\", display: \"block\", cursor: \"pointer\" }}\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 {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 isLive={state.isLive}\n qualityLevels={state.qualityLevels}\n currentQualityLevel={state.currentQualityLevel}\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 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}\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 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 });\n\n const stateRef = useRef(state);\n stateRef.current = state;\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 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 }));\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 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 };\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 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 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 getState,\n getVideoElement,\n ],\n );\n\n return { state, ref, hlsRef, fullscreenContainerRef };\n}\n","import {\n PlayButton,\n PauseButton,\n FullscreenButton,\n PiPButton,\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} 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} 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 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 default { PlayButton, PauseButton, FullscreenButton, PiPButton };\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 = \"\";\n if (hoverIndicatorRef.current) hoverIndicatorRef.current.style.display = \"\";\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 // Update tooltip position and time text imperatively\n if (tooltipRef.current) tooltipRef.current.style.left = `${px}px`;\n if (hoverIndicatorRef.current) hoverIndicatorRef.current.style.left = `${px}px`;\n if (hoverTimeTextRef.current) hoverTimeTextRef.current.textContent = formatTime(time);\n\n applyThumbnail(time);\n\n if (isDraggingRef.current) playerRef.seek(time);\n }, [playerRef, applyThumbnail, getTimeFromClientX, getPxFromClientX]);\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} 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 isLive: boolean;\n qualityLevels: HLSQualityLevel[];\n currentQualityLevel: number;\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 isLive,\n qualityLevels,\n currentQualityLevel,\n}) => {\n const containerRef = useRef<HTMLDivElement>(null);\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 = containerRef.current;\n if (el) {\n el.addEventListener(\"mousemove\", reset);\n el.addEventListener(\"mouseenter\", reset);\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(\"touchstart\", reset);\n }\n if (hideTimeoutRef.current) clearTimeout(hideTimeoutRef.current);\n };\n }, [isPlaying]);\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 \"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 handleFullscreen = useCallback(() => playerRef.toggleFullscreen(), [playerRef]);\n const handleSeekToLive = useCallback(() => playerRef.seekToLive(), [playerRef]);\n\n return (\n <div\n ref={containerRef}\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: showControls ? \"auto\" : \"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 }}\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 <ControlElements.SettingsMenu\n currentRate={playbackRate}\n playbackRates={playbackRates}\n onRateChange={handleRateChange}\n qualityLevels={qualityLevels}\n currentQualityLevel={currentQualityLevel}\n onQualityChange={handleQualityChange}\n />\n\n <ControlElements.PiPButton onClick={handlePiP} isPiP={isPictureInPicture} />\n <ControlElements.FullscreenButton onClick={handleFullscreen} isFullscreen={isFullscreen} />\n </div>\n </div>\n </div>\n );\n};\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"]}
|