react-helios 2.1.0 → 2.2.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 CHANGED
@@ -109,6 +109,24 @@ To disable the preview entirely:
109
109
  | `onTimeUpdate` | `(time: number) => void` | — | Fired every ~250 ms during playback |
110
110
  | `onDurationChange` | `(duration: number) => void` | — | Fired when video duration becomes known |
111
111
  | `onBuffering` | `(isBuffering: boolean) => void` | — | Fired when buffering starts / stops |
112
+ | `contextMenuItems` | `ContextMenuItem[]` | — | Extra items appended to the right-click context menu |
113
+
114
+ ## Context Menu
115
+
116
+ Right-clicking the player shows a built-in menu (Play/Pause, Loop, Copy URL, Picture-in-Picture). You can append your own items by passing `contextMenuItems`:
117
+
118
+ ```tsx
119
+ import { VideoPlayer, ContextMenuItem } from "react-helios";
120
+
121
+ const items: ContextMenuItem[] = [
122
+ { label: "Add to Watchlist", onClick: () => addToWatchlist() },
123
+ { label: "Share", onClick: () => openShareDialog() },
124
+ ];
125
+
126
+ <VideoPlayer src="..." contextMenuItems={items} />
127
+ ```
128
+
129
+ Each item closes the menu automatically after its `onClick` is called.
112
130
 
113
131
  ## Imperative API (Ref)
114
132
 
@@ -203,6 +221,7 @@ import type {
203
221
  VideoError,
204
222
  VideoErrorCode,
205
223
  ThumbnailCue,
224
+ ContextMenuItem,
206
225
  } from "react-helios";
207
226
 
208
227
  // VTT utilities (useful for server-side pre-parsing or custom UIs)
package/dist/index.d.mts CHANGED
@@ -38,6 +38,7 @@ interface PlayerState {
38
38
  error: VideoError | null;
39
39
  isFullscreen: boolean;
40
40
  isPictureInPicture: boolean;
41
+ isTheaterMode: boolean;
41
42
  isLive: boolean;
42
43
  qualityLevels: HLSQualityLevel[];
43
44
  currentQualityLevel: number;
@@ -54,9 +55,14 @@ interface VideoPlayerRef {
54
55
  seekToLive: () => void;
55
56
  toggleFullscreen: () => Promise<void>;
56
57
  togglePictureInPicture: () => Promise<void>;
58
+ toggleTheaterMode: () => void;
57
59
  getState: () => PlayerState;
58
60
  getVideoElement: () => HTMLVideoElement | null;
59
61
  }
62
+ interface ContextMenuItem {
63
+ label: string;
64
+ onClick: () => void;
65
+ }
60
66
  interface VideoPlayerProps {
61
67
  src: string;
62
68
  poster?: string;
@@ -97,6 +103,8 @@ interface VideoPlayerProps {
97
103
  onTimeUpdate?: (time: number) => void;
98
104
  onDurationChange?: (duration: number) => void;
99
105
  onBuffering?: (isBuffering: boolean) => void;
106
+ onTheaterModeChange?: (isTheater: boolean) => void;
107
+ contextMenuItems?: ContextMenuItem[];
100
108
  }
101
109
 
102
110
  declare const VideoPlayer: react__default.ForwardRefExoticComponent<VideoPlayerProps & react__default.RefAttributes<VideoPlayerRef>>;
@@ -114,6 +122,7 @@ interface ControlsProps {
114
122
  playbackRate: number;
115
123
  isFullscreen: boolean;
116
124
  isPictureInPicture: boolean;
125
+ isTheaterMode: boolean;
117
126
  isLive: boolean;
118
127
  qualityLevels: HLSQualityLevel[];
119
128
  currentQualityLevel: number;
@@ -175,12 +184,18 @@ declare const PlayButton: react.NamedExoticComponent<PlayButtonProps>;
175
184
  declare const PauseButton: react.NamedExoticComponent<PauseButtonProps>;
176
185
  declare const FullscreenButton: react.NamedExoticComponent<FullscreenButtonProps>;
177
186
  declare const PiPButton: react.NamedExoticComponent<PiPButtonProps>;
187
+ interface TheaterButtonProps {
188
+ onClick: () => void;
189
+ isTheater?: boolean;
190
+ }
191
+ declare const TheaterButton: react.NamedExoticComponent<TheaterButtonProps>;
178
192
 
179
193
  declare const ControlElements: {
180
194
  PlayButton: react.NamedExoticComponent<PlayButtonProps>;
181
195
  PauseButton: react.NamedExoticComponent<PauseButtonProps>;
182
196
  FullscreenButton: react.NamedExoticComponent<FullscreenButtonProps>;
183
197
  PiPButton: react.NamedExoticComponent<PiPButtonProps>;
198
+ TheaterButton: react.NamedExoticComponent<TheaterButtonProps>;
184
199
  VolumeControl: react.NamedExoticComponent<VolumeControlProps>;
185
200
  ProgressBar: react.FC<ProgressBarProps>;
186
201
  SettingsMenu: react.NamedExoticComponent<SettingsMenuProps>;
@@ -200,12 +215,14 @@ declare const index_ProgressBar: typeof ProgressBar;
200
215
  type index_ProgressBarProps = ProgressBarProps;
201
216
  declare const index_SettingsMenu: typeof SettingsMenu;
202
217
  type index_SettingsMenuProps = SettingsMenuProps;
218
+ declare const index_TheaterButton: typeof TheaterButton;
219
+ type index_TheaterButtonProps = TheaterButtonProps;
203
220
  declare const index_TimeDisplay: typeof TimeDisplay;
204
221
  type index_TimeDisplayProps = TimeDisplayProps;
205
222
  declare const index_VolumeControl: typeof VolumeControl;
206
223
  type index_VolumeControlProps = VolumeControlProps;
207
224
  declare namespace index {
208
- export { index_ControlElements as ControlElements, index_FullscreenButton as FullscreenButton, type index_FullscreenButtonProps as FullscreenButtonProps, index_PauseButton as PauseButton, type index_PauseButtonProps as PauseButtonProps, index_PiPButton as PiPButton, type index_PiPButtonProps as PiPButtonProps, index_PlayButton as PlayButton, type index_PlayButtonProps as PlayButtonProps, index_ProgressBar as ProgressBar, type index_ProgressBarProps as ProgressBarProps, index_SettingsMenu as SettingsMenu, type index_SettingsMenuProps as SettingsMenuProps, index_TimeDisplay as TimeDisplay, type index_TimeDisplayProps as TimeDisplayProps, index_VolumeControl as VolumeControl, type index_VolumeControlProps as VolumeControlProps };
225
+ export { index_ControlElements as ControlElements, index_FullscreenButton as FullscreenButton, type index_FullscreenButtonProps as FullscreenButtonProps, index_PauseButton as PauseButton, type index_PauseButtonProps as PauseButtonProps, index_PiPButton as PiPButton, type index_PiPButtonProps as PiPButtonProps, index_PlayButton as PlayButton, type index_PlayButtonProps as PlayButtonProps, index_ProgressBar as ProgressBar, type index_ProgressBarProps as ProgressBarProps, index_SettingsMenu as SettingsMenu, type index_SettingsMenuProps as SettingsMenuProps, index_TheaterButton as TheaterButton, type index_TheaterButtonProps as TheaterButtonProps, index_TimeDisplay as TimeDisplay, type index_TimeDisplayProps as TimeDisplayProps, index_VolumeControl as VolumeControl, type index_VolumeControlProps as VolumeControlProps };
209
226
  }
210
227
 
211
228
  /**
@@ -252,4 +269,4 @@ declare function parseThumbnailVtt(text: string, baseUrl?: string): ThumbnailCue
252
269
  */
253
270
  declare function findThumbnailCue(cues: ThumbnailCue[], time: number): ThumbnailCue | null;
254
271
 
255
- export { type BufferedRange, index as ControlElements, Controls, type HLSQualityLevel, type PlaybackRate, type PlayerState, type SubtitleTrack, type ThumbnailCue, type VideoError, type VideoErrorCode, VideoPlayer, type VideoPlayerProps, type VideoPlayerRef, findThumbnailCue, formatTime, getMimeType, isHLSUrl, parseThumbnailVtt };
272
+ export { type BufferedRange, type ContextMenuItem, index as ControlElements, Controls, type HLSQualityLevel, type PlaybackRate, type PlayerState, type SubtitleTrack, type ThumbnailCue, type VideoError, type VideoErrorCode, VideoPlayer, type VideoPlayerProps, type VideoPlayerRef, findThumbnailCue, formatTime, getMimeType, isHLSUrl, parseThumbnailVtt };
package/dist/index.d.ts CHANGED
@@ -38,6 +38,7 @@ interface PlayerState {
38
38
  error: VideoError | null;
39
39
  isFullscreen: boolean;
40
40
  isPictureInPicture: boolean;
41
+ isTheaterMode: boolean;
41
42
  isLive: boolean;
42
43
  qualityLevels: HLSQualityLevel[];
43
44
  currentQualityLevel: number;
@@ -54,9 +55,14 @@ interface VideoPlayerRef {
54
55
  seekToLive: () => void;
55
56
  toggleFullscreen: () => Promise<void>;
56
57
  togglePictureInPicture: () => Promise<void>;
58
+ toggleTheaterMode: () => void;
57
59
  getState: () => PlayerState;
58
60
  getVideoElement: () => HTMLVideoElement | null;
59
61
  }
62
+ interface ContextMenuItem {
63
+ label: string;
64
+ onClick: () => void;
65
+ }
60
66
  interface VideoPlayerProps {
61
67
  src: string;
62
68
  poster?: string;
@@ -97,6 +103,8 @@ interface VideoPlayerProps {
97
103
  onTimeUpdate?: (time: number) => void;
98
104
  onDurationChange?: (duration: number) => void;
99
105
  onBuffering?: (isBuffering: boolean) => void;
106
+ onTheaterModeChange?: (isTheater: boolean) => void;
107
+ contextMenuItems?: ContextMenuItem[];
100
108
  }
101
109
 
102
110
  declare const VideoPlayer: react__default.ForwardRefExoticComponent<VideoPlayerProps & react__default.RefAttributes<VideoPlayerRef>>;
@@ -114,6 +122,7 @@ interface ControlsProps {
114
122
  playbackRate: number;
115
123
  isFullscreen: boolean;
116
124
  isPictureInPicture: boolean;
125
+ isTheaterMode: boolean;
117
126
  isLive: boolean;
118
127
  qualityLevels: HLSQualityLevel[];
119
128
  currentQualityLevel: number;
@@ -175,12 +184,18 @@ declare const PlayButton: react.NamedExoticComponent<PlayButtonProps>;
175
184
  declare const PauseButton: react.NamedExoticComponent<PauseButtonProps>;
176
185
  declare const FullscreenButton: react.NamedExoticComponent<FullscreenButtonProps>;
177
186
  declare const PiPButton: react.NamedExoticComponent<PiPButtonProps>;
187
+ interface TheaterButtonProps {
188
+ onClick: () => void;
189
+ isTheater?: boolean;
190
+ }
191
+ declare const TheaterButton: react.NamedExoticComponent<TheaterButtonProps>;
178
192
 
179
193
  declare const ControlElements: {
180
194
  PlayButton: react.NamedExoticComponent<PlayButtonProps>;
181
195
  PauseButton: react.NamedExoticComponent<PauseButtonProps>;
182
196
  FullscreenButton: react.NamedExoticComponent<FullscreenButtonProps>;
183
197
  PiPButton: react.NamedExoticComponent<PiPButtonProps>;
198
+ TheaterButton: react.NamedExoticComponent<TheaterButtonProps>;
184
199
  VolumeControl: react.NamedExoticComponent<VolumeControlProps>;
185
200
  ProgressBar: react.FC<ProgressBarProps>;
186
201
  SettingsMenu: react.NamedExoticComponent<SettingsMenuProps>;
@@ -200,12 +215,14 @@ declare const index_ProgressBar: typeof ProgressBar;
200
215
  type index_ProgressBarProps = ProgressBarProps;
201
216
  declare const index_SettingsMenu: typeof SettingsMenu;
202
217
  type index_SettingsMenuProps = SettingsMenuProps;
218
+ declare const index_TheaterButton: typeof TheaterButton;
219
+ type index_TheaterButtonProps = TheaterButtonProps;
203
220
  declare const index_TimeDisplay: typeof TimeDisplay;
204
221
  type index_TimeDisplayProps = TimeDisplayProps;
205
222
  declare const index_VolumeControl: typeof VolumeControl;
206
223
  type index_VolumeControlProps = VolumeControlProps;
207
224
  declare namespace index {
208
- export { index_ControlElements as ControlElements, index_FullscreenButton as FullscreenButton, type index_FullscreenButtonProps as FullscreenButtonProps, index_PauseButton as PauseButton, type index_PauseButtonProps as PauseButtonProps, index_PiPButton as PiPButton, type index_PiPButtonProps as PiPButtonProps, index_PlayButton as PlayButton, type index_PlayButtonProps as PlayButtonProps, index_ProgressBar as ProgressBar, type index_ProgressBarProps as ProgressBarProps, index_SettingsMenu as SettingsMenu, type index_SettingsMenuProps as SettingsMenuProps, index_TimeDisplay as TimeDisplay, type index_TimeDisplayProps as TimeDisplayProps, index_VolumeControl as VolumeControl, type index_VolumeControlProps as VolumeControlProps };
225
+ export { index_ControlElements as ControlElements, index_FullscreenButton as FullscreenButton, type index_FullscreenButtonProps as FullscreenButtonProps, index_PauseButton as PauseButton, type index_PauseButtonProps as PauseButtonProps, index_PiPButton as PiPButton, type index_PiPButtonProps as PiPButtonProps, index_PlayButton as PlayButton, type index_PlayButtonProps as PlayButtonProps, index_ProgressBar as ProgressBar, type index_ProgressBarProps as ProgressBarProps, index_SettingsMenu as SettingsMenu, type index_SettingsMenuProps as SettingsMenuProps, index_TheaterButton as TheaterButton, type index_TheaterButtonProps as TheaterButtonProps, index_TimeDisplay as TimeDisplay, type index_TimeDisplayProps as TimeDisplayProps, index_VolumeControl as VolumeControl, type index_VolumeControlProps as VolumeControlProps };
209
226
  }
210
227
 
211
228
  /**
@@ -252,4 +269,4 @@ declare function parseThumbnailVtt(text: string, baseUrl?: string): ThumbnailCue
252
269
  */
253
270
  declare function findThumbnailCue(cues: ThumbnailCue[], time: number): ThumbnailCue | null;
254
271
 
255
- export { type BufferedRange, index as ControlElements, Controls, type HLSQualityLevel, type PlaybackRate, type PlayerState, type SubtitleTrack, type ThumbnailCue, type VideoError, type VideoErrorCode, VideoPlayer, type VideoPlayerProps, type VideoPlayerRef, findThumbnailCue, formatTime, getMimeType, isHLSUrl, parseThumbnailVtt };
272
+ export { type BufferedRange, type ContextMenuItem, index as ControlElements, Controls, type HLSQualityLevel, type PlaybackRate, type PlayerState, type SubtitleTrack, type ThumbnailCue, type VideoError, type VideoErrorCode, VideoPlayer, type VideoPlayerProps, type VideoPlayerRef, findThumbnailCue, formatTime, getMimeType, isHLSUrl, parseThumbnailVtt };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';var ct=require('react'),ue=require('hls.js'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var ct__default=/*#__PURE__*/_interopDefault(ct);var ue__default=/*#__PURE__*/_interopDefault(ue);var $e=Object.defineProperty;var Ue=(r,e)=>{for(var m in e)$e(r,m,{get:e[m],enumerable:true});};function j(r){if(!Number.isFinite(r)||r<0)return "0:00";let e=Math.floor(r),m=Math.floor(e/3600),s=Math.floor(e%3600/60),a=e%60;return m>0?`${m}:${String(s).padStart(2,"0")}:${String(a).padStart(2,"0")}`:`${s}:${String(a).padStart(2,"0")}`}function le(r){try{return new URL(r,"https://x").pathname.toLowerCase().endsWith(".m3u8")||/\/hls\//i.test(r)||/\/stream\.m3u8/i.test(r)}catch{return r.toLowerCase().includes(".m3u8")}}function We(r){if(le(r))return "application/x-mpegURL";let e=r.toLowerCase().split("?")[0];return e.endsWith(".mp4")?"video/mp4":e.endsWith(".webm")?"video/webm":e.endsWith(".ogv")||e.endsWith(".ogg")?"video/ogg":e.endsWith(".mov")?"video/quicktime":"video/mp4"}function Te(r){return r.map((e,m)=>({id:m,height:e.height??0,width:e.width??0,bitrate:e.bitrate??0,name:e.height?`${e.height}p`:`Level ${m+1}`}))}var qe={isPlaying:false,currentTime:0,duration:0,volume:1,isMuted:false,playbackRate:1,isFullscreen:false,isPictureInPicture:false,isBuffering:false,bufferedRanges:[],error:null,isLive:false,qualityLevels:[],currentQualityLevel:-1};function Me(r,e,m={}){let s=ct.useRef(null),a=ct.useRef(null),h=ct.useRef(1),f=ct.useRef(0),l=ct.useRef(m);l.current=m;let[b,d]=ct.useState({...qe,isMuted:m.muted??false,volume:m.muted?0:1}),P=ct.useRef(b);P.current=b,ct.useEffect(()=>{let t=r.current;if(!t||(s.current&&(s.current.destroy(),s.current=null),f.current=0,d(c=>({...c,currentTime:0,duration:0,error:null,isBuffering:false,isLive:false,qualityLevels:[],currentQualityLevel:-1})),!e))return;let o=l.current;if(o.enableHLS!==false&&le(e)){if(t.canPlayType("application/vnd.apple.mpegurl"))t.src=e,t.load(),o.autoplay&&t.play().catch(()=>{});else if(ue__default.default.isSupported()){let c=new ue__default.default({autoStartLoad:true,startLevel:-1,capLevelToPlayerSize:true,capLevelOnFPSDrop:true,enableWorker:true,maxBufferLength:30,maxMaxBufferLength:600,maxBufferSize:6e7,liveBackBufferLength:30,liveSyncDurationCount:3,...o.hlsConfig});c.attachMedia(t),c.loadSource(e),c.on(ue.Events.MANIFEST_PARSED,(I,g)=>{let u=Te(g.levels);d(R=>({...R,qualityLevels:u,currentQualityLevel:-1})),l.current.autoplay&&t.play().catch(()=>{});}),c.on(ue.Events.LEVEL_SWITCHED,(I,g)=>{d(u=>({...u,currentQualityLevel:g.level}));});let M=3;c.on(ue.Events.ERROR,(I,g)=>{if(!g.fatal){console.warn("[hls] non-fatal:",g.details);return}switch(g.type){case ue__default.default.ErrorTypes.NETWORK_ERROR:if(f.current<M){f.current+=1;let u=1e3*f.current;console.warn(`[hls] network error \u2013 retry ${f.current}/${M} in ${u}ms`),setTimeout(()=>{s.current===c&&c.startLoad();},u);}else {let u={code:"HLS_NETWORK_ERROR",message:"Failed to load stream after multiple retries."};d(R=>({...R,error:u})),l.current.onError?.(u);}break;case ue__default.default.ErrorTypes.MEDIA_ERROR:console.warn("[hls] media error \u2013 recovering"),c.recoverMediaError();break;default:{c.destroy(),s.current=null;let u={code:"HLS_FATAL_ERROR",message:"An unrecoverable HLS error occurred."};d(R=>({...R,error:u})),l.current.onError?.(u);break}}}),s.current=c;}}else t.src=e,t.load(),o.autoplay&&t.play().catch(()=>{});return ()=>{s.current&&(s.current.destroy(),s.current=null);}},[e,r]),ct.useEffect(()=>{let t=r.current;if(!t)return;l.current.muted&&(t.muted=true),l.current.loop&&(t.loop=true);let o=()=>{d(n=>({...n,isPlaying:true})),l.current.onPlay?.();},c=()=>{d(n=>({...n,isPlaying:false})),l.current.onPause?.();},M=()=>{d(n=>({...n,isPlaying:false})),l.current.onEnded?.();},I=()=>{l.current.onTimeUpdate?.(t.currentTime);},g=()=>{let n=t.duration,p=!Number.isFinite(n);d(y=>({...y,duration:p?0:n,isLive:p})),p||l.current.onDurationChange?.(n);},u=()=>{let n=t.volume;n>0&&!t.muted&&(h.current=n),d(p=>({...p,volume:n,isMuted:t.muted||n===0}));},R=()=>{d(n=>({...n,playbackRate:t.playbackRate}));},Y=()=>{let n=t.error;if(!n)return;let y={code:{1:"MEDIA_ERR_ABORTED",2:"MEDIA_ERR_NETWORK",3:"MEDIA_ERR_DECODE",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"}[n.code]??"UNKNOWN",message:n.message||"Unknown media error"};d(U=>({...U,error:y})),l.current.onError?.(y);},q=()=>{d(n=>({...n,isBuffering:true})),l.current.onBuffering?.(true);},Z=()=>{d(n=>({...n,isBuffering:false})),l.current.onBuffering?.(false);},X=()=>d(n=>({...n,isBuffering:false})),G=()=>{},Q=()=>{let n=!!(document.fullscreenElement||document.webkitFullscreenElement);d(p=>({...p,isFullscreen:n}));},i=()=>{d(n=>({...n,isPictureInPicture:document.pictureInPictureElement===t}));};return t.addEventListener("play",o),t.addEventListener("pause",c),t.addEventListener("ended",M),t.addEventListener("timeupdate",I),t.addEventListener("durationchange",g),t.addEventListener("volumechange",u),t.addEventListener("ratechange",R),t.addEventListener("error",Y),t.addEventListener("waiting",q),t.addEventListener("canplay",Z),t.addEventListener("playing",X),t.addEventListener("progress",G),document.addEventListener("fullscreenchange",Q),document.addEventListener("webkitfullscreenchange",Q),t.addEventListener("enterpictureinpicture",i),t.addEventListener("leavepictureinpicture",i),()=>{t.removeEventListener("play",o),t.removeEventListener("pause",c),t.removeEventListener("ended",M),t.removeEventListener("timeupdate",I),t.removeEventListener("durationchange",g),t.removeEventListener("volumechange",u),t.removeEventListener("ratechange",R),t.removeEventListener("error",Y),t.removeEventListener("waiting",q),t.removeEventListener("canplay",Z),t.removeEventListener("playing",X),t.removeEventListener("progress",G),document.removeEventListener("fullscreenchange",Q),document.removeEventListener("webkitfullscreenchange",Q),t.removeEventListener("enterpictureinpicture",i),t.removeEventListener("leavepictureinpicture",i);}},[r]);let T=ct.useCallback(async()=>{let t=r.current;if(t)try{await t.play();}catch(o){o instanceof Error&&o.name!=="AbortError"&&console.error("[player] play() failed:",o);}},[r]),C=ct.useCallback(()=>{r.current?.pause();},[r]),E=ct.useCallback(t=>{let o=r.current;o&&(o.currentTime=Math.max(0,Math.min(t,o.duration||t)));},[r]),v=ct.useCallback(t=>{let o=r.current;if(!o)return;let c=Math.max(0,Math.min(t,1));c>0&&(h.current=c),o.volume=c,o.muted=c===0;},[r]),w=ct.useCallback(()=>{let t=r.current;if(t)if(t.muted||t.volume===0){let o=h.current>0?h.current:1;t.volume=o,t.muted=false;}else h.current=t.volume,t.muted=true;},[r]),L=ct.useCallback(t=>{let o=r.current;o&&(o.playbackRate=t);},[r]),D=ct.useCallback(t=>{let o=s.current;o&&(o.currentLevel=t,d(c=>({...c,currentQualityLevel:t})));},[]),x=ct.useCallback(()=>{let t=s.current,o=r.current;if(!t||!o)return;let c=t.liveSyncPosition;c!=null&&Number.isFinite(c)&&(o.currentTime=c);},[r]),V=ct.useCallback(async()=>{let t=r.current;if(!t)return;let o=a.current??t.parentElement;if(o)try{!document.fullscreenElement&&!document.webkitFullscreenElement?o.requestFullscreen?await o.requestFullscreen():o.webkitRequestFullscreen?.():document.exitFullscreen?await document.exitFullscreen():document.webkitExitFullscreen?.();}catch(c){console.error("[player] fullscreen toggle failed:",c);}},[r]),O=ct.useCallback(async()=>{let t=r.current;if(t)try{document.pictureInPictureElement?await document.exitPictureInPicture():await t.requestPictureInPicture();}catch(o){console.error("[player] PiP toggle failed:",o);}},[r]),S=ct.useCallback(()=>{let t=r.current,o=t?.currentTime??0,c=[];if(t)for(let M=0;M<t.buffered.length;M++)c.push({start:t.buffered.start(M),end:t.buffered.end(M)});return {...P.current,currentTime:o,bufferedRanges:c}},[r]),$=ct.useCallback(()=>r.current??null,[r]),A=ct.useMemo(()=>({play:T,pause:C,seek:E,setVolume:v,toggleMute:w,setPlaybackRate:L,setQualityLevel:D,seekToLive:x,toggleFullscreen:V,togglePictureInPicture:O,getState:S,getVideoElement:$}),[T,C,E,v,w,L,D,x,V,O,S,$]);return {state:b,ref:A,hlsRef:s,fullscreenContainerRef:a}}var Ve={};Ue(Ve,{ControlElements:()=>z,FullscreenButton:()=>ae,PauseButton:()=>ie,PiPButton:()=>se,PlayButton:()=>oe,ProgressBar:()=>me,SettingsMenu:()=>pe,TimeDisplay:()=>ve,VolumeControl:()=>de});var oe=ct.memo(({onClick:r})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":"Play",title:"Play (Space)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M8 5v14l11-7z"})})}));oe.displayName="PlayButton";var ie=ct.memo(({onClick:r})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":"Pause",title:"Pause (Space)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M6 4h4v16H6V4zm8 0h4v16h-4V4z"})})}));ie.displayName="PauseButton";var ae=ct.memo(({onClick:r,isFullscreen:e=false})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":e?"Exit Fullscreen":"Fullscreen",title:e?"Exit Fullscreen (F)":"Fullscreen (F)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:e?jsxRuntime.jsx("path",{d:"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"}):jsxRuntime.jsx("path",{d:"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"})})}));ae.displayName="FullscreenButton";var se=ct.memo(({onClick:r,isPiP:e=false})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":e?"Exit Picture-in-Picture":"Picture-in-Picture",title:e?"Exit Picture-in-Picture (P)":"Picture-in-Picture (P)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("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"})})}));se.displayName="PiPButton";var Ce=ct.memo(({volume:r,isMuted:e,onVolumeChange:m,onToggleMute:s})=>{let[a,h]=ct.useState(false),f=e?0:r,l=f*100,b=ct.useMemo(()=>`linear-gradient(to right, #60a5fa 0%, #60a5fa ${l}%, rgba(255,255,255,0.3) ${l}%, rgba(255,255,255,0.3) 100%)`,[l]);return jsxRuntime.jsxs("div",{className:"volumeContainer",onMouseEnter:()=>h(true),onMouseLeave:()=>h(false),children:[jsxRuntime.jsx("button",{onClick:s,className:"controlButton","aria-label":e?"Unmute":"Mute",title:e?"Unmute (M)":"Mute (M)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:f===0?jsxRuntime.jsx("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"}):f<.5?jsxRuntime.jsx("path",{d:"M7 9v6h4l5 5V4l-5 5H7z"}):jsxRuntime.jsx("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"})})}),a&&jsxRuntime.jsx("input",{type:"range",min:"0",max:"100",value:l,onChange:d=>m(Number(d.target.value)/100),className:"volumeSlider",style:{background:b},"aria-label":"Volume","aria-valuenow":Math.round(l)})]})});Ce.displayName="VolumeControl";var de=Ce;function we(r){let e=r.trim().split(":");return e.length===3?+e[0]*3600+ +e[1]*60+parseFloat(e[2]):+e[0]*60+parseFloat(e[1])}function Ye(r,e){if(/^https?:\/\//i.test(e))return e;try{return new URL(e,r).href}catch{return e}}function ge(r,e=""){let m=[],s=r.replace(/\r\n/g,`
1
+ 'use strict';var Et=require('react'),pe=require('hls.js'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Et__default=/*#__PURE__*/_interopDefault(Et);var pe__default=/*#__PURE__*/_interopDefault(pe);var qe=Object.defineProperty;var Xe=(n,e)=>{for(var p in e)qe(n,p,{get:e[p],enumerable:true});};function J(n){if(!Number.isFinite(n)||n<0)return "0:00";let e=Math.floor(n),p=Math.floor(e/3600),l=Math.floor(e%3600/60),o=e%60;return p>0?`${p}:${String(l).padStart(2,"0")}:${String(o).padStart(2,"0")}`:`${l}:${String(o).padStart(2,"0")}`}function me(n){try{return new URL(n,"https://x").pathname.toLowerCase().endsWith(".m3u8")||/\/hls\//i.test(n)||/\/stream\.m3u8/i.test(n)}catch{return n.toLowerCase().includes(".m3u8")}}function je(n){if(me(n))return "application/x-mpegURL";let e=n.toLowerCase().split("?")[0];return e.endsWith(".mp4")?"video/mp4":e.endsWith(".webm")?"video/webm":e.endsWith(".ogv")||e.endsWith(".ogg")?"video/ogg":e.endsWith(".mov")?"video/quicktime":"video/mp4"}function Re(n){return n.map((e,p)=>({id:p,height:e.height??0,width:e.width??0,bitrate:e.bitrate??0,name:e.height?`${e.height}p`:`Level ${p+1}`}))}var Je={isPlaying:false,currentTime:0,duration:0,volume:1,isMuted:false,playbackRate:1,isFullscreen:false,isPictureInPicture:false,isTheaterMode:false,isBuffering:false,bufferedRanges:[],error:null,isLive:false,qualityLevels:[],currentQualityLevel:-1};function Be(n,e,p={}){let l=Et.useRef(null),o=Et.useRef(null),f=Et.useRef(1),d=Et.useRef(0),c=Et.useRef(p);c.current=p;let[b,m]=Et.useState({...Je,isMuted:p.muted??false,volume:p.muted?0:1}),M=Et.useRef(b);M.current=b,Et.useEffect(()=>{let t=n.current;if(!t||(l.current&&(l.current.destroy(),l.current=null),d.current=0,m(i=>({...i,currentTime:0,duration:0,error:null,isBuffering:false,isLive:false,qualityLevels:[],currentQualityLevel:-1})),!e))return;let u=c.current;if(u.enableHLS!==false&&me(e)){if(t.canPlayType("application/vnd.apple.mpegurl"))t.src=e,t.load(),u.autoplay&&t.play().catch(()=>{});else if(pe__default.default.isSupported()){let i=new pe__default.default({autoStartLoad:true,startLevel:-1,capLevelToPlayerSize:true,capLevelOnFPSDrop:true,enableWorker:true,maxBufferLength:30,maxMaxBufferLength:600,maxBufferSize:6e7,liveBackBufferLength:30,liveSyncDurationCount:3,...u.hlsConfig});i.attachMedia(t),i.loadSource(e),i.on(pe.Events.MANIFEST_PARSED,(z,w)=>{let h=Re(w.levels);m(g=>({...g,qualityLevels:h,currentQualityLevel:-1})),c.current.autoplay&&t.play().catch(()=>{});}),i.on(pe.Events.LEVEL_SWITCHED,(z,w)=>{m(h=>({...h,currentQualityLevel:w.level}));});let L=3;i.on(pe.Events.ERROR,(z,w)=>{if(!w.fatal){console.warn("[hls] non-fatal:",w.details);return}switch(w.type){case pe__default.default.ErrorTypes.NETWORK_ERROR:if(d.current<L){d.current+=1;let h=1e3*d.current;console.warn(`[hls] network error \u2013 retry ${d.current}/${L} in ${h}ms`),setTimeout(()=>{l.current===i&&i.startLoad();},h);}else {let h={code:"HLS_NETWORK_ERROR",message:"Failed to load stream after multiple retries."};m(g=>({...g,error:h})),c.current.onError?.(h);}break;case pe__default.default.ErrorTypes.MEDIA_ERROR:console.warn("[hls] media error \u2013 recovering"),i.recoverMediaError();break;default:{i.destroy(),l.current=null;let h={code:"HLS_FATAL_ERROR",message:"An unrecoverable HLS error occurred."};m(g=>({...g,error:h})),c.current.onError?.(h);break}}}),l.current=i;}}else t.src=e,t.load(),u.autoplay&&t.play().catch(()=>{});return ()=>{l.current&&(l.current.destroy(),l.current=null);}},[e,n]),Et.useEffect(()=>{let t=n.current;if(!t)return;c.current.muted&&(t.muted=true),c.current.loop&&(t.loop=true);let u=()=>{m(a=>({...a,isPlaying:true})),c.current.onPlay?.();},i=()=>{m(a=>({...a,isPlaying:false})),c.current.onPause?.();},L=()=>{m(a=>({...a,isPlaying:false})),c.current.onEnded?.();},z=()=>{c.current.onTimeUpdate?.(t.currentTime);},w=()=>{let a=t.duration,P=!Number.isFinite(a);m(A=>({...A,duration:P?0:a,isLive:P})),P||c.current.onDurationChange?.(a);},h=()=>{let a=t.volume;a>0&&!t.muted&&(f.current=a),m(P=>({...P,volume:a,isMuted:t.muted||a===0}));},g=()=>{m(a=>({...a,playbackRate:t.playbackRate}));},U=()=>{let a=t.error;if(!a)return;let A={code:{1:"MEDIA_ERR_ABORTED",2:"MEDIA_ERR_NETWORK",3:"MEDIA_ERR_DECODE",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"}[a.code]??"UNKNOWN",message:a.message||"Unknown media error"};m(ye=>({...ye,error:A})),c.current.onError?.(A);},j=()=>{m(a=>({...a,isBuffering:true})),c.current.onBuffering?.(true);},D=()=>{m(a=>({...a,isBuffering:false})),c.current.onBuffering?.(false);},ee=()=>m(a=>({...a,isBuffering:false})),Y=()=>{},r=()=>{let a=!!(document.fullscreenElement||document.webkitFullscreenElement);m(P=>({...P,isFullscreen:a}));},s=()=>{m(a=>({...a,isPictureInPicture:document.pictureInPictureElement===t}));};return t.addEventListener("play",u),t.addEventListener("pause",i),t.addEventListener("ended",L),t.addEventListener("timeupdate",z),t.addEventListener("durationchange",w),t.addEventListener("volumechange",h),t.addEventListener("ratechange",g),t.addEventListener("error",U),t.addEventListener("waiting",j),t.addEventListener("canplay",D),t.addEventListener("playing",ee),t.addEventListener("progress",Y),document.addEventListener("fullscreenchange",r),document.addEventListener("webkitfullscreenchange",r),t.addEventListener("enterpictureinpicture",s),t.addEventListener("leavepictureinpicture",s),()=>{t.removeEventListener("play",u),t.removeEventListener("pause",i),t.removeEventListener("ended",L),t.removeEventListener("timeupdate",z),t.removeEventListener("durationchange",w),t.removeEventListener("volumechange",h),t.removeEventListener("ratechange",g),t.removeEventListener("error",U),t.removeEventListener("waiting",j),t.removeEventListener("canplay",D),t.removeEventListener("playing",ee),t.removeEventListener("progress",Y),document.removeEventListener("fullscreenchange",r),document.removeEventListener("webkitfullscreenchange",r),t.removeEventListener("enterpictureinpicture",s),t.removeEventListener("leavepictureinpicture",s);}},[n]);let x=Et.useCallback(async()=>{let t=n.current;if(t)try{await t.play();}catch(u){u instanceof Error&&u.name!=="AbortError"&&console.error("[player] play() failed:",u);}},[n]),V=Et.useCallback(()=>{n.current?.pause();},[n]),E=Et.useCallback(t=>{let u=n.current;u&&(u.currentTime=Math.max(0,Math.min(t,u.duration||t)));},[n]),v=Et.useCallback(t=>{let u=n.current;if(!u)return;let i=Math.max(0,Math.min(t,1));i>0&&(f.current=i),u.volume=i,u.muted=i===0;},[n]),R=Et.useCallback(()=>{let t=n.current;if(t)if(t.muted||t.volume===0){let u=f.current>0?f.current:1;t.volume=u,t.muted=false;}else f.current=t.volume,t.muted=true;},[n]),H=Et.useCallback(t=>{let u=n.current;u&&(u.playbackRate=t);},[n]),k=Et.useCallback(t=>{let u=l.current;u&&(u.currentLevel=t,m(i=>({...i,currentQualityLevel:t})));},[]),y=Et.useCallback(()=>{let t=l.current,u=n.current;if(!t||!u)return;let i=t.liveSyncPosition;i!=null&&Number.isFinite(i)&&(u.currentTime=i);},[n]),T=Et.useCallback(async()=>{let t=n.current;if(!t)return;let u=o.current??t.parentElement;if(u)try{!document.fullscreenElement&&!document.webkitFullscreenElement?u.requestFullscreen?await u.requestFullscreen():u.webkitRequestFullscreen?.():document.exitFullscreen?await document.exitFullscreen():document.webkitExitFullscreen?.();}catch(i){console.error("[player] fullscreen toggle failed:",i);}},[n]),N=Et.useCallback(async()=>{let t=n.current;if(t)try{document.pictureInPictureElement?await document.exitPictureInPicture():await t.requestPictureInPicture();}catch(u){console.error("[player] PiP toggle failed:",u);}},[n]),C=Et.useCallback(()=>{m(t=>{let u=!t.isTheaterMode;return c.current.onTheaterModeChange?.(u),{...t,isTheaterMode:u}});},[]),Q=Et.useCallback(()=>{let t=n.current,u=t?.currentTime??0,i=[];if(t)for(let L=0;L<t.buffered.length;L++)i.push({start:t.buffered.start(L),end:t.buffered.end(L)});return {...M.current,currentTime:u,bufferedRanges:i}},[n]),q=Et.useCallback(()=>n.current??null,[n]),X=Et.useMemo(()=>({play:x,pause:V,seek:E,setVolume:v,toggleMute:R,setPlaybackRate:H,setQualityLevel:k,seekToLive:y,toggleFullscreen:T,togglePictureInPicture:N,toggleTheaterMode:C,getState:Q,getVideoElement:q}),[x,V,E,v,R,H,k,y,T,N,C,Q,q]);return {state:b,ref:X,hlsRef:l,fullscreenContainerRef:o}}var _e={};Xe(_e,{ControlElements:()=>_,FullscreenButton:()=>le,PauseButton:()=>se,PiPButton:()=>ue,PlayButton:()=>ie,ProgressBar:()=>ve,SettingsMenu:()=>he,TheaterButton:()=>ce,TimeDisplay:()=>be,VolumeControl:()=>fe});var ie=Et.memo(({onClick:n})=>jsxRuntime.jsx("button",{onClick:n,className:"controlButton","aria-label":"Play",title:"Play (Space)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M8 5v14l11-7z"})})}));ie.displayName="PlayButton";var se=Et.memo(({onClick:n})=>jsxRuntime.jsx("button",{onClick:n,className:"controlButton","aria-label":"Pause",title:"Pause (Space)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M6 4h4v16H6V4zm8 0h4v16h-4V4z"})})}));se.displayName="PauseButton";var le=Et.memo(({onClick:n,isFullscreen:e=false})=>jsxRuntime.jsx("button",{onClick:n,className:"controlButton","aria-label":e?"Exit Fullscreen":"Fullscreen",title:e?"Exit Fullscreen (F)":"Fullscreen (F)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:e?jsxRuntime.jsx("path",{d:"M5 16h3v3h2v-5H5v2zm3-8H5v2h5V5H8v3zm6 11h2v-3h3v-2h-5v5zm2-11V5h-2v5h5V8h-3z"}):jsxRuntime.jsx("path",{d:"M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"})})}));le.displayName="FullscreenButton";var ue=Et.memo(({onClick:n,isPiP:e=false})=>jsxRuntime.jsx("button",{onClick:n,className:"controlButton","aria-label":e?"Exit Picture-in-Picture":"Picture-in-Picture",title:e?"Exit Picture-in-Picture (P)":"Picture-in-Picture (P)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("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"})})}));ue.displayName="PiPButton";var ce=Et.memo(({onClick:n,isTheater:e=false})=>jsxRuntime.jsx("button",{onClick:n,className:"controlButton","aria-label":e?"Exit Theater Mode":"Theater Mode",title:e?"Exit Theater Mode (T)":"Theater Mode (T)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:e?jsxRuntime.jsx("path",{d:"M19 7H5c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zm0 8H5V9h14v6z"}):jsxRuntime.jsx("path",{d:"M21 3H3c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H3V5h18v14z"})})}));ce.displayName="TheaterButton";var He=Et.memo(({volume:n,isMuted:e,onVolumeChange:p,onToggleMute:l})=>{let[o,f]=Et.useState(false),d=e?0:n,c=d*100,b=Et.useMemo(()=>`linear-gradient(to right, #60a5fa 0%, #60a5fa ${c}%, rgba(255,255,255,0.3) ${c}%, rgba(255,255,255,0.3) 100%)`,[c]);return jsxRuntime.jsxs("div",{className:"volumeContainer",onMouseEnter:()=>f(true),onMouseLeave:()=>f(false),children:[jsxRuntime.jsx("button",{onClick:l,className:"controlButton","aria-label":e?"Unmute":"Mute",title:e?"Unmute (M)":"Mute (M)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:d===0?jsxRuntime.jsx("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"}):d<.5?jsxRuntime.jsx("path",{d:"M7 9v6h4l5 5V4l-5 5H7z"}):jsxRuntime.jsx("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"})})}),o&&jsxRuntime.jsx("input",{type:"range",min:"0",max:"100",value:c,onChange:m=>p(Number(m.target.value)/100),className:"volumeSlider",style:{background:b},"aria-label":"Volume","aria-valuenow":Math.round(c)})]})});He.displayName="VolumeControl";var fe=He;function Ve(n){let e=n.trim().split(":");return e.length===3?+e[0]*3600+ +e[1]*60+parseFloat(e[2]):+e[0]*60+parseFloat(e[1])}function rt(n,e){if(/^https?:\/\//i.test(e))return e;try{return new URL(e,n).href}catch{return e}}function Le(n,e=""){let p=[],l=n.replace(/\r\n/g,`
2
2
  `).split(`
3
- `),a=0;for(;a<s.length;){let h=s[a].trim();if(h.includes("-->")){let f=h.indexOf("-->"),l=we(h.slice(0,f)),b=we(h.slice(f+3));for(a++;a<s.length&&!s[a].trim();)a++;if(a<s.length){let d=s[a].trim(),P=d.lastIndexOf("#xywh="),T=d,C=0,E=0,v=160,w=90;if(P!==-1){T=d.slice(0,P);let L=d.slice(P+6).split(",").map(Number);C=L[0]??0,E=L[1]??0,v=L[2]??160,w=L[3]??90;}m.push({start:l,end:b,url:Ye(e,T),x:C,y:E,w:v,h:w});}}a++;}return m}function be(r,e){if(!r.length)return null;let m=0,s=r.length-1;for(;m<=s;){let a=m+s>>1;if(r[a].end<=e)m=a+1;else if(r[a].start>e)s=a-1;else return r[a]}return null}var xe=ct.memo(({videoRef:r,playerRef:e,enablePreview:m=true,thumbnailVtt:s})=>{let a=ct.useRef(null),h=ct.useRef(null),f=ct.useRef(null),l=ct.useRef(null),b=ct.useRef(null),d=ct.useRef(null),P=ct.useRef(null),[T,C]=ct.useState([]),E=ct.useRef(false),v=ct.useRef(0),w=ct.useRef(0),L=ct.useRef(null),D=ct.useRef([]),x=ct.useRef(null);ct.useEffect(()=>{let i=()=>{x.current=null;};return window.addEventListener("resize",i,{passive:true}),()=>window.removeEventListener("resize",i)},[]);let V=ct.useCallback(()=>(!x.current&&a.current&&(x.current=a.current.getBoundingClientRect()),x.current),[]);ct.useEffect(()=>{if(!s){D.current=[];return}let i=false;return fetch(s).then(n=>n.text()).then(n=>{i||(D.current=ge(n,s));}).catch(()=>{i||(D.current=[]);}),()=>{i=true;}},[s]),ct.useEffect(()=>{let i=r.current;if(!i)return;let n=()=>{let p=isFinite(i.duration)?i.duration:0,y=i.currentTime,U=p>0?y/p*100:0;h.current&&(h.current.style.width=`${U}%`),f.current&&(f.current.style.left=`${U}%`),a.current&&(a.current.setAttribute("aria-valuenow",String(Math.round(y))),a.current.setAttribute("aria-valuemax",String(Math.round(p))),a.current.setAttribute("aria-valuetext",j(y)));};return i.addEventListener("timeupdate",n),i.addEventListener("durationchange",n),i.addEventListener("seeked",n),n(),()=>{i.removeEventListener("timeupdate",n),i.removeEventListener("durationchange",n),i.removeEventListener("seeked",n);}},[r]),ct.useEffect(()=>{let i=r.current;if(!i)return;let n=()=>{let p=[];for(let y=0;y<i.buffered.length;y++)p.push({start:i.buffered.start(y),end:i.buffered.end(y)});C(p);};return i.addEventListener("progress",n),()=>i.removeEventListener("progress",n)},[r]);let O=ct.useCallback(()=>{E.current=true,f.current?.classList.add("dragging");},[]),S=ct.useCallback(()=>{E.current=false,f.current?.classList.remove("dragging");},[]),$=ct.useCallback(()=>{m&&(x.current=null,l.current&&(l.current.style.display=""),d.current&&(d.current.style.display=""));},[m]),A=ct.useCallback(()=>{l.current&&(l.current.style.display="none"),d.current&&(d.current.style.display="none");},[]),t=ct.useCallback(i=>{if(!P.current||!D.current.length)return;let n=be(D.current,i);if(L.current=n,!n)return;let p=P.current;p.style.backgroundImage=`url(${n.url})`,p.style.backgroundPosition=`-${n.x}px -${n.y}px`,p.style.width=`${n.w}px`,p.style.height=`${n.h}px`;},[]),o=ct.useCallback(i=>{let n=V(),p=r.current?.duration;return !n||n.width===0||!p||!isFinite(p)?0:Math.max(0,Math.min(i-n.left,n.width))/n.width*p},[V,r]),c=ct.useCallback(i=>{let n=V();return n?Math.max(0,Math.min(i-n.left,n.width)):0},[V]),M=ct.useCallback(i=>{let n=r.current;if(!n)return;let p=n.currentTime,y=isFinite(n.duration)?n.duration:0;switch(i.key){case "ArrowLeft":case "ArrowRight":{i.preventDefault(),i.nativeEvent.stopImmediatePropagation();let U=i.shiftKey?10:5;e.seek(i.key==="ArrowLeft"?Math.max(0,p-U):Math.min(y,p+U));break}case "Home":i.preventDefault(),i.nativeEvent.stopImmediatePropagation(),e.seek(0);break;case "End":y>0&&(i.preventDefault(),i.nativeEvent.stopImmediatePropagation(),e.seek(y));break}},[r,e]),I=ct.useCallback(i=>{let n=o(i.clientX),p=c(i.clientX);v.current=p,w.current=n,l.current&&(l.current.style.left=`${p}px`),d.current&&(d.current.style.left=`${p}px`),b.current&&(b.current.textContent=j(n)),t(n),E.current&&e.seek(n);},[e,t,o,c]),g=ct.useCallback(()=>{$();},[$]),u=ct.useCallback(()=>{A(),S();},[A,S]),R=ct.useCallback(i=>{i.preventDefault(),O(),e.seek(o(i.clientX));},[O,o,e]),Y=ct.useCallback(()=>S(),[S]),q=ct.useCallback(i=>{E.current||e.seek(o(i.clientX));},[o,e]);ct.useEffect(()=>{let i=a.current;if(!i)return;let n=p=>{E.current&&p.preventDefault();};return i.addEventListener("touchmove",n,{passive:false}),()=>i.removeEventListener("touchmove",n)},[]);let Z=ct.useCallback(i=>{x.current=null,O(),e.seek(o(i.touches[0].clientX));},[O,o,e]),X=ct.useCallback(i=>{E.current&&e.seek(o(i.touches[0].clientX));},[o,e]),G=ct.useCallback(()=>S(),[S]);ct.useEffect(()=>{let i=()=>S();return window.addEventListener("mouseup",i),()=>window.removeEventListener("mouseup",i)},[S]);let Q=ct.useMemo(()=>{let i=r.current,n=i&&isFinite(i.duration)?i.duration:0;return n<=0||!T.length?null:T.map((p,y)=>{let U=p.start/n*100,_e=(p.end-p.start)/n*100;return jsxRuntime.jsx("div",{className:"bufferedSegment",style:{left:`${U}%`,width:`${_e}%`}},y)})},[T,r]);return jsxRuntime.jsxs("div",{ref:a,className:"progressContainer",onMouseMove:I,onMouseEnter:g,onMouseLeave:u,onMouseDown:R,onMouseUp:Y,onClick:q,onTouchStart:Z,onTouchMove:X,onTouchEnd:G,onKeyDown:M,role:"slider","aria-label":"Video progress","aria-valuemin":0,"aria-valuemax":0,"aria-valuenow":0,"aria-valuetext":"0:00",tabIndex:0,children:[m&&jsxRuntime.jsxs("div",{ref:l,className:"previewTooltip",style:{left:0,display:"none"},"aria-hidden":"true",children:[s&&jsxRuntime.jsx("div",{ref:P,className:"previewThumbnail"}),jsxRuntime.jsx("div",{ref:b,className:"previewTime"})]}),jsxRuntime.jsxs("div",{className:"progressBackground",children:[Q,jsxRuntime.jsx("div",{ref:h,className:"progressFilled",style:{width:"0%"}}),m&&jsxRuntime.jsx("div",{ref:d,className:"hoverIndicator",style:{left:0,display:"none"},"aria-hidden":"true"})]}),jsxRuntime.jsx("div",{ref:f,className:"scrubHandle",style:{left:"0%"},"aria-hidden":"true"})]})});xe.displayName="ProgressBar";var me=xe;var De=ct.memo(({currentRate:r,playbackRates:e,onRateChange:m,qualityLevels:s=[],currentQualityLevel:a=-1,onQualityChange:h})=>{let[f,l]=ct.useState(false),[b,d]=ct.useState("speed"),P=ct.useRef(null),T=s.length>0&&!!h;ct.useEffect(()=>{let v=w=>{P.current&&!P.current.contains(w.target)&&l(false);};return f&&document.addEventListener("mousedown",v),()=>document.removeEventListener("mousedown",v)},[f]);let C=ct.useMemo(()=>[...s].sort((v,w)=>w.bitrate-v.bitrate),[s]),E=ct.useMemo(()=>a===-1?"Auto":s.find(v=>v.id===a)?.name??"Auto",[s,a]);return jsxRuntime.jsxs("div",{ref:P,className:"settingsContainer",children:[jsxRuntime.jsx("button",{onClick:()=>l(v=>!v),className:"controlButton","aria-label":"Settings",title:"Settings","aria-expanded":f,children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("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"})})}),f&&jsxRuntime.jsxs("div",{className:"settingsDropdown",role:"menu",children:[T&&jsxRuntime.jsxs("div",{className:"settingsTabs",children:[jsxRuntime.jsx("button",{className:`settingsTab${b==="speed"?" active":""}`,onClick:()=>d("speed"),children:"Speed"}),jsxRuntime.jsx("button",{className:`settingsTab${b==="quality"?" active":""}`,onClick:()=>d("quality"),children:"Quality"})]}),(!T||b==="speed")&&jsxRuntime.jsxs("div",{children:[!T&&jsxRuntime.jsx("div",{className:"settingsPanelLabel",children:"Playback Speed"}),e.map(v=>jsxRuntime.jsx("button",{onClick:()=>{m(v),l(false);},className:`settingsOption${r===v?" active":""}`,role:"menuitemradio","aria-checked":r===v,children:v===1?"Normal":`${v}\xD7`},v))]}),T&&b==="quality"&&jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{h(-1),l(false);},className:`settingsOption${a===-1?" active":""}`,role:"menuitemradio","aria-checked":a===-1,children:["Auto ",a===-1&&E!=="Auto"?`(${E})`:""]}),C.map(v=>jsxRuntime.jsxs("button",{onClick:()=>{h(v.id),l(false);},className:`settingsOption${a===v.id?" active":""}`,role:"menuitemradio","aria-checked":a===v.id,children:[v.name,v.bitrate>0&&jsxRuntime.jsxs("span",{className:"settingsOptionBadge",children:[Math.round(v.bitrate/1e3)," kbps"]})]},v.id))]})]})]})});De.displayName="SettingsMenu";var pe=De;var He=ct.memo(({videoRef:r,isLive:e=false})=>{let m=ct.useRef(null),s=ct.useRef(null);return ct.useEffect(()=>{let a=r.current;if(!a)return;let h=()=>{m.current&&(m.current.textContent=j(a.currentTime));},f=()=>{if(s.current){let l=isFinite(a.duration)?a.duration:0;s.current.textContent=` / ${j(l)}`;}};return a.addEventListener("timeupdate",h),a.addEventListener("durationchange",f),a.addEventListener("seeked",h),h(),f(),()=>{a.removeEventListener("timeupdate",h),a.removeEventListener("durationchange",f),a.removeEventListener("seeked",h);}},[r,e]),e?jsxRuntime.jsx("span",{className:"timeDisplay",style:{opacity:.7},children:jsxRuntime.jsx("span",{ref:m,children:"0:00"})}):jsxRuntime.jsxs("span",{className:"timeDisplay",children:[jsxRuntime.jsx("span",{ref:m,children:"0:00"}),jsxRuntime.jsx("span",{ref:s,style:{opacity:.6},children:" / 0:00"})]})});He.displayName="TimeDisplay";var ve=He;var z={PlayButton:oe,PauseButton:ie,FullscreenButton:ae,PiPButton:se,VolumeControl:de,ProgressBar:me,SettingsMenu:pe,TimeDisplay:ve};var Le=({videoRef:r,playerRef:e,playerContainerRef:m,playbackRates:s,enablePreview:a,thumbnailVtt:h,isPlaying:f,volume:l,isMuted:b,playbackRate:d,isFullscreen:P,isPictureInPicture:T,isLive:C,qualityLevels:E,currentQualityLevel:v})=>{let w=ct.useRef(null),L=ct.useRef(null),[D,x]=ct.useState(true),V=ct.useRef({isPlaying:f,volume:l,isMuted:b,isLive:C});V.current={isPlaying:f,volume:l,isMuted:b,isLive:C},ct.useEffect(()=>{if(!f){x(true),L.current&&clearTimeout(L.current);return}let g=()=>{x(true),L.current&&clearTimeout(L.current),L.current=setTimeout(()=>x(false),3e3);},u=w.current;return u&&(u.addEventListener("mousemove",g),u.addEventListener("mouseenter",g),u.addEventListener("touchstart",g,{passive:true})),g(),()=>{u&&(u.removeEventListener("mousemove",g),u.removeEventListener("mouseenter",g),u.removeEventListener("touchstart",g)),L.current&&clearTimeout(L.current);}},[f]),ct.useEffect(()=>{let g=u=>{if(!m.current?.contains(document.activeElement))return;let R=u.target;if(R.tagName==="INPUT"||R.tagName==="TEXTAREA"||R.isContentEditable)return;let{isPlaying:Y,volume:q,isLive:Z}=V.current,X=r.current?.currentTime??0,G=r.current?.duration??0;switch(u.code){case "Space":case "KeyK":u.preventDefault(),Y?e.pause():e.play();break;case "ArrowLeft":u.preventDefault(),e.seek(Math.max(0,X-5));break;case "ArrowRight":u.preventDefault(),e.seek(Math.min(G||1/0,X+5));break;case "ArrowUp":u.preventDefault(),e.setVolume(Math.min(1,q+.1));break;case "ArrowDown":u.preventDefault(),e.setVolume(Math.max(0,q-.1));break;case "KeyM":u.preventDefault(),e.toggleMute();break;case "KeyF":u.preventDefault(),e.toggleFullscreen();break;case "KeyP":u.preventDefault(),e.togglePictureInPicture();break;case "KeyL":u.preventDefault(),Z&&e.seekToLive();break;case "Digit0":case "Digit1":case "Digit2":case "Digit3":case "Digit4":case "Digit5":case "Digit6":case "Digit7":case "Digit8":case "Digit9":{u.preventDefault();let Q=Number(u.code.replace("Digit",""))*10;e.seek(G/100*Q);break}}};return window.addEventListener("keydown",g),()=>window.removeEventListener("keydown",g)},[e,m,r]);let O=ct.useCallback(()=>e.play(),[e]),S=ct.useCallback(()=>e.pause(),[e]),$=ct.useCallback(g=>e.setVolume(g),[e]),A=ct.useCallback(()=>e.toggleMute(),[e]),t=ct.useCallback(g=>e.setPlaybackRate(g),[e]),o=ct.useCallback(g=>e.setQualityLevel(g),[e]),c=ct.useCallback(()=>e.togglePictureInPicture(),[e]),M=ct.useCallback(()=>e.toggleFullscreen(),[e]),I=ct.useCallback(()=>e.seekToLive(),[e]);return jsxRuntime.jsx("div",{ref:w,style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",justifyContent:"flex-end",opacity:D?1:0,transition:"opacity 0.3s",pointerEvents:D?"auto":"none"},children:jsxRuntime.jsxs("div",{style:{background:"linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 60%, transparent 100%)",padding:"48px 12px 12px"},role:"region","aria-label":"Video player controls",children:[jsxRuntime.jsx(z.ProgressBar,{videoRef:r,playerRef:e,enablePreview:a,thumbnailVtt:h}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,marginTop:4},children:[f?jsxRuntime.jsx(z.PauseButton,{onClick:S}):jsxRuntime.jsx(z.PlayButton,{onClick:O}),jsxRuntime.jsx(z.VolumeControl,{volume:l,isMuted:b,onVolumeChange:$,onToggleMute:A}),jsxRuntime.jsx(z.TimeDisplay,{videoRef:r,isLive:C}),jsxRuntime.jsx("div",{style:{flex:1}}),C&&jsxRuntime.jsx(Oe,{onClick:I}),jsxRuntime.jsx(z.SettingsMenu,{currentRate:d,playbackRates:s,onRateChange:t,qualityLevels:E,currentQualityLevel:v,onQualityChange:o}),jsxRuntime.jsx(z.PiPButton,{onClick:c,isPiP:T}),jsxRuntime.jsx(z.FullscreenButton,{onClick:M,isFullscreen:P})]})]})})},Oe=ct.memo(({onClick:r})=>jsxRuntime.jsx("button",{onClick:r,style:{background:"none",border:"1px solid rgba(255,255,255,0.6)",color:"#fff",borderRadius:3,padding:"2px 8px",fontSize:11,fontWeight:700,cursor:"pointer",letterSpacing:"0.06em"},title:"Go to live (L)",children:"GO LIVE"}));Oe.displayName="GoLiveButton";var ze=ct.forwardRef(({src:r,poster:e,autoplay:m=false,muted:s=false,loop:a=false,controls:h=true,preload:f="metadata",playbackRates:l=[.25,.5,.75,1,1.25,1.5,1.75,2],className:b,enableHLS:d=true,enablePreview:P=true,thumbnailVtt:T,hlsConfig:C,subtitles:E,crossOrigin:v,onPlay:w,onPause:L,onEnded:D,onError:x,onTimeUpdate:V,onDurationChange:O,onBuffering:S},$)=>{let A=ct.useRef(null),t=ct.useRef(null),{state:o,ref:c,fullscreenContainerRef:M}=Me(A,r,{autoplay:m,muted:s,loop:a,playbackRates:l,enableHLS:d,hlsConfig:C,onPlay:w,onPause:L,onEnded:D,onError:x,onTimeUpdate:V,onDurationChange:O,onBuffering:S});ct.useEffect(()=>{M.current=t.current;},[M]),ct__default.default.useImperativeHandle($,()=>c,[c]);let I=ct.useCallback(()=>{t.current?.focus(),o.isPlaying?c.pause():c.play();},[o.isPlaying,c]),g=ct.useCallback(()=>{c.toggleFullscreen();},[c]);return jsxRuntime.jsxs("div",{ref:t,tabIndex:0,style:{position:"relative",width:"100%",backgroundColor:"#000",aspectRatio:"16 / 9",userSelect:"none",outline:"none"},className:b,"data-test":"video-player-container",children:[jsxRuntime.jsx("video",{ref:A,poster:e,preload:f,crossOrigin:v,onClick:I,onDoubleClick:g,playsInline:true,style:{width:"100%",height:"100%",display:"block",cursor:"pointer"},"data-test":"video-element",children:E?.map(u=>jsxRuntime.jsx("track",{kind:"subtitles",src:u.src,label:u.label,srcLang:u.srclang,default:u.default},u.id))}),h&&jsxRuntime.jsx(Le,{videoRef:A,playerRef:c,playerContainerRef:t,playbackRates:l,enablePreview:P,thumbnailVtt:T,isPlaying:o.isPlaying,volume:o.volume,isMuted:o.isMuted,playbackRate:o.playbackRate,isFullscreen:o.isFullscreen,isPictureInPicture:o.isPictureInPicture,isLive:o.isLive,qualityLevels:o.qualityLevels,currentQualityLevel:o.currentQualityLevel}),o.isLive&&jsxRuntime.jsx("div",{style:{position:"absolute",top:12,left:12,backgroundColor:"#e53935",color:"#fff",fontSize:11,fontWeight:700,letterSpacing:"0.08em",padding:"2px 8px",borderRadius:3,pointerEvents:"none"},children:"LIVE"}),o.isBuffering&&!o.error&&jsxRuntime.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:12,color:"#fff",pointerEvents:"none"},"data-test":"buffering-indicator",children:[jsxRuntime.jsx("div",{style:{width:48,height:48,border:"4px solid rgba(255,255,255,0.25)",borderTop:"4px solid #fff",borderRadius:"50%",animation:"rvp-spin 0.8s linear infinite"}}),jsxRuntime.jsx("style",{children:"@keyframes rvp-spin { to { transform: rotate(360deg); } }"})]}),o.error&&jsxRuntime.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"rgba(0,0,0,0.85)",color:"#fff",padding:24},"data-test":"error-overlay",children:jsxRuntime.jsxs("div",{style:{textAlign:"center",maxWidth:400},children:[jsxRuntime.jsx("div",{style:{fontSize:36,marginBottom:12},children:"\u26A0"}),jsxRuntime.jsx("h3",{style:{margin:"0 0 8px",fontSize:18},children:o.error.code==="MEDIA_ERR_SRC_NOT_SUPPORTED"?"Unsupported Format":o.error.code.startsWith("HLS")?"Stream Error":"Playback Error"}),jsxRuntime.jsx("p",{style:{margin:0,fontSize:13,opacity:.75},children:o.error.message})]})})]})});ze.displayName="VideoPlayer";var pt=ze;exports.ControlElements=Ve;exports.Controls=Le;exports.VideoPlayer=pt;exports.findThumbnailCue=be;exports.formatTime=j;exports.getMimeType=We;exports.isHLSUrl=le;exports.parseThumbnailVtt=ge;//# sourceMappingURL=index.js.map
3
+ `),o=0;for(;o<l.length;){let f=l[o].trim();if(f.includes("-->")){let d=f.indexOf("-->"),c=Ve(f.slice(0,d)),b=Ve(f.slice(d+3));for(o++;o<l.length&&!l[o].trim();)o++;if(o<l.length){let m=l[o].trim(),M=m.lastIndexOf("#xywh="),x=m,V=0,E=0,v=160,R=90;if(M!==-1){x=m.slice(0,M);let H=m.slice(M+6).split(",").map(Number);V=H[0]??0,E=H[1]??0,v=H[2]??160,R=H[3]??90;}p.push({start:c,end:b,url:rt(e,x),x:V,y:E,w:v,h:R});}}o++;}return p}function Pe(n,e){if(!n.length)return null;let p=0,l=n.length-1;for(;p<=l;){let o=p+l>>1;if(n[o].end<=e)p=o+1;else if(n[o].start>e)l=o-1;else return n[o]}return null}var Ne=Et.memo(({videoRef:n,playerRef:e,enablePreview:p=true,thumbnailVtt:l})=>{let o=Et.useRef(null),f=Et.useRef(null),d=Et.useRef(null),c=Et.useRef(null),b=Et.useRef(null),m=Et.useRef(null),M=Et.useRef(null),[x,V]=Et.useState([]),E=Et.useRef(false),v=Et.useRef(0),R=Et.useRef(0),H=Et.useRef(null),k=Et.useRef([]),y=Et.useRef(null);Et.useEffect(()=>{let r=()=>{y.current=null;};return window.addEventListener("resize",r,{passive:true}),()=>window.removeEventListener("resize",r)},[]);let T=Et.useCallback(()=>(!y.current&&o.current&&(y.current=o.current.getBoundingClientRect()),y.current),[]);Et.useEffect(()=>{if(!l){k.current=[];return}let r=false;return fetch(l).then(s=>s.text()).then(s=>{r||(k.current=Le(s,l));}).catch(()=>{r||(k.current=[]);}),()=>{r=true;}},[l]),Et.useEffect(()=>{let r=n.current;if(!r)return;let s=()=>{let a=isFinite(r.duration)?r.duration:0,P=r.currentTime,A=a>0?P/a*100:0;f.current&&(f.current.style.width=`${A}%`),d.current&&(d.current.style.left=`${A}%`),o.current&&(o.current.setAttribute("aria-valuenow",String(Math.round(P))),o.current.setAttribute("aria-valuemax",String(Math.round(a))),o.current.setAttribute("aria-valuetext",J(P)));};return r.addEventListener("timeupdate",s),r.addEventListener("durationchange",s),r.addEventListener("seeked",s),s(),()=>{r.removeEventListener("timeupdate",s),r.removeEventListener("durationchange",s),r.removeEventListener("seeked",s);}},[n]),Et.useEffect(()=>{let r=n.current;if(!r)return;let s=()=>{let a=[];for(let P=0;P<r.buffered.length;P++)a.push({start:r.buffered.start(P),end:r.buffered.end(P)});V(a);};return r.addEventListener("progress",s),()=>r.removeEventListener("progress",s)},[n]);let N=Et.useCallback(()=>{E.current=true,d.current?.classList.add("dragging");},[]),C=Et.useCallback(()=>{E.current=false,d.current?.classList.remove("dragging");},[]),Q=Et.useCallback(()=>{p&&(y.current=null,c.current&&(c.current.style.display=""),m.current&&(m.current.style.display=""));},[p]),q=Et.useCallback(()=>{c.current&&(c.current.style.display="none"),m.current&&(m.current.style.display="none");},[]),X=Et.useCallback(r=>{if(!M.current||!k.current.length)return;let s=Pe(k.current,r);if(H.current=s,!s)return;let a=M.current;a.style.backgroundImage=`url(${s.url})`,a.style.backgroundPosition=`-${s.x}px -${s.y}px`,a.style.width=`${s.w}px`,a.style.height=`${s.h}px`;},[]),t=Et.useCallback(r=>{let s=T(),a=n.current?.duration;return !s||s.width===0||!a||!isFinite(a)?0:Math.max(0,Math.min(r-s.left,s.width))/s.width*a},[T,n]),u=Et.useCallback(r=>{let s=T();return s?Math.max(0,Math.min(r-s.left,s.width)):0},[T]),i=Et.useCallback(r=>{let s=n.current;if(!s)return;let a=s.currentTime,P=isFinite(s.duration)?s.duration:0;switch(r.key){case "ArrowLeft":case "ArrowRight":{r.preventDefault(),r.nativeEvent.stopImmediatePropagation();let A=r.shiftKey?10:5;e.seek(r.key==="ArrowLeft"?Math.max(0,a-A):Math.min(P,a+A));break}case "Home":r.preventDefault(),r.nativeEvent.stopImmediatePropagation(),e.seek(0);break;case "End":P>0&&(r.preventDefault(),r.nativeEvent.stopImmediatePropagation(),e.seek(P));break}},[n,e]),L=Et.useCallback(r=>{let s=t(r.clientX),a=u(r.clientX);v.current=a,R.current=s,c.current&&(c.current.style.left=`${a}px`),m.current&&(m.current.style.left=`${a}px`),b.current&&(b.current.textContent=J(s)),X(s),E.current&&e.seek(s);},[e,X,t,u]),z=Et.useCallback(()=>{Q();},[Q]),w=Et.useCallback(()=>{q(),C();},[q,C]),h=Et.useCallback(r=>{r.preventDefault(),N(),e.seek(t(r.clientX));},[N,t,e]),g=Et.useCallback(()=>C(),[C]),U=Et.useCallback(r=>{E.current||e.seek(t(r.clientX));},[t,e]);Et.useEffect(()=>{let r=o.current;if(!r)return;let s=a=>{E.current&&a.preventDefault();};return r.addEventListener("touchmove",s,{passive:false}),()=>r.removeEventListener("touchmove",s)},[]);let j=Et.useCallback(r=>{y.current=null,N(),e.seek(t(r.touches[0].clientX));},[N,t,e]),D=Et.useCallback(r=>{E.current&&e.seek(t(r.touches[0].clientX));},[t,e]),ee=Et.useCallback(()=>C(),[C]);Et.useEffect(()=>{let r=()=>C();return window.addEventListener("mouseup",r),()=>window.removeEventListener("mouseup",r)},[C]);let Y=Et.useMemo(()=>{let r=n.current,s=r&&isFinite(r.duration)?r.duration:0;return s<=0||!x.length?null:x.map((a,P)=>{let A=a.start/s*100,ye=(a.end-a.start)/s*100;return jsxRuntime.jsx("div",{className:"bufferedSegment",style:{left:`${A}%`,width:`${ye}%`}},P)})},[x,n]);return jsxRuntime.jsxs("div",{ref:o,className:"progressContainer",onMouseMove:L,onMouseEnter:z,onMouseLeave:w,onMouseDown:h,onMouseUp:g,onClick:U,onTouchStart:j,onTouchMove:D,onTouchEnd:ee,onKeyDown:i,role:"slider","aria-label":"Video progress","aria-valuemin":0,"aria-valuemax":0,"aria-valuenow":0,"aria-valuetext":"0:00",tabIndex:0,children:[p&&jsxRuntime.jsxs("div",{ref:c,className:"previewTooltip",style:{left:0,display:"none"},"aria-hidden":"true",children:[l&&jsxRuntime.jsx("div",{ref:M,className:"previewThumbnail"}),jsxRuntime.jsx("div",{ref:b,className:"previewTime"})]}),jsxRuntime.jsxs("div",{className:"progressBackground",children:[Y,jsxRuntime.jsx("div",{ref:f,className:"progressFilled",style:{width:"0%"}}),p&&jsxRuntime.jsx("div",{ref:m,className:"hoverIndicator",style:{left:0,display:"none"},"aria-hidden":"true"})]}),jsxRuntime.jsx("div",{ref:d,className:"scrubHandle",style:{left:"0%"},"aria-hidden":"true"})]})});Ne.displayName="ProgressBar";var ve=Ne;var Oe=Et.memo(({currentRate:n,playbackRates:e,onRateChange:p,qualityLevels:l=[],currentQualityLevel:o=-1,onQualityChange:f})=>{let[d,c]=Et.useState(false),[b,m]=Et.useState("speed"),M=Et.useRef(null),x=l.length>0&&!!f;Et.useEffect(()=>{let v=R=>{M.current&&!M.current.contains(R.target)&&c(false);};return d&&document.addEventListener("mousedown",v),()=>document.removeEventListener("mousedown",v)},[d]);let V=Et.useMemo(()=>[...l].sort((v,R)=>R.bitrate-v.bitrate),[l]),E=Et.useMemo(()=>o===-1?"Auto":l.find(v=>v.id===o)?.name??"Auto",[l,o]);return jsxRuntime.jsxs("div",{ref:M,className:"settingsContainer",children:[jsxRuntime.jsx("button",{onClick:()=>c(v=>!v),className:"controlButton","aria-label":"Settings",title:"Settings","aria-expanded":d,children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("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"})})}),d&&jsxRuntime.jsxs("div",{className:"settingsDropdown",role:"menu",children:[x&&jsxRuntime.jsxs("div",{className:"settingsTabs",children:[jsxRuntime.jsx("button",{className:`settingsTab${b==="speed"?" active":""}`,onClick:()=>m("speed"),children:"Speed"}),jsxRuntime.jsx("button",{className:`settingsTab${b==="quality"?" active":""}`,onClick:()=>m("quality"),children:"Quality"})]}),(!x||b==="speed")&&jsxRuntime.jsxs("div",{children:[!x&&jsxRuntime.jsx("div",{className:"settingsPanelLabel",children:"Playback Speed"}),e.map(v=>jsxRuntime.jsx("button",{onClick:()=>{p(v),c(false);},className:`settingsOption${n===v?" active":""}`,role:"menuitemradio","aria-checked":n===v,children:v===1?"Normal":`${v}\xD7`},v))]}),x&&b==="quality"&&jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{f(-1),c(false);},className:`settingsOption${o===-1?" active":""}`,role:"menuitemradio","aria-checked":o===-1,children:["Auto ",o===-1&&E!=="Auto"?`(${E})`:""]}),V.map(v=>jsxRuntime.jsxs("button",{onClick:()=>{f(v.id),c(false);},className:`settingsOption${o===v.id?" active":""}`,role:"menuitemradio","aria-checked":o===v.id,children:[v.name,v.bitrate>0&&jsxRuntime.jsxs("span",{className:"settingsOptionBadge",children:[Math.round(v.bitrate/1e3)," kbps"]})]},v.id))]})]})]})});Oe.displayName="SettingsMenu";var he=Oe;var Ae=Et.memo(({videoRef:n,isLive:e=false})=>{let p=Et.useRef(null),l=Et.useRef(null);return Et.useEffect(()=>{let o=n.current;if(!o)return;let f=()=>{p.current&&(p.current.textContent=J(o.currentTime));},d=()=>{if(l.current){let c=isFinite(o.duration)?o.duration:0;l.current.textContent=` / ${J(c)}`;}};return o.addEventListener("timeupdate",f),o.addEventListener("durationchange",d),o.addEventListener("seeked",f),f(),d(),()=>{o.removeEventListener("timeupdate",f),o.removeEventListener("durationchange",d),o.removeEventListener("seeked",f);}},[n,e]),e?jsxRuntime.jsx("span",{className:"timeDisplay",style:{opacity:.7},children:jsxRuntime.jsx("span",{ref:p,children:"0:00"})}):jsxRuntime.jsxs("span",{className:"timeDisplay",children:[jsxRuntime.jsx("span",{ref:p,children:"0:00"}),jsxRuntime.jsx("span",{ref:l,style:{opacity:.6},children:" / 0:00"})]})});Ae.displayName="TimeDisplay";var be=Ae;var _={PlayButton:ie,PauseButton:se,FullscreenButton:le,PiPButton:ue,TheaterButton:ce,VolumeControl:fe,ProgressBar:ve,SettingsMenu:he,TimeDisplay:be};var xe=({videoRef:n,playerRef:e,playerContainerRef:p,playbackRates:l,enablePreview:o,thumbnailVtt:f,isPlaying:d,volume:c,isMuted:b,playbackRate:m,isFullscreen:M,isPictureInPicture:x,isTheaterMode:V,isLive:E,qualityLevels:v,currentQualityLevel:R})=>{let H=Et.useRef(null),k=Et.useRef(null),[y,T]=Et.useState(true),N=Et.useRef({isPlaying:d,volume:c,isMuted:b,isLive:E});N.current={isPlaying:d,volume:c,isMuted:b,isLive:E},Et.useEffect(()=>{if(!d){T(true),k.current&&clearTimeout(k.current);return}let h=()=>{T(true),k.current&&clearTimeout(k.current),k.current=setTimeout(()=>T(false),3e3);},g=H.current;return g&&(g.addEventListener("mousemove",h),g.addEventListener("mouseenter",h),g.addEventListener("touchstart",h,{passive:true})),h(),()=>{g&&(g.removeEventListener("mousemove",h),g.removeEventListener("mouseenter",h),g.removeEventListener("touchstart",h)),k.current&&clearTimeout(k.current);}},[d]),Et.useEffect(()=>{let h=g=>{if(!p.current?.contains(document.activeElement))return;let U=g.target;if(U.tagName==="INPUT"||U.tagName==="TEXTAREA"||U.isContentEditable)return;let{isPlaying:j,volume:D,isLive:ee}=N.current,Y=n.current?.currentTime??0,r=n.current?.duration??0;switch(g.code){case "Space":case "KeyK":g.preventDefault(),j?e.pause():e.play();break;case "ArrowLeft":g.preventDefault(),e.seek(Math.max(0,Y-5));break;case "ArrowRight":g.preventDefault(),e.seek(Math.min(r||1/0,Y+5));break;case "ArrowUp":g.preventDefault(),e.setVolume(Math.min(1,D+.1));break;case "ArrowDown":g.preventDefault(),e.setVolume(Math.max(0,D-.1));break;case "KeyM":g.preventDefault(),e.toggleMute();break;case "KeyF":g.preventDefault(),e.toggleFullscreen();break;case "KeyP":g.preventDefault(),e.togglePictureInPicture();break;case "KeyT":g.preventDefault(),e.toggleTheaterMode();break;case "KeyL":g.preventDefault(),ee&&e.seekToLive();break;case "Digit0":case "Digit1":case "Digit2":case "Digit3":case "Digit4":case "Digit5":case "Digit6":case "Digit7":case "Digit8":case "Digit9":{g.preventDefault();let s=Number(g.code.replace("Digit",""))*10;e.seek(r/100*s);break}}};return window.addEventListener("keydown",h),()=>window.removeEventListener("keydown",h)},[e,p,n]);let C=Et.useCallback(()=>e.play(),[e]),Q=Et.useCallback(()=>e.pause(),[e]),q=Et.useCallback(h=>e.setVolume(h),[e]),X=Et.useCallback(()=>e.toggleMute(),[e]),t=Et.useCallback(h=>e.setPlaybackRate(h),[e]),u=Et.useCallback(h=>e.setQualityLevel(h),[e]),i=Et.useCallback(()=>e.togglePictureInPicture(),[e]),L=Et.useCallback(()=>e.toggleTheaterMode(),[e]),z=Et.useCallback(()=>e.toggleFullscreen(),[e]),w=Et.useCallback(()=>e.seekToLive(),[e]);return jsxRuntime.jsx("div",{ref:H,style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",justifyContent:"flex-end",opacity:y?1:0,transition:"opacity 0.3s",pointerEvents:"none"},children:jsxRuntime.jsxs("div",{style:{background:"linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.2) 60%, transparent 100%)",padding:"48px 12px 12px",pointerEvents:y?"auto":"none"},role:"region","aria-label":"Video player controls",children:[jsxRuntime.jsx(_.ProgressBar,{videoRef:n,playerRef:e,enablePreview:o,thumbnailVtt:f}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,marginTop:4},children:[d?jsxRuntime.jsx(_.PauseButton,{onClick:Q}):jsxRuntime.jsx(_.PlayButton,{onClick:C}),jsxRuntime.jsx(_.VolumeControl,{volume:c,isMuted:b,onVolumeChange:q,onToggleMute:X}),jsxRuntime.jsx(_.TimeDisplay,{videoRef:n,isLive:E}),jsxRuntime.jsx("div",{style:{flex:1}}),E&&jsxRuntime.jsx(We,{onClick:w}),jsxRuntime.jsx(_.SettingsMenu,{currentRate:m,playbackRates:l,onRateChange:t,qualityLevels:v,currentQualityLevel:R,onQualityChange:u}),jsxRuntime.jsx(_.PiPButton,{onClick:i,isPiP:x}),jsxRuntime.jsx(_.TheaterButton,{onClick:L,isTheater:V}),jsxRuntime.jsx(_.FullscreenButton,{onClick:z,isFullscreen:M})]})]})})},We=Et.memo(({onClick:n})=>jsxRuntime.jsx("button",{onClick:n,style:{background:"none",border:"1px solid rgba(255,255,255,0.6)",color:"#fff",borderRadius:3,padding:"2px 8px",fontSize:11,fontWeight:700,cursor:"pointer",letterSpacing:"0.06em"},title:"Go to live (L)",children:"GO LIVE"}));We.displayName="GoLiveButton";var Ce=Et.memo(({x:n,y:e,isPlaying:p,src:l,videoRef:o,playerRef:f,onClose:d,contextMenuItems:c})=>{let b=Et.useRef(null),[m,M]=Et.useState(()=>o.current?.loop??false),x=Math.min(n,window.innerWidth-220),V=Math.min(e,window.innerHeight-290);Et.useEffect(()=>{let y=C=>{b.current&&!b.current.contains(C.target)&&d();},T=C=>{C.key==="Escape"&&d();},N=()=>d();return document.addEventListener("mousedown",y),document.addEventListener("keydown",T),window.addEventListener("scroll",N,true),()=>{document.removeEventListener("mousedown",y),document.removeEventListener("keydown",T),window.removeEventListener("scroll",N,true);}},[d]);let E=Et.useCallback(()=>{p?f.pause():f.play(),d();},[p,f,d]),v=Et.useCallback(()=>{let y=o.current;if(!y)return;let T=!m;y.loop=T,M(T);},[o,m]),R=Et.useCallback(async()=>{try{await navigator.clipboard.writeText(l);}catch{}d();},[l,d]),H=Et.useCallback(async()=>{let y=Math.floor(o.current?.currentTime??0);try{await navigator.clipboard.writeText(`${l}?t=${y}`);}catch{}d();},[l,o,d]),k=Et.useCallback(()=>{f.togglePictureInPicture(),d();},[f,d]);return jsxRuntime.jsxs("div",{ref:b,className:"contextMenu",style:{left:x,top:V},children:[jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:E,children:p?"Pause":"Play"}),jsxRuntime.jsxs("button",{className:"contextMenuItem",onClick:v,children:[jsxRuntime.jsx("span",{children:"Loop"}),m&&jsxRuntime.jsx("span",{className:"contextMenuCheck",children:"\u2713"})]}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:R,children:"Copy video URL"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:H,children:"Copy video URL at current time"}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:k,children:"Picture-in-Picture"}),c&&c.length>0&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{className:"contextMenuDivider"}),c.map((y,T)=>jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:()=>{y.onClick(),d();},children:y.label},T))]})]})});Ce.displayName="ContextMenu";var Qe=Et.forwardRef(({src:n,poster:e,autoplay:p=false,muted:l=false,loop:o=false,controls:f=true,preload:d="metadata",playbackRates:c=[.25,.5,.75,1,1.25,1.5,1.75,2],className:b,enableHLS:m=true,enablePreview:M=true,thumbnailVtt:x,hlsConfig:V,subtitles:E,crossOrigin:v,onPlay:R,onPause:H,onEnded:k,onError:y,onTimeUpdate:T,onDurationChange:N,onBuffering:C,onTheaterModeChange:Q,contextMenuItems:q},X)=>{let t=Et.useRef(null),u=Et.useRef(null),{state:i,ref:L,fullscreenContainerRef:z}=Be(t,n,{autoplay:p,muted:l,loop:o,playbackRates:c,enableHLS:m,hlsConfig:V,onPlay:R,onPause:H,onEnded:k,onError:y,onTimeUpdate:T,onDurationChange:N,onBuffering:C,onTheaterModeChange:Q}),[w,h]=Et.useState(null);Et.useEffect(()=>{z.current=u.current;},[z]),Et__default.default.useImperativeHandle(X,()=>L,[L]);let g=Et.useCallback(()=>{u.current?.focus(),i.isPlaying?L.pause():L.play();},[i.isPlaying,L]),U=Et.useCallback(()=>{L.toggleFullscreen();},[L]),j=Et.useCallback(D=>{D.preventDefault(),h({x:D.clientX,y:D.clientY});},[]);return jsxRuntime.jsxs("div",{ref:u,tabIndex:0,style:{position:"relative",width:"100%",backgroundColor:"#000",aspectRatio:"16 / 9",userSelect:"none",outline:"none"},className:b,"data-test":"video-player-container","data-theater":i.isTheaterMode?"true":void 0,onContextMenu:j,children:[jsxRuntime.jsx("video",{ref:t,poster:e,preload:d,crossOrigin:v,onClick:g,onDoubleClick:U,playsInline:true,style:{width:"100%",height:"100%",display:"block",cursor:"pointer"},"data-test":"video-element",children:E?.map(D=>jsxRuntime.jsx("track",{kind:"subtitles",src:D.src,label:D.label,srcLang:D.srclang,default:D.default},D.id))}),f&&jsxRuntime.jsx(xe,{videoRef:t,playerRef:L,playerContainerRef:u,playbackRates:c,enablePreview:M,thumbnailVtt:x,isPlaying:i.isPlaying,volume:i.volume,isMuted:i.isMuted,playbackRate:i.playbackRate,isFullscreen:i.isFullscreen,isPictureInPicture:i.isPictureInPicture,isTheaterMode:i.isTheaterMode,isLive:i.isLive,qualityLevels:i.qualityLevels,currentQualityLevel:i.currentQualityLevel}),w&&jsxRuntime.jsx(Ce,{x:w.x,y:w.y,isPlaying:i.isPlaying,src:n,videoRef:t,playerRef:L,onClose:()=>h(null),contextMenuItems:q}),i.isLive&&jsxRuntime.jsx("div",{style:{position:"absolute",top:12,left:12,backgroundColor:"#e53935",color:"#fff",fontSize:11,fontWeight:700,letterSpacing:"0.08em",padding:"2px 8px",borderRadius:3,pointerEvents:"none"},children:"LIVE"}),i.isBuffering&&!i.error&&jsxRuntime.jsxs("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",gap:12,color:"#fff",pointerEvents:"none"},"data-test":"buffering-indicator",children:[jsxRuntime.jsx("div",{style:{width:48,height:48,border:"4px solid rgba(255,255,255,0.25)",borderTop:"4px solid #fff",borderRadius:"50%",animation:"rvp-spin 0.8s linear infinite"}}),jsxRuntime.jsx("style",{children:"@keyframes rvp-spin { to { transform: rotate(360deg); } }"})]}),i.error&&jsxRuntime.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"rgba(0,0,0,0.85)",color:"#fff",padding:24},"data-test":"error-overlay",children:jsxRuntime.jsxs("div",{style:{textAlign:"center",maxWidth:400},children:[jsxRuntime.jsx("div",{style:{fontSize:36,marginBottom:12},children:"\u26A0"}),jsxRuntime.jsx("h3",{style:{margin:"0 0 8px",fontSize:18},children:i.error.code==="MEDIA_ERR_SRC_NOT_SUPPORTED"?"Unsupported Format":i.error.code.startsWith("HLS")?"Stream Error":"Playback Error"}),jsxRuntime.jsx("p",{style:{margin:0,fontSize:13,opacity:.75},children:i.error.message})]})})]})});Qe.displayName="VideoPlayer";var Mt=Qe;exports.ControlElements=_e;exports.Controls=xe;exports.VideoPlayer=Mt;exports.findThumbnailCue=Pe;exports.formatTime=J;exports.getMimeType=je;exports.isHLSUrl=me;exports.parseThumbnailVtt=Le;//# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map