react-helios 2.5.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # react-helios
2
2
 
3
- Production-grade React video player with HLS streaming, audio mode, adaptive quality selection, live stream support, subtitle tracks, VTT sprite sheet thumbnail preview, Picture-in-Picture, and full keyboard control.
3
+ Production-grade React video player with HLS streaming, zero-cost audio mode, adaptive quality selection, live stream support, subtitle tracks, VTT sprite sheet thumbnail preview, Picture-in-Picture, and full keyboard control.
4
4
 
5
5
  ## Installation
6
6
 
@@ -60,7 +60,7 @@ On Safari the browser's native HLS engine is used. A **LIVE** badge and **GO LIV
60
60
 
61
61
  ## Audio Mode
62
62
 
63
- Audio mode hides the video, shows the poster artwork, and keeps the audio stream playing useful when bandwidth is poor or the user wants to background the content.
63
+ Audio mode pauses the video element completely (stopping all video decoding), shows the poster artwork, and hands playback off to a lightweight `<audio>` elementso the player uses roughly the same CPU/GPU as a music app instead of a playing video.
64
64
 
65
65
  ```tsx
66
66
  <VideoPlayer
@@ -79,9 +79,13 @@ Audio mode hides the video, shows the poster artwork, and keeps the audio stream
79
79
 
80
80
  The audio toggle button only appears in the control bar when `audioSrc` is provided. Custom icons can be passed via `audioModeIcon` / `videoModeIcon`.
81
81
 
82
- ### Automatic bandwidth switching
82
+ When switching between modes, position, volume, and playback rate are synced automatically — the listener hears no gap.
83
83
 
84
- For HLS streams the player monitors bandwidth and switches to audio mode automatically when conditions drop below a threshold:
84
+ ### Automatic switching
85
+
86
+ The player uses two independent signals to detect poor conditions and switch to audio mode automatically. Either one firing is enough.
87
+
88
+ **Bandwidth-based** — measures the actual download speed of each HLS fragment and switches when the rolling average drops below a threshold:
85
89
 
86
90
  ```tsx
87
91
  import { AUDIO_BANDWIDTH_THRESHOLDS } from "react-helios";
@@ -89,8 +93,8 @@ import { AUDIO_BANDWIDTH_THRESHOLDS } from "react-helios";
89
93
  <VideoPlayer
90
94
  src="https://example.com/stream.m3u8"
91
95
  options={{
92
- audioBandwidthThreshold: AUDIO_BANDWIDTH_THRESHOLDS.POOR, // 300 Kbps (default)
93
- // audioBandwidthThreshold: 0, // disable automatic switching
96
+ audioBandwidthThreshold: AUDIO_BANDWIDTH_THRESHOLDS.FAIR, // recommended
97
+ // audioBandwidthThreshold: 0, // disable bandwidth-based switching
94
98
  }}
95
99
  />
96
100
  ```
@@ -98,11 +102,43 @@ import { AUDIO_BANDWIDTH_THRESHOLDS } from "react-helios";
98
102
  | Preset | Kbps | Typical connection |
99
103
  |--------|------|--------------------|
100
104
  | `EXTREME` | 100 | 2G / Edge |
101
- | `POOR` | 300 | Slow 3G ← **default** |
102
- | `FAIR` | 700 | 3G |
103
- | `GOOD` | 1500 | 4G / Wi-Fi |
105
+ | `POOR` | 300 | Slow 3G |
106
+ | `FAIR` | 800 | Marginal 3G ← **recommended** |
107
+ | `GOOD` | 1500 | Weak 4G / congested Wi-Fi |
108
+
109
+ **Level-based** — switches when HLS.js drops to a specific quality level (its own ABR algorithm already does the hard work):
110
+
111
+ ```tsx
112
+ import { AUDIO_SWITCH_LEVELS } from "react-helios";
113
+
114
+ <VideoPlayer
115
+ src="https://example.com/stream.m3u8"
116
+ options={{
117
+ audioModeSwitchLevel: AUDIO_SWITCH_LEVELS.LOWEST, // switch at lowest quality level
118
+ }}
119
+ />
120
+ ```
104
121
 
105
- After the user manually toggles audio mode a 60-second cooldown suppresses automatic switching so the player respects their choice.
122
+ | Preset | Value | Meaning |
123
+ |--------|-------|---------|
124
+ | `LOWEST` | 0 | Switch when HLS.js is at the lowest available quality |
125
+ | `SECOND_LOWEST` | 1 | Switch one level above the lowest |
126
+ | `DISABLED` | -1 | Disable level-based switching |
127
+
128
+ Using **both together** is the most reliable approach:
129
+
130
+ ```tsx
131
+ <VideoPlayer
132
+ src="https://example.com/stream.m3u8"
133
+ options={{
134
+ audioSrc: "https://example.com/audio-only.m3u8",
135
+ audioBandwidthThreshold: AUDIO_BANDWIDTH_THRESHOLDS.FAIR,
136
+ audioModeSwitchLevel: AUDIO_SWITCH_LEVELS.LOWEST,
137
+ }}
138
+ />
139
+ ```
140
+
141
+ After the user manually toggles audio mode a 60-second cooldown suppresses automatic switching. The player also probes for bandwidth recovery every 30 seconds while in auto-switched audio mode (configurable via `audioModeRecoveryInterval`).
106
142
 
107
143
  ## Thumbnail Preview
108
144
 
@@ -199,7 +235,9 @@ To disable the preview entirely:
199
235
  | `videoModeIcon` | `ReactNode` | built-in video icon | Icon shown when in audio mode (click → video) |
200
236
  | `audioModeFallback` | `ReactNode` | — | Custom content shown in audio mode when no `poster` is provided |
201
237
  | `logo` | `string \| ReactNode` | — | Logo shown in audio mode when no `poster` or `audioModeFallback` is provided |
202
- | `audioBandwidthThreshold` | `number` | `300` | Kbps — auto-switch to audio mode below this bandwidth. `0` = disabled (HLS only) |
238
+ | `audioBandwidthThreshold` | `number` | `300` | Kbps — switch when per-fragment bandwidth average drops below this. `0` = disabled (HLS only) |
239
+ | `audioModeSwitchLevel` | `number` | — | HLS quality level index — switch when HLS.js drops to this level or below. `0` = lowest. `-1` = disabled |
240
+ | `audioModeRecoveryInterval` | `number` | `30000` | Ms between recovery probes while in auto-switched audio mode |
203
241
 
204
242
  ### `options` — Callbacks
205
243
 
@@ -407,7 +445,7 @@ import type {
407
445
  ControlBarItem,
408
446
  } from "react-helios";
409
447
 
410
- import { AUDIO_BANDWIDTH_THRESHOLDS } from "react-helios";
448
+ import { AUDIO_BANDWIDTH_THRESHOLDS, AUDIO_SWITCH_LEVELS } from "react-helios";
411
449
 
412
450
  // VTT utilities (useful for server-side pre-parsing or custom UIs)
413
451
  import { parseThumbnailVtt, findThumbnailCue } from "react-helios";
@@ -525,11 +563,11 @@ if (cue) {
525
563
  The player is architected to produce **zero React re-renders during playback**:
526
564
 
527
565
  - `timeupdate` and `progress` events are handled by direct DOM mutation (refs), not React state.
528
- - `ProgressBar` and `TimeDisplay` self-subscribe to the video element — the parent tree never re-renders on seek or time change.
566
+ - `ProgressBar` and `TimeDisplay` self-subscribe to the active media element — the parent tree never re-renders on seek or time change.
529
567
  - `Controls` and `AudioModeOverlay` are wrapped in `React.memo` — they only re-render when their own props change, not when unrelated state (buffering, errors) updates.
530
568
  - VTT sprite thumbnails are looked up via binary search (O(log n)) and rendered via CSS `background-position` — no hidden `<video>` element, no canvas, no network requests per hover.
531
569
  - Buffered ranges are the only state that triggers a re-render (fires every few seconds during buffering, not 60× per second).
532
- - In audio mode the `<video>` element stays mounted with `visibility: hidden` audio keeps playing without any re-initialisation cost on toggle.
570
+ - In audio mode the `<video>` element is **paused** — the browser stops decoding frames entirely. A lightweight `<audio>` element takes over with `preload="none"` (no network cost at startup). The `<audio>` element only loads its source the first time the user switches to audio mode.
533
571
 
534
572
  ## Project Structure
535
573
 
package/dist/index.d.mts CHANGED
@@ -5,30 +5,57 @@ import { HlsConfig } from 'hls.js';
5
5
  /**
6
6
  * Preset bandwidth thresholds (Kbps) for automatic audio mode switching.
7
7
  *
8
- * | Preset | Kbps | Typical connection |
9
- * |-----------|------|-------------------------|
10
- * | EXTREME | 100 | 2G / Edge |
11
- * | POOR | 300 | Slow 3G ← **default** |
12
- * | FAIR | 700 | 3G |
13
- * | GOOD | 1500 | 4G / Wi-Fi |
8
+ * | Preset | Kbps | Typical connection |
9
+ * |-----------|------|--------------------------------|
10
+ * | EXTREME | 100 | 2G / Edge |
11
+ * | POOR | 300 | Slow 3G |
12
+ * | FAIR | 800 | Marginal 3G ← **recommended** |
13
+ * | GOOD | 1500 | Weak 4G / congested Wi-Fi |
14
14
  *
15
15
  * Pass any of these (or a custom number) as `audioBandwidthThreshold`.
16
- * Set to `0` to disable automatic switching entirely.
16
+ * Set to `0` to disable bandwidth-based switching entirely.
17
17
  *
18
18
  * @example
19
19
  * import { AUDIO_BANDWIDTH_THRESHOLDS } from "react-helios";
20
- * <VideoPlayer audioBandwidthThreshold={AUDIO_BANDWIDTH_THRESHOLDS.FAIR} ... />
20
+ * <VideoPlayer options={{ audioBandwidthThreshold: AUDIO_BANDWIDTH_THRESHOLDS.FAIR }} />
21
21
  */
22
22
  declare const AUDIO_BANDWIDTH_THRESHOLDS: {
23
23
  /** < 100 Kbps — very poor, 2G / Edge */
24
24
  readonly EXTREME: 100;
25
- /** < 300 Kbps — poor, slow 3G (default) */
25
+ /** < 300 Kbps — poor, slow 3G */
26
26
  readonly POOR: 300;
27
- /** < 700 Kbps — fair, 3G */
28
- readonly FAIR: 700;
29
- /** < 1500 Kbps — decent, 4G / Wi-Fi */
27
+ /** < 800 Kbps — marginal 3G ← **recommended default** */
28
+ readonly FAIR: 800;
29
+ /** < 1500 Kbps — weak 4G / congested Wi-Fi */
30
30
  readonly GOOD: 1500;
31
31
  };
32
+ /**
33
+ * Preset HLS quality level indices for automatic audio mode switching.
34
+ *
35
+ * When HLS.js drops to this level or below (due to poor bandwidth), the player
36
+ * automatically switches to audio mode. Level `0` is always the lowest quality
37
+ * available in the manifest.
38
+ *
39
+ * | Preset | Value | Meaning |
40
+ * |----------------|-------|-----------------------------------------------|
41
+ * | LOWEST | 0 | Switch when at the very lowest quality ← **recommended** |
42
+ * | SECOND_LOWEST | 1 | Switch one level above the lowest |
43
+ * | DISABLED | -1 | Disable level-based switching entirely |
44
+ *
45
+ * Works alongside `audioBandwidthThreshold` — whichever fires first wins.
46
+ *
47
+ * @example
48
+ * import { AUDIO_SWITCH_LEVELS } from "react-helios";
49
+ * <VideoPlayer options={{ audioModeSwitchLevel: AUDIO_SWITCH_LEVELS.LOWEST }} />
50
+ */
51
+ declare const AUDIO_SWITCH_LEVELS: {
52
+ /** Switch when HLS.js is at the lowest available quality (recommended default). */
53
+ readonly LOWEST: 0;
54
+ /** Switch when HLS.js drops to the second-lowest quality. */
55
+ readonly SECOND_LOWEST: 1;
56
+ /** Disable level-based auto-switching. */
57
+ readonly DISABLED: -1;
58
+ };
32
59
  interface BufferedRange {
33
60
  start: number;
34
61
  end: number;
@@ -130,7 +157,24 @@ interface VideoPlayerOptions {
130
157
  /** Label shown next to the icon when in audio mode (click → switches to video). Default: "Video" */
131
158
  videoModeLabel?: string;
132
159
  defaultAudioMode?: boolean;
160
+ /**
161
+ * Kbps — switch to audio mode when rolling average bandwidth drops below this value.
162
+ * `0` disables bandwidth-based switching. Default: `300` (slow 3G).
163
+ * Works alongside `audioModeSwitchLevel` — whichever fires first wins.
164
+ */
133
165
  audioBandwidthThreshold?: number;
166
+ /**
167
+ * HLS quality level index — switch to audio mode when HLS.js drops to this level or below.
168
+ * `0` = lowest quality (recommended default). `-1` disables level-based switching.
169
+ * Works alongside `audioBandwidthThreshold` — whichever fires first wins.
170
+ */
171
+ audioModeSwitchLevel?: number;
172
+ /**
173
+ * Milliseconds between automatic recovery probes while in auto-switched audio mode.
174
+ * The player briefly resumes video loading to sample bandwidth, then switches back
175
+ * to video if conditions have improved. Default: `30000` (30 seconds).
176
+ */
177
+ audioModeRecoveryInterval?: number;
134
178
  onPlay?: () => void;
135
179
  onPause?: () => void;
136
180
  onEnded?: () => void;
@@ -154,7 +198,7 @@ interface VideoPlayerProps {
154
198
  declare const VideoPlayer: react__default.ForwardRefExoticComponent<VideoPlayerProps & react__default.RefAttributes<VideoPlayerRef>>;
155
199
 
156
200
  interface ControlsProps {
157
- videoRef: react__default.RefObject<HTMLVideoElement | null>;
201
+ videoRef: react__default.RefObject<HTMLMediaElement | null>;
158
202
  playerRef: VideoPlayerRef;
159
203
  playerContainerRef: react__default.RefObject<HTMLElement | null>;
160
204
  playbackRates: PlaybackRate[];
@@ -182,7 +226,7 @@ interface ControlsProps {
182
226
  declare const Controls: react__default.NamedExoticComponent<ControlsProps>;
183
227
 
184
228
  interface TimeDisplayProps {
185
- videoRef: React.RefObject<HTMLVideoElement | null>;
229
+ videoRef: React.RefObject<HTMLMediaElement | null>;
186
230
  isLive?: boolean;
187
231
  }
188
232
  /**
@@ -203,7 +247,7 @@ interface SettingsMenuProps {
203
247
  declare const SettingsMenu: react.NamedExoticComponent<SettingsMenuProps>;
204
248
 
205
249
  interface ProgressBarProps {
206
- videoRef: react__default.RefObject<HTMLVideoElement | null>;
250
+ videoRef: react__default.RefObject<HTMLMediaElement | null>;
207
251
  playerRef: VideoPlayerRef;
208
252
  enablePreview?: boolean;
209
253
  thumbnailVtt?: string;
@@ -321,4 +365,4 @@ declare function parseThumbnailVtt(text: string, baseUrl?: string): ThumbnailCue
321
365
  */
322
366
  declare function findThumbnailCue(cues: ThumbnailCue[], time: number): ThumbnailCue | null;
323
367
 
324
- export { AUDIO_BANDWIDTH_THRESHOLDS, type BufferedRange, type ContextMenuItem, type ControlBarItem, index as ControlElements, Controls, type HLSQualityLevel, type PlaybackRate, type PlayerState, type SubtitleTrack, type ThumbnailCue, type VideoError, type VideoErrorCode, VideoPlayer, type VideoPlayerOptions, type VideoPlayerProps, type VideoPlayerRef, findThumbnailCue, formatTime, getMimeType, isHLSUrl, parseThumbnailVtt };
368
+ export { AUDIO_BANDWIDTH_THRESHOLDS, AUDIO_SWITCH_LEVELS, type BufferedRange, type ContextMenuItem, type ControlBarItem, index as ControlElements, Controls, type HLSQualityLevel, type PlaybackRate, type PlayerState, type SubtitleTrack, type ThumbnailCue, type VideoError, type VideoErrorCode, VideoPlayer, type VideoPlayerOptions, type VideoPlayerProps, type VideoPlayerRef, findThumbnailCue, formatTime, getMimeType, isHLSUrl, parseThumbnailVtt };
package/dist/index.d.ts CHANGED
@@ -5,30 +5,57 @@ import { HlsConfig } from 'hls.js';
5
5
  /**
6
6
  * Preset bandwidth thresholds (Kbps) for automatic audio mode switching.
7
7
  *
8
- * | Preset | Kbps | Typical connection |
9
- * |-----------|------|-------------------------|
10
- * | EXTREME | 100 | 2G / Edge |
11
- * | POOR | 300 | Slow 3G ← **default** |
12
- * | FAIR | 700 | 3G |
13
- * | GOOD | 1500 | 4G / Wi-Fi |
8
+ * | Preset | Kbps | Typical connection |
9
+ * |-----------|------|--------------------------------|
10
+ * | EXTREME | 100 | 2G / Edge |
11
+ * | POOR | 300 | Slow 3G |
12
+ * | FAIR | 800 | Marginal 3G ← **recommended** |
13
+ * | GOOD | 1500 | Weak 4G / congested Wi-Fi |
14
14
  *
15
15
  * Pass any of these (or a custom number) as `audioBandwidthThreshold`.
16
- * Set to `0` to disable automatic switching entirely.
16
+ * Set to `0` to disable bandwidth-based switching entirely.
17
17
  *
18
18
  * @example
19
19
  * import { AUDIO_BANDWIDTH_THRESHOLDS } from "react-helios";
20
- * <VideoPlayer audioBandwidthThreshold={AUDIO_BANDWIDTH_THRESHOLDS.FAIR} ... />
20
+ * <VideoPlayer options={{ audioBandwidthThreshold: AUDIO_BANDWIDTH_THRESHOLDS.FAIR }} />
21
21
  */
22
22
  declare const AUDIO_BANDWIDTH_THRESHOLDS: {
23
23
  /** < 100 Kbps — very poor, 2G / Edge */
24
24
  readonly EXTREME: 100;
25
- /** < 300 Kbps — poor, slow 3G (default) */
25
+ /** < 300 Kbps — poor, slow 3G */
26
26
  readonly POOR: 300;
27
- /** < 700 Kbps — fair, 3G */
28
- readonly FAIR: 700;
29
- /** < 1500 Kbps — decent, 4G / Wi-Fi */
27
+ /** < 800 Kbps — marginal 3G ← **recommended default** */
28
+ readonly FAIR: 800;
29
+ /** < 1500 Kbps — weak 4G / congested Wi-Fi */
30
30
  readonly GOOD: 1500;
31
31
  };
32
+ /**
33
+ * Preset HLS quality level indices for automatic audio mode switching.
34
+ *
35
+ * When HLS.js drops to this level or below (due to poor bandwidth), the player
36
+ * automatically switches to audio mode. Level `0` is always the lowest quality
37
+ * available in the manifest.
38
+ *
39
+ * | Preset | Value | Meaning |
40
+ * |----------------|-------|-----------------------------------------------|
41
+ * | LOWEST | 0 | Switch when at the very lowest quality ← **recommended** |
42
+ * | SECOND_LOWEST | 1 | Switch one level above the lowest |
43
+ * | DISABLED | -1 | Disable level-based switching entirely |
44
+ *
45
+ * Works alongside `audioBandwidthThreshold` — whichever fires first wins.
46
+ *
47
+ * @example
48
+ * import { AUDIO_SWITCH_LEVELS } from "react-helios";
49
+ * <VideoPlayer options={{ audioModeSwitchLevel: AUDIO_SWITCH_LEVELS.LOWEST }} />
50
+ */
51
+ declare const AUDIO_SWITCH_LEVELS: {
52
+ /** Switch when HLS.js is at the lowest available quality (recommended default). */
53
+ readonly LOWEST: 0;
54
+ /** Switch when HLS.js drops to the second-lowest quality. */
55
+ readonly SECOND_LOWEST: 1;
56
+ /** Disable level-based auto-switching. */
57
+ readonly DISABLED: -1;
58
+ };
32
59
  interface BufferedRange {
33
60
  start: number;
34
61
  end: number;
@@ -130,7 +157,24 @@ interface VideoPlayerOptions {
130
157
  /** Label shown next to the icon when in audio mode (click → switches to video). Default: "Video" */
131
158
  videoModeLabel?: string;
132
159
  defaultAudioMode?: boolean;
160
+ /**
161
+ * Kbps — switch to audio mode when rolling average bandwidth drops below this value.
162
+ * `0` disables bandwidth-based switching. Default: `300` (slow 3G).
163
+ * Works alongside `audioModeSwitchLevel` — whichever fires first wins.
164
+ */
133
165
  audioBandwidthThreshold?: number;
166
+ /**
167
+ * HLS quality level index — switch to audio mode when HLS.js drops to this level or below.
168
+ * `0` = lowest quality (recommended default). `-1` disables level-based switching.
169
+ * Works alongside `audioBandwidthThreshold` — whichever fires first wins.
170
+ */
171
+ audioModeSwitchLevel?: number;
172
+ /**
173
+ * Milliseconds between automatic recovery probes while in auto-switched audio mode.
174
+ * The player briefly resumes video loading to sample bandwidth, then switches back
175
+ * to video if conditions have improved. Default: `30000` (30 seconds).
176
+ */
177
+ audioModeRecoveryInterval?: number;
134
178
  onPlay?: () => void;
135
179
  onPause?: () => void;
136
180
  onEnded?: () => void;
@@ -154,7 +198,7 @@ interface VideoPlayerProps {
154
198
  declare const VideoPlayer: react__default.ForwardRefExoticComponent<VideoPlayerProps & react__default.RefAttributes<VideoPlayerRef>>;
155
199
 
156
200
  interface ControlsProps {
157
- videoRef: react__default.RefObject<HTMLVideoElement | null>;
201
+ videoRef: react__default.RefObject<HTMLMediaElement | null>;
158
202
  playerRef: VideoPlayerRef;
159
203
  playerContainerRef: react__default.RefObject<HTMLElement | null>;
160
204
  playbackRates: PlaybackRate[];
@@ -182,7 +226,7 @@ interface ControlsProps {
182
226
  declare const Controls: react__default.NamedExoticComponent<ControlsProps>;
183
227
 
184
228
  interface TimeDisplayProps {
185
- videoRef: React.RefObject<HTMLVideoElement | null>;
229
+ videoRef: React.RefObject<HTMLMediaElement | null>;
186
230
  isLive?: boolean;
187
231
  }
188
232
  /**
@@ -203,7 +247,7 @@ interface SettingsMenuProps {
203
247
  declare const SettingsMenu: react.NamedExoticComponent<SettingsMenuProps>;
204
248
 
205
249
  interface ProgressBarProps {
206
- videoRef: react__default.RefObject<HTMLVideoElement | null>;
250
+ videoRef: react__default.RefObject<HTMLMediaElement | null>;
207
251
  playerRef: VideoPlayerRef;
208
252
  enablePreview?: boolean;
209
253
  thumbnailVtt?: string;
@@ -321,4 +365,4 @@ declare function parseThumbnailVtt(text: string, baseUrl?: string): ThumbnailCue
321
365
  */
322
366
  declare function findThumbnailCue(cues: ThumbnailCue[], time: number): ThumbnailCue | null;
323
367
 
324
- export { AUDIO_BANDWIDTH_THRESHOLDS, type BufferedRange, type ContextMenuItem, type ControlBarItem, index as ControlElements, Controls, type HLSQualityLevel, type PlaybackRate, type PlayerState, type SubtitleTrack, type ThumbnailCue, type VideoError, type VideoErrorCode, VideoPlayer, type VideoPlayerOptions, type VideoPlayerProps, type VideoPlayerRef, findThumbnailCue, formatTime, getMimeType, isHLSUrl, parseThumbnailVtt };
368
+ export { AUDIO_BANDWIDTH_THRESHOLDS, AUDIO_SWITCH_LEVELS, type BufferedRange, type ContextMenuItem, type ControlBarItem, index as ControlElements, Controls, type HLSQualityLevel, type PlaybackRate, type PlayerState, type SubtitleTrack, type ThumbnailCue, type VideoError, type VideoErrorCode, VideoPlayer, type VideoPlayerOptions, type VideoPlayerProps, type VideoPlayerRef, findThumbnailCue, formatTime, getMimeType, isHLSUrl, parseThumbnailVtt };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- 'use strict';var Dt=require('react'),Ee=require('hls.js'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Dt__default=/*#__PURE__*/_interopDefault(Dt);var Ee__default=/*#__PURE__*/_interopDefault(Ee);var ot=Object.defineProperty;var it=(n,t)=>{for(var r in t)ot(n,r,{get:t[r],enumerable:true});};function se(n){if(!Number.isFinite(n)||n<0)return "0:00";let t=Math.floor(n),r=Math.floor(t/3600),s=Math.floor(t%3600/60),a=t%60;return r>0?`${r}:${String(s).padStart(2,"0")}:${String(a).padStart(2,"0")}`:`${s}:${String(a).padStart(2,"0")}`}function ye(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 at(n){if(ye(n))return "application/x-mpegURL";let t=n.toLowerCase().split("?")[0];return t.endsWith(".mp4")?"video/mp4":t.endsWith(".webm")?"video/webm":t.endsWith(".ogv")||t.endsWith(".ogg")?"video/ogg":t.endsWith(".mov")?"video/quicktime":"video/mp4"}function Oe(n){return n.map((t,r)=>({id:r,height:t.height??0,width:t.width??0,bitrate:t.bitrate??0,name:t.height?`${t.height}p`:`Level ${r+1}`}))}var ut={isPlaying:false,currentTime:0,duration:0,volume:1,isMuted:false,playbackRate:1,isFullscreen:false,isPictureInPicture:false,isTheaterMode:false,isAudioMode:false,isBuffering:false,bufferedRanges:[],error:null,isLive:false,qualityLevels:[],currentQualityLevel:-1};function _e(n,t,r={}){let s=Dt.useRef(null),a=Dt.useRef(null),p=Dt.useRef(1),u=Dt.useRef(0),l=Dt.useRef(r);l.current=r;let[L,c]=Dt.useState({...ut,isMuted:r.muted??false,volume:r.muted?0:1,isAudioMode:r.defaultAudioMode??false}),C=Dt.useRef(L);C.current=L;let k=Dt.useRef([]),R=Dt.useRef(false),T=Dt.useRef(false),m=Dt.useRef(null);Dt.useEffect(()=>{let e=n.current;if(!e||(s.current&&(s.current.destroy(),s.current=null),u.current=0,k.current=[],R.current=false,T.current=false,m.current&&(clearTimeout(m.current),m.current=null),c(v=>({...v,currentTime:0,duration:0,error:null,isBuffering:false,isLive:false,qualityLevels:[],currentQualityLevel:-1,isAudioMode:l.current.defaultAudioMode??false})),!t))return;let d=l.current;if(d.enableHLS!==false&&ye(t)){if(e.canPlayType("application/vnd.apple.mpegurl"))e.src=t,e.load(),d.autoplay&&e.play().catch(()=>{});else if(Ee__default.default.isSupported()){let v=new Ee__default.default({autoStartLoad:true,startLevel:-1,capLevelToPlayerSize:true,capLevelOnFPSDrop:true,enableWorker:true,maxBufferLength:30,maxMaxBufferLength:600,maxBufferSize:6e7,liveBackBufferLength:30,liveSyncDurationCount:3,...d.hlsConfig});v.attachMedia(e),v.loadSource(t),v.on(Ee.Events.MANIFEST_PARSED,(O,o)=>{let i=Oe(o.levels);c(f=>({...f,qualityLevels:i,currentQualityLevel:-1})),l.current.autoplay&&e.play().catch(()=>{});}),v.on(Ee.Events.LEVEL_SWITCHED,(O,o)=>{c(i=>({...i,currentQualityLevel:o.level}));}),v.on(Ee.Events.FRAG_LOADED,()=>{let O=l.current.audioBandwidthThreshold??300;if(!O||T.current)return;let o=v.bandwidthEstimate/1e3;if(o<=0)return;let i=k.current;if(i.push(o),i.length>5&&i.shift(),i.length<3)return;let f=i.reduce((y,S)=>y+S,0)/i.length;c(y=>!y.isAudioMode&&f<O?(R.current=true,l.current.onAudioModeChange?.(true),{...y,isAudioMode:true}):y.isAudioMode&&R.current&&f>O*1.5?(R.current=false,l.current.onAudioModeChange?.(false),{...y,isAudioMode:false}):y);});let V=3;v.on(Ee.Events.ERROR,(O,o)=>{if(!o.fatal){console.warn("[hls] non-fatal:",o.details);return}switch(o.type){case Ee__default.default.ErrorTypes.NETWORK_ERROR:if(u.current<V){u.current+=1;let i=1e3*u.current;console.warn(`[hls] network error \u2013 retry ${u.current}/${V} in ${i}ms`),setTimeout(()=>{s.current===v&&v.startLoad();},i);}else {let i={code:"HLS_NETWORK_ERROR",message:"Failed to load stream after multiple retries."};c(f=>({...f,error:i})),l.current.onError?.(i);}break;case Ee__default.default.ErrorTypes.MEDIA_ERROR:console.warn("[hls] media error \u2013 recovering"),v.recoverMediaError();break;default:{v.destroy(),s.current=null;let i={code:"HLS_FATAL_ERROR",message:"An unrecoverable HLS error occurred."};c(f=>({...f,error:i})),l.current.onError?.(i);break}}}),s.current=v;}}else e.src=t,e.load(),d.autoplay&&e.play().catch(()=>{});return ()=>{s.current&&(s.current.destroy(),s.current=null),m.current&&(clearTimeout(m.current),m.current=null);}},[t,n]),Dt.useEffect(()=>{let e=n.current;if(!e)return;l.current.muted&&(e.muted=true),l.current.loop&&(e.loop=true);let d=()=>{c(b=>({...b,isPlaying:true})),l.current.onPlay?.();},v=()=>{c(b=>({...b,isPlaying:false})),l.current.onPause?.();},V=()=>{c(b=>({...b,isPlaying:false})),l.current.onEnded?.();},O=()=>{l.current.onTimeUpdate?.(e.currentTime);},o=()=>{let b=e.duration,z=!Number.isFinite(b);c(j=>({...j,duration:z?0:b,isLive:z})),z||l.current.onDurationChange?.(b);},i=()=>{let b=e.volume;b>0&&!e.muted&&(p.current=b),c(z=>({...z,volume:b,isMuted:e.muted||b===0}));},f=()=>{c(b=>({...b,playbackRate:e.playbackRate}));},y=()=>{let b=e.error;if(!b)return;let j={code:{1:"MEDIA_ERR_ABORTED",2:"MEDIA_ERR_NETWORK",3:"MEDIA_ERR_DECODE",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"}[b.code]??"UNKNOWN",message:b.message||"Unknown media error"};c(ae=>({...ae,error:j})),l.current.onError?.(j);},S=()=>{c(b=>({...b,isBuffering:true})),l.current.onBuffering?.(true);},h=()=>{c(b=>({...b,isBuffering:false})),l.current.onBuffering?.(false);},E=()=>c(b=>({...b,isBuffering:false})),g=()=>{let b=!!(document.fullscreenElement||document.webkitFullscreenElement);c(z=>({...z,isFullscreen:b}));},A=()=>{c(b=>({...b,isPictureInPicture:document.pictureInPictureElement===e}));};return e.addEventListener("play",d),e.addEventListener("pause",v),e.addEventListener("ended",V),e.addEventListener("timeupdate",O),e.addEventListener("durationchange",o),e.addEventListener("volumechange",i),e.addEventListener("ratechange",f),e.addEventListener("error",y),e.addEventListener("waiting",S),e.addEventListener("canplay",h),e.addEventListener("playing",E),document.addEventListener("fullscreenchange",g),document.addEventListener("webkitfullscreenchange",g),e.addEventListener("enterpictureinpicture",A),e.addEventListener("leavepictureinpicture",A),()=>{e.removeEventListener("play",d),e.removeEventListener("pause",v),e.removeEventListener("ended",V),e.removeEventListener("timeupdate",O),e.removeEventListener("durationchange",o),e.removeEventListener("volumechange",i),e.removeEventListener("ratechange",f),e.removeEventListener("error",y),e.removeEventListener("waiting",S),e.removeEventListener("canplay",h),e.removeEventListener("playing",E),document.removeEventListener("fullscreenchange",g),document.removeEventListener("webkitfullscreenchange",g),e.removeEventListener("enterpictureinpicture",A),e.removeEventListener("leavepictureinpicture",A);}},[n]);let B=Dt.useCallback(async()=>{let e=n.current;if(e)try{await e.play();}catch(d){d instanceof Error&&d.name!=="AbortError"&&console.error("[player] play() failed:",d);}},[n]),I=Dt.useCallback(()=>{n.current?.pause();},[n]),_=Dt.useCallback(e=>{let d=n.current;d&&(d.currentTime=Math.max(0,Math.min(e,d.duration||e)));},[n]),P=Dt.useCallback(e=>{let d=n.current;if(!d)return;let v=Math.max(0,Math.min(e,1));v>0&&(p.current=v),d.volume=v,d.muted=v===0;},[n]),x=Dt.useCallback(()=>{let e=n.current;if(e)if(e.muted||e.volume===0){let d=p.current>0?p.current:1;e.volume=d,e.muted=false;}else p.current=e.volume,e.muted=true;},[n]),D=Dt.useCallback(e=>{let d=n.current;d&&(d.playbackRate=e);},[n]),N=Dt.useCallback(e=>{let d=s.current;d&&(d.currentLevel=e,c(v=>({...v,currentQualityLevel:e})));},[]),ne=Dt.useCallback(()=>{let e=s.current,d=n.current;if(!e||!d)return;let v=e.liveSyncPosition;v!=null&&Number.isFinite(v)&&(d.currentTime=v);},[n]),Z=Dt.useCallback(async()=>{let e=n.current;if(!e)return;let d=a.current??e.parentElement;if(d)try{!document.fullscreenElement&&!document.webkitFullscreenElement?d.requestFullscreen?await d.requestFullscreen():d.webkitRequestFullscreen?.():document.exitFullscreen?await document.exitFullscreen():document.webkitExitFullscreen?.();}catch(v){console.error("[player] fullscreen toggle failed:",v);}},[n]),X=Dt.useCallback(async()=>{let e=n.current;if(e)try{document.pictureInPictureElement?await document.exitPictureInPicture():await e.requestPictureInPicture();}catch(d){console.error("[player] PiP toggle failed:",d);}},[n]),M=Dt.useCallback(()=>{let e=!C.current.isTheaterMode;c(d=>({...d,isTheaterMode:e})),l.current.onTheaterModeChange?.(e);},[]),G=Dt.useCallback(()=>{m.current&&clearTimeout(m.current),R.current=false,T.current=true,m.current=setTimeout(()=>{T.current=false,k.current=[];},6e4);let e=!C.current.isAudioMode;c(d=>({...d,isAudioMode:e})),l.current.onAudioModeChange?.(e);},[]),U=Dt.useCallback(()=>{let e=n.current,d=e?.currentTime??0,v=[];if(e)for(let V=0;V<e.buffered.length;V++)v.push({start:e.buffered.start(V),end:e.buffered.end(V)});return {...C.current,currentTime:d,bufferedRanges:v}},[n]),ee=Dt.useCallback(()=>n.current??null,[n]),ie=Dt.useMemo(()=>({play:B,pause:I,seek:_,setVolume:P,toggleMute:x,setPlaybackRate:D,setQualityLevel:N,seekToLive:ne,toggleFullscreen:Z,togglePictureInPicture:X,toggleTheaterMode:M,toggleAudioMode:G,getState:U,getVideoElement:ee}),[B,I,_,P,x,D,N,ne,Z,X,M,G,U,ee]);return {state:L,ref:ie,hlsRef:s,fullscreenContainerRef:a}}var Ge={};it(Ge,{ControlElements:()=>Q,FullscreenButton:()=>ve,PauseButton:()=>pe,PiPButton:()=>he,PlayButton:()=>fe,ProgressBar:()=>Pe,SettingsMenu:()=>Te,TheaterButton:()=>ge,TimeDisplay:()=>ke,VolumeControl:()=>Le});var fe=Dt.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"})})}));fe.displayName="PlayButton";var pe=Dt.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"})})}));pe.displayName="PauseButton";var ve=Dt.memo(({onClick:n,isFullscreen:t=false})=>jsxRuntime.jsx("button",{onClick:n,className:"controlButton","aria-label":t?"Exit Fullscreen":"Fullscreen",title:t?"Exit Fullscreen (F)":"Fullscreen (F)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:t?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"})})}));ve.displayName="FullscreenButton";var he=Dt.memo(({onClick:n,isPiP:t=false})=>jsxRuntime.jsx("button",{onClick:n,className:"controlButton","aria-label":t?"Exit Picture-in-Picture":"Picture-in-Picture",title:t?"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"})})}));he.displayName="PiPButton";var ge=Dt.memo(({onClick:n,isTheater:t=false})=>jsxRuntime.jsx("button",{onClick:n,className:"controlButton","aria-label":t?"Exit Theater Mode":"Theater Mode",title:t?"Exit Theater Mode (T)":"Theater Mode (T)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:t?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"})})}));ge.displayName="TheaterButton";var ze=Dt.memo(({volume:n,isMuted:t,onVolumeChange:r,onToggleMute:s})=>{let[a,p]=Dt.useState(false),u=t?0:n,l=u*100,L=Dt.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:()=>p(true),onMouseLeave:()=>p(false),children:[jsxRuntime.jsx("button",{onClick:s,className:"controlButton","aria-label":t?"Unmute":"Mute",title:t?"Unmute (M)":"Mute (M)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:u===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"}):u<.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:c=>r(Number(c.target.value)/100),className:"volumeSlider",style:{background:L},"aria-label":"Volume","aria-valuenow":Math.round(l)})]})});ze.displayName="VolumeControl";var Le=ze;function $e(n){let t=n.trim().split(":");return t.length===3?+t[0]*3600+ +t[1]*60+parseFloat(t[2]):+t[0]*60+parseFloat(t[1])}function pt(n,t){if(/^https?:\/\//i.test(t))return t;try{return new URL(t,n).href}catch{return t}}function Re(n,t=""){let r=[],s=n.replace(/\r\n/g,`
1
+ 'use strict';var ot=require('react'),Ce=require('hls.js'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var ot__default=/*#__PURE__*/_interopDefault(ot);var Ce__default=/*#__PURE__*/_interopDefault(Ce);var lt=Object.defineProperty;var ct=(i,r)=>{for(var o in r)lt(i,o,{get:r[o],enumerable:true});};function ce(i){if(!Number.isFinite(i)||i<0)return "0:00";let r=Math.floor(i),o=Math.floor(r/3600),u=Math.floor(r%3600/60),s=r%60;return o>0?`${o}:${String(u).padStart(2,"0")}:${String(s).padStart(2,"0")}`:`${u}:${String(s).padStart(2,"0")}`}function Pe(i){try{return new URL(i,"https://x").pathname.toLowerCase().endsWith(".m3u8")||/\/hls\//i.test(i)||/\/stream\.m3u8/i.test(i)}catch{return i.toLowerCase().includes(".m3u8")}}function dt(i){if(Pe(i))return "application/x-mpegURL";let r=i.toLowerCase().split("?")[0];return r.endsWith(".mp4")?"video/mp4":r.endsWith(".webm")?"video/webm":r.endsWith(".ogv")||r.endsWith(".ogg")?"video/ogg":r.endsWith(".mov")?"video/quicktime":"video/mp4"}function Ue(i){return i.map((r,o)=>({id:o,height:r.height??0,width:r.width??0,bitrate:r.bitrate??0,name:r.height?`${r.height}p`:`Level ${o+1}`}))}var vt={isPlaying:false,currentTime:0,duration:0,volume:1,isMuted:false,playbackRate:1,isFullscreen:false,isPictureInPicture:false,isTheaterMode:false,isAudioMode:false,isBuffering:false,bufferedRanges:[],error:null,isLive:false,qualityLevels:[],currentQualityLevel:-1};function $e(i,r,o={}){let u=ot.useRef(null),s=ot.useRef(null),h=ot.useRef(1),d=ot.useRef(0),a=ot.useRef(o);a.current=o;let[L,l]=ot.useState({...vt,isMuted:o.muted??false,volume:o.muted?0:1,isAudioMode:o.defaultAudioMode??false}),T=ot.useRef(L);T.current=L;let S=ot.useRef([]),F=ot.useRef(0),C=ot.useRef(false),p=ot.useRef(false),x=ot.useRef(null),P=ot.useRef(null),A=ot.useRef(false),b=ot.useCallback(()=>{let e=a.current;return T.current.isAudioMode&&e.audioSrc&&e.audioRef?.current?e.audioRef.current:i.current},[i]);ot.useEffect(()=>{let e=i.current;if(!e||(u.current&&(u.current.destroy(),u.current=null),d.current=0,S.current=[],F.current=0,C.current=false,p.current=false,x.current&&(clearTimeout(x.current),x.current=null),P.current&&(clearTimeout(P.current),P.current=null),A.current=false,l(n=>({...n,currentTime:0,duration:0,error:null,isBuffering:false,isLive:false,qualityLevels:[],currentQualityLevel:-1,isAudioMode:a.current.defaultAudioMode??false})),!r))return;let t=a.current;if(t.enableHLS!==false&&Pe(r)){if(e.canPlayType("application/vnd.apple.mpegurl"))e.src=r,e.load(),t.autoplay&&e.play().catch(()=>{});else if(Ce__default.default.isSupported()){let n=new Ce__default.default({autoStartLoad:true,startLevel:-1,capLevelToPlayerSize:true,capLevelOnFPSDrop:true,enableWorker:true,maxBufferLength:30,maxMaxBufferLength:600,maxBufferSize:6e7,liveBackBufferLength:30,liveSyncDurationCount:3,...t.hlsConfig});n.attachMedia(e),n.loadSource(r),n.on(Ce.Events.MANIFEST_PARSED,(k,c)=>{let f=Ue(c.levels);l(M=>({...M,qualityLevels:f,currentQualityLevel:-1})),a.current.autoplay&&e.play().catch(()=>{});}),n.on(Ce.Events.LEVEL_SWITCHED,(k,c)=>{l(w=>({...w,currentQualityLevel:c.level}));let f=a.current,M=f.audioModeSwitchLevel;M===void 0||M<0||!f.audioSrc||p.current||F.current<3||l(w=>!w.isAudioMode&&c.level<=M?(C.current=true,a.current.onAudioModeChange?.(true),{...w,isAudioMode:true}):w);}),n.on(Ce.Events.FRAG_LOADED,(k,c)=>{let f=a.current;if(!f.audioSrc)return;F.current+=1;let M=c.stats.loading.end-c.stats.loading.start,w=M>0&&c.stats.total>0?c.stats.total*8/M:0,E=f.audioBandwidthThreshold??300;if(A.current){A.current=false,w>0&&E&&w>E*1.5?(C.current=false,n.startLoad(),a.current.onAudioModeChange?.(false),l(V=>({...V,isAudioMode:false}))):(n.stopLoad(),m());return}if(!E||p.current||w<=0)return;let v=S.current;if(v.push(w),v.length>5&&v.shift(),v.length<2)return;let N=v.reduce((V,g)=>V+g,0)/v.length;l(V=>!V.isAudioMode&&N<E?(C.current=true,a.current.onAudioModeChange?.(true),{...V,isAudioMode:true}):V);});let m=()=>{P.current&&clearTimeout(P.current);let k=a.current.audioModeRecoveryInterval??3e4;P.current=setTimeout(()=>{!C.current||!T.current.isAudioMode||(A.current=true,n.startLoad());},k);},y=3;n.on(Ce.Events.ERROR,(k,c)=>{if(!c.fatal){console.warn("[hls] non-fatal:",c.details);return}switch(c.type){case Ce__default.default.ErrorTypes.NETWORK_ERROR:if(d.current<y){d.current+=1;let f=1e3*d.current;console.warn(`[hls] network error \u2013 retry ${d.current}/${y} in ${f}ms`),setTimeout(()=>{u.current===n&&n.startLoad();},f);}else {let f={code:"HLS_NETWORK_ERROR",message:"Failed to load stream after multiple retries."};l(M=>({...M,error:f})),a.current.onError?.(f);}break;case Ce__default.default.ErrorTypes.MEDIA_ERROR:console.warn("[hls] media error \u2013 recovering"),n.recoverMediaError();break;default:{n.destroy(),u.current=null;let f={code:"HLS_FATAL_ERROR",message:"An unrecoverable HLS error occurred."};l(M=>({...M,error:f})),a.current.onError?.(f);break}}}),u.current=n;}}else e.src=r,e.load(),t.autoplay&&e.play().catch(()=>{});return ()=>{u.current&&(u.current.destroy(),u.current=null),x.current&&(clearTimeout(x.current),x.current=null),P.current&&(clearTimeout(P.current),P.current=null),A.current=false;let n=a.current.audioRef?.current;n&&(n.pause(),n.removeAttribute("src"),n.load());}},[r,i]),ot.useEffect(()=>{let e=i.current;if(!e)return;a.current.muted&&(e.muted=true),a.current.loop&&(e.loop=true);let t=()=>{l(g=>({...g,isPlaying:true})),a.current.onPlay?.();},n=()=>{l(g=>({...g,isPlaying:false})),a.current.onPause?.();},m=()=>{l(g=>({...g,isPlaying:false})),a.current.onEnded?.();},y=()=>{T.current.isAudioMode&&a.current.audioSrc||a.current.onTimeUpdate?.(e.currentTime);},k=()=>{let g=e.duration,Q=!Number.isFinite(g);l(le=>({...le,duration:Q?0:g,isLive:Q})),Q||a.current.onDurationChange?.(g);},c=()=>{let g=e.volume;g>0&&!e.muted&&(h.current=g),l(Q=>({...Q,volume:g,isMuted:e.muted||g===0}));},f=()=>{l(g=>({...g,playbackRate:e.playbackRate}));},M=()=>{let g=e.error;if(!g)return;let le={code:{1:"MEDIA_ERR_ABORTED",2:"MEDIA_ERR_NETWORK",3:"MEDIA_ERR_DECODE",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"}[g.code]??"UNKNOWN",message:g.message||"Unknown media error"};l(Le=>({...Le,error:le})),a.current.onError?.(le);},w=()=>{l(g=>({...g,isBuffering:true})),a.current.onBuffering?.(true);},E=()=>{l(g=>({...g,isBuffering:false})),a.current.onBuffering?.(false);},v=()=>l(g=>({...g,isBuffering:false})),N=()=>{let g=!!(document.fullscreenElement||document.webkitFullscreenElement);l(Q=>({...Q,isFullscreen:g}));},V=()=>{l(g=>({...g,isPictureInPicture:document.pictureInPictureElement===e}));};return e.addEventListener("play",t),e.addEventListener("pause",n),e.addEventListener("ended",m),e.addEventListener("timeupdate",y),e.addEventListener("durationchange",k),e.addEventListener("volumechange",c),e.addEventListener("ratechange",f),e.addEventListener("error",M),e.addEventListener("waiting",w),e.addEventListener("canplay",E),e.addEventListener("playing",v),document.addEventListener("fullscreenchange",N),document.addEventListener("webkitfullscreenchange",N),e.addEventListener("enterpictureinpicture",V),e.addEventListener("leavepictureinpicture",V),()=>{e.removeEventListener("play",t),e.removeEventListener("pause",n),e.removeEventListener("ended",m),e.removeEventListener("timeupdate",y),e.removeEventListener("durationchange",k),e.removeEventListener("volumechange",c),e.removeEventListener("ratechange",f),e.removeEventListener("error",M),e.removeEventListener("waiting",w),e.removeEventListener("canplay",E),e.removeEventListener("playing",v),document.removeEventListener("fullscreenchange",N),document.removeEventListener("webkitfullscreenchange",N),e.removeEventListener("enterpictureinpicture",V),e.removeEventListener("leavepictureinpicture",V);}},[i]),ot.useEffect(()=>{let e=a.current.audioRef?.current;if(!e||!a.current.audioSrc)return;let t=()=>{l(E=>({...E,isPlaying:true})),a.current.onPlay?.();},n=()=>{l(E=>({...E,isPlaying:false})),a.current.onPause?.();},m=()=>{l(E=>({...E,isPlaying:false})),a.current.onEnded?.();},y=()=>{l(E=>({...E,isBuffering:true})),a.current.onBuffering?.(true);},k=()=>{l(E=>({...E,isBuffering:false})),a.current.onBuffering?.(false);},c=()=>l(E=>({...E,isBuffering:false})),f=()=>{T.current.isAudioMode&&a.current.onTimeUpdate?.(e.currentTime);},M=()=>{let E=e.duration;isFinite(E)&&(l(v=>({...v,duration:E})),a.current.onDurationChange?.(E));},w=()=>{let E={code:"MEDIA_ERR_NETWORK",message:"Audio source failed to load."};l(v=>({...v,error:E})),a.current.onError?.(E);};return e.addEventListener("play",t),e.addEventListener("pause",n),e.addEventListener("ended",m),e.addEventListener("waiting",y),e.addEventListener("canplay",k),e.addEventListener("playing",c),e.addEventListener("timeupdate",f),e.addEventListener("durationchange",M),e.addEventListener("error",w),()=>{e.removeEventListener("play",t),e.removeEventListener("pause",n),e.removeEventListener("ended",m),e.removeEventListener("waiting",y),e.removeEventListener("canplay",k),e.removeEventListener("playing",c),e.removeEventListener("timeupdate",f),e.removeEventListener("durationchange",M),e.removeEventListener("error",w);}},[r]),ot.useEffect(()=>{let e=a.current,t=i.current,n=e.audioRef?.current;if(!(!t||!n||!e.audioSrc))if(L.isAudioMode){let m=t.currentTime,y=!t.paused;if(t.pause(),u.current?.stopLoad(),n.getAttribute("src")||(n.src=e.audioSrc),n.currentTime=m,n.volume=t.volume,n.muted=t.muted,n.playbackRate=t.playbackRate,y&&n.play().catch(()=>{}),C.current){P.current&&clearTimeout(P.current);let k=e.audioModeRecoveryInterval??3e4;P.current=setTimeout(()=>{!C.current||!T.current.isAudioMode||(A.current=true,u.current?.startLoad());},k);}}else {let m=n.currentTime,y=!n.paused;n.pause(),P.current&&(clearTimeout(P.current),P.current=null),A.current=false,u.current?.startLoad(),t.currentTime=m,t.volume=n.volume,y&&t.play().catch(()=>{});}},[L.isAudioMode,i]);let B=ot.useCallback(async()=>{let e=b();if(e)try{await e.play();}catch(t){t instanceof Error&&t.name!=="AbortError"&&console.error("[player] play() failed:",t);}},[b]),I=ot.useCallback(()=>{b()?.pause();},[b]),D=ot.useCallback(e=>{let t=b();t&&(t.currentTime=Math.max(0,Math.min(e,t.duration||e)));},[b]),te=ot.useCallback(e=>{let t=b();if(!t)return;let n=Math.max(0,Math.min(e,1));n>0&&(h.current=n),t.volume=n,t.muted=n===0;},[b]),J=ot.useCallback(()=>{let e=b();if(e)if(e.muted||e.volume===0){let t=h.current>0?h.current:1;e.volume=t,e.muted=false;}else h.current=e.volume,e.muted=true;},[b]),j=ot.useCallback(e=>{let t=i.current;t&&(t.playbackRate=e);let n=a.current.audioRef?.current;n&&(n.playbackRate=e);},[i]),R=ot.useCallback(e=>{let t=u.current;t&&(t.currentLevel=e,l(n=>({...n,currentQualityLevel:e})));},[]),G=ot.useCallback(()=>{let e=u.current,t=i.current;if(!e||!t)return;let n=e.liveSyncPosition;n!=null&&Number.isFinite(n)&&(t.currentTime=n);},[i]),W=ot.useCallback(async()=>{let e=i.current;if(!e)return;let t=s.current??e.parentElement;if(t)try{!document.fullscreenElement&&!document.webkitFullscreenElement?t.requestFullscreen?await t.requestFullscreen():t.webkitRequestFullscreen?.():document.exitFullscreen?await document.exitFullscreen():document.webkitExitFullscreen?.();}catch(n){console.error("[player] fullscreen toggle failed:",n);}},[i]),Z=ot.useCallback(async()=>{let e=i.current;if(e)try{document.pictureInPictureElement?await document.exitPictureInPicture():await e.requestPictureInPicture();}catch(t){console.error("[player] PiP toggle failed:",t);}},[i]),ne=ot.useCallback(()=>{let e=!T.current.isTheaterMode;l(t=>({...t,isTheaterMode:e})),a.current.onTheaterModeChange?.(e);},[]),re=ot.useCallback(()=>{x.current&&clearTimeout(x.current),C.current=false,p.current=true,x.current=setTimeout(()=>{p.current=false,S.current=[];},6e4);let e=!T.current.isAudioMode;l(t=>({...t,isAudioMode:e})),a.current.onAudioModeChange?.(e);},[]),oe=ot.useCallback(()=>{let e=b(),t=e?.currentTime??0,n=[];if(e)for(let m=0;m<e.buffered.length;m++)n.push({start:e.buffered.start(m),end:e.buffered.end(m)});return {...T.current,currentTime:t,bufferedRanges:n}},[b]),ie=ot.useCallback(()=>i.current??null,[i]),ue=ot.useMemo(()=>({play:B,pause:I,seek:D,setVolume:te,toggleMute:J,setPlaybackRate:j,setQualityLevel:R,seekToLive:G,toggleFullscreen:W,togglePictureInPicture:Z,toggleTheaterMode:ne,toggleAudioMode:re,getState:oe,getVideoElement:ie}),[B,I,D,te,J,j,R,G,W,Z,ne,re,oe,ie]);return {state:L,ref:ue,hlsRef:u,fullscreenContainerRef:s}}var Ze={};ct(Ze,{ControlElements:()=>q,FullscreenButton:()=>be,PauseButton:()=>ge,PiPButton:()=>ye,PlayButton:()=>he,ProgressBar:()=>xe,SettingsMenu:()=>we,TheaterButton:()=>Ee,TimeDisplay:()=>Be,VolumeControl:()=>ke});var he=ot.memo(({onClick:i})=>jsxRuntime.jsx("button",{onClick:i,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"})})}));he.displayName="PlayButton";var ge=ot.memo(({onClick:i})=>jsxRuntime.jsx("button",{onClick:i,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"})})}));ge.displayName="PauseButton";var be=ot.memo(({onClick:i,isFullscreen:r=false})=>jsxRuntime.jsx("button",{onClick:i,className:"controlButton","aria-label":r?"Exit Fullscreen":"Fullscreen",title:r?"Exit Fullscreen (F)":"Fullscreen (F)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:r?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"})})}));be.displayName="FullscreenButton";var ye=ot.memo(({onClick:i,isPiP:r=false})=>jsxRuntime.jsx("button",{onClick:i,className:"controlButton","aria-label":r?"Exit Picture-in-Picture":"Picture-in-Picture",title:r?"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"})})}));ye.displayName="PiPButton";var Ee=ot.memo(({onClick:i,isTheater:r=false})=>jsxRuntime.jsx("button",{onClick:i,className:"controlButton","aria-label":r?"Exit Theater Mode":"Theater Mode",title:r?"Exit Theater Mode (T)":"Theater Mode (T)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:r?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"})})}));Ee.displayName="TheaterButton";var Ke=ot.memo(({volume:i,isMuted:r,onVolumeChange:o,onToggleMute:u})=>{let[s,h]=ot.useState(false),d=r?0:i,a=d*100,L=ot.useMemo(()=>`linear-gradient(to right, #60a5fa 0%, #60a5fa ${a}%, rgba(255,255,255,0.3) ${a}%, rgba(255,255,255,0.3) 100%)`,[a]);return jsxRuntime.jsxs("div",{className:"volumeContainer",onMouseEnter:()=>h(true),onMouseLeave:()=>h(false),children:[jsxRuntime.jsx("button",{onClick:u,className:"controlButton","aria-label":r?"Unmute":"Mute",title:r?"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"})})}),s&&jsxRuntime.jsx("input",{type:"range",min:"0",max:"100",value:a,onChange:l=>o(Number(l.target.value)/100),className:"volumeSlider",style:{background:L},"aria-label":"Volume","aria-valuenow":Math.round(a)})]})});Ke.displayName="VolumeControl";var ke=Ke;function Qe(i){let r=i.trim().split(":");return r.length===3?+r[0]*3600+ +r[1]*60+parseFloat(r[2]):+r[0]*60+parseFloat(r[1])}function yt(i,r){if(/^https?:\/\//i.test(r))return r;try{return new URL(r,i).href}catch{return r}}function Ne(i,r=""){let o=[],u=i.replace(/\r\n/g,`
2
2
  `).split(`
3
- `),a=0;for(;a<s.length;){let p=s[a].trim();if(p.includes("-->")){let u=p.indexOf("-->"),l=$e(p.slice(0,u)),L=$e(p.slice(u+3));for(a++;a<s.length&&!s[a].trim();)a++;if(a<s.length){let c=s[a].trim(),C=c.lastIndexOf("#xywh="),k=c,R=0,T=0,m=160,B=90;if(C!==-1){k=c.slice(0,C);let I=c.slice(C+6).split(",").map(Number);R=I[0]??0,T=I[1]??0,m=I[2]??160,B=I[3]??90;}r.push({start:l,end:L,url:pt(t,k),x:R,y:T,w:m,h:B});}}a++;}return r}function Se(n,t){if(!n.length)return null;let r=0,s=n.length-1;for(;r<=s;){let a=r+s>>1;if(n[a].end<=t)r=a+1;else if(n[a].start>t)s=a-1;else return n[a]}return null}var Ue=Dt.memo(({videoRef:n,playerRef:t,enablePreview:r=true,thumbnailVtt:s})=>{let a=Dt.useRef(null),p=Dt.useRef(null),u=Dt.useRef(null),l=Dt.useRef(null),L=Dt.useRef(null),c=Dt.useRef(null),C=Dt.useRef(null),[k,R]=Dt.useState([]),T=Dt.useRef(false),m=Dt.useRef(0),B=Dt.useRef(0),I=Dt.useRef(null),_=Dt.useRef([]),P=Dt.useRef(null);Dt.useEffect(()=>{let o=()=>{P.current=null;};return window.addEventListener("resize",o,{passive:true}),()=>window.removeEventListener("resize",o)},[]);let x=Dt.useCallback(()=>(!P.current&&a.current&&(P.current=a.current.getBoundingClientRect()),P.current),[]);Dt.useEffect(()=>{if(!s){_.current=[];return}let o=false;return fetch(s).then(i=>i.text()).then(i=>{o||(_.current=Re(i,s));}).catch(()=>{o||(_.current=[]);}),()=>{o=true;}},[s]),Dt.useEffect(()=>{let o=n.current;if(!o)return;let i=()=>{let f=isFinite(o.duration)?o.duration:0,y=o.currentTime,S=f>0?y/f*100:0;p.current&&(p.current.style.width=`${S}%`),u.current&&(u.current.style.left=`${S}%`),a.current&&(a.current.setAttribute("aria-valuenow",String(Math.round(y))),a.current.setAttribute("aria-valuemax",String(Math.round(f))),a.current.setAttribute("aria-valuetext",se(y)));};return o.addEventListener("timeupdate",i),o.addEventListener("durationchange",i),o.addEventListener("seeked",i),i(),()=>{o.removeEventListener("timeupdate",i),o.removeEventListener("durationchange",i),o.removeEventListener("seeked",i);}},[n]),Dt.useEffect(()=>{let o=n.current;if(!o)return;let i=()=>{let f=[];for(let y=0;y<o.buffered.length;y++)f.push({start:o.buffered.start(y),end:o.buffered.end(y)});R(f);};return o.addEventListener("progress",i),()=>o.removeEventListener("progress",i)},[n]);let D=Dt.useCallback(()=>{T.current=true,u.current?.classList.add("dragging");},[]),N=Dt.useCallback(()=>{T.current=false,u.current?.classList.remove("dragging");},[]),ne=Dt.useCallback(()=>{r&&(P.current=null,l.current&&(l.current.style.display="block"),c.current&&(c.current.style.display="block"));},[r]),Z=Dt.useCallback(()=>{l.current&&(l.current.style.display="none"),c.current&&(c.current.style.display="none");},[]),X=Dt.useCallback(o=>{if(!C.current||!_.current.length)return;let i=Se(_.current,o);if(I.current=i,!i)return;let f=C.current;f.style.backgroundImage=`url(${i.url})`,f.style.backgroundPosition=`-${i.x}px -${i.y}px`,f.style.width=`${i.w}px`,f.style.height=`${i.h}px`;},[]),M=Dt.useCallback(o=>{let i=x(),f=n.current?.duration;return !i||i.width===0||!f||!isFinite(f)?0:Math.max(0,Math.min(o-i.left,i.width))/i.width*f},[x,n]),G=Dt.useCallback(o=>{let i=x();return i?Math.max(0,Math.min(o-i.left,i.width)):0},[x]),U=Dt.useCallback(o=>{let i=n.current;if(!i)return;let f=i.currentTime,y=isFinite(i.duration)?i.duration:0;switch(o.key){case "ArrowLeft":case "ArrowRight":{o.preventDefault(),o.nativeEvent.stopImmediatePropagation();let S=o.shiftKey?10:5;t.seek(o.key==="ArrowLeft"?Math.max(0,f-S):Math.min(y,f+S));break}case "Home":o.preventDefault(),o.nativeEvent.stopImmediatePropagation(),t.seek(0);break;case "End":y>0&&(o.preventDefault(),o.nativeEvent.stopImmediatePropagation(),t.seek(y));break}},[n,t]),ee=Dt.useCallback(o=>{let i=M(o.clientX),f=G(o.clientX);if(m.current=f,B.current=i,c.current&&(c.current.style.left=`${f}px`),L.current&&(L.current.textContent=se(i)),X(i),l.current){let y=l.current.offsetWidth,S=x()?.width??0,h=y/2,E=Math.max(h,Math.min(f,S-h));l.current.style.left=`${E}px`;}T.current&&t.seek(i);},[t,X,M,G,x]),ie=Dt.useCallback(()=>{Z(),N();},[Z,N]),e=Dt.useCallback(o=>{o.preventDefault(),D(),t.seek(M(o.clientX));},[D,M,t]),d=Dt.useCallback(o=>{T.current||t.seek(M(o.clientX));},[M,t]);Dt.useEffect(()=>{let o=a.current;if(!o)return;let i=f=>{T.current&&f.preventDefault();};return o.addEventListener("touchmove",i,{passive:false}),()=>o.removeEventListener("touchmove",i)},[]);let v=Dt.useCallback(o=>{P.current=null,D(),t.seek(M(o.touches[0].clientX));},[D,M,t]),V=Dt.useCallback(o=>{T.current&&t.seek(M(o.touches[0].clientX));},[M,t]);Dt.useEffect(()=>{let o=()=>N();return window.addEventListener("mouseup",o),()=>window.removeEventListener("mouseup",o)},[N]);let O=Dt.useMemo(()=>{let o=n.current,i=o&&isFinite(o.duration)?o.duration:0;return i<=0||!k.length?null:k.map((f,y)=>{let S=f.start/i*100,h=(f.end-f.start)/i*100;return jsxRuntime.jsx("div",{className:"bufferedSegment",style:{left:`${S}%`,width:`${h}%`}},y)})},[k,n]);return jsxRuntime.jsxs("div",{ref:a,className:"progressContainer",onMouseMove:ee,onMouseEnter:ne,onMouseLeave:ie,onMouseDown:e,onMouseUp:N,onClick:d,onTouchStart:v,onTouchMove:V,onTouchEnd:N,onKeyDown:U,role:"slider","aria-label":"Video progress","aria-valuemin":0,"aria-valuemax":0,"aria-valuenow":0,"aria-valuetext":"0:00",tabIndex:0,children:[r&&jsxRuntime.jsxs("div",{ref:l,className:"previewTooltip",style:{left:0,display:"none"},"aria-hidden":"true",children:[s&&jsxRuntime.jsx("div",{ref:C,className:"previewThumbnail"}),jsxRuntime.jsx("div",{ref:L,className:"previewTime"})]}),jsxRuntime.jsxs("div",{className:"progressBackground",children:[O,jsxRuntime.jsx("div",{ref:p,className:"progressFilled",style:{width:"0%"}}),r&&jsxRuntime.jsx("div",{ref:c,className:"hoverIndicator",style:{left:0,display:"none"},"aria-hidden":"true"})]}),jsxRuntime.jsx("div",{ref:u,className:"scrubHandle",style:{left:"0%"},"aria-hidden":"true"})]})});Ue.displayName="ProgressBar";var Pe=Ue;var Qe=Dt.memo(({currentRate:n,playbackRates:t,onRateChange:r,qualityLevels:s=[],currentQualityLevel:a=-1,onQualityChange:p})=>{let[u,l]=Dt.useState(false),[L,c]=Dt.useState("speed"),C=Dt.useRef(null),k=s.length>0&&!!p;Dt.useEffect(()=>{let m=B=>{C.current&&!C.current.contains(B.target)&&l(false);};return u&&document.addEventListener("mousedown",m),()=>document.removeEventListener("mousedown",m)},[u]);let R=Dt.useMemo(()=>[...s].sort((m,B)=>B.bitrate-m.bitrate),[s]),T=Dt.useMemo(()=>a===-1?"Auto":s.find(m=>m.id===a)?.name??"Auto",[s,a]);return jsxRuntime.jsxs("div",{ref:C,className:"settingsContainer",children:[jsxRuntime.jsx("button",{onClick:()=>l(m=>!m),className:"controlButton","aria-label":"Settings",title:"Settings","aria-expanded":u,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"})})}),u&&jsxRuntime.jsxs("div",{className:"settingsDropdown",role:"menu",children:[k&&jsxRuntime.jsxs("div",{className:"settingsTabs",children:[jsxRuntime.jsx("button",{className:`settingsTab${L==="speed"?" active":""}`,onClick:()=>c("speed"),children:"Speed"}),jsxRuntime.jsx("button",{className:`settingsTab${L==="quality"?" active":""}`,onClick:()=>c("quality"),children:"Quality"})]}),(!k||L==="speed")&&jsxRuntime.jsxs("div",{children:[!k&&jsxRuntime.jsx("div",{className:"settingsPanelLabel",children:"Playback Speed"}),t.map(m=>jsxRuntime.jsx("button",{onClick:()=>{r(m),l(false);},className:`settingsOption${n===m?" active":""}`,role:"menuitemradio","aria-checked":n===m,children:m===1?"Normal":`${m}\xD7`},m))]}),k&&L==="quality"&&jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{p(-1),l(false);},className:`settingsOption${a===-1?" active":""}`,role:"menuitemradio","aria-checked":a===-1,children:["Auto ",a===-1&&T!=="Auto"?`(${T})`:""]}),R.map(m=>jsxRuntime.jsxs("button",{onClick:()=>{p(m.id),l(false);},className:`settingsOption${a===m.id?" active":""}`,role:"menuitemradio","aria-checked":a===m.id,children:[m.name,m.bitrate>0&&jsxRuntime.jsxs("span",{className:"settingsOptionBadge",children:[Math.round(m.bitrate/1e3)," kbps"]})]},m.id))]})]})]})});Qe.displayName="SettingsMenu";var Te=Qe;var Xe=Dt.memo(({videoRef:n,isLive:t=false})=>{let r=Dt.useRef(null),s=Dt.useRef(null);return Dt.useEffect(()=>{let a=n.current;if(!a)return;let p=()=>{r.current&&(r.current.textContent=se(a.currentTime));},u=()=>{if(s.current){let l=isFinite(a.duration)?a.duration:0;s.current.textContent=` / ${se(l)}`;}};return a.addEventListener("timeupdate",p),a.addEventListener("durationchange",u),a.addEventListener("seeked",p),p(),u(),()=>{a.removeEventListener("timeupdate",p),a.removeEventListener("durationchange",u),a.removeEventListener("seeked",p);}},[n,t]),t?jsxRuntime.jsx("span",{className:"timeDisplay",style:{opacity:.7},children:jsxRuntime.jsx("span",{ref:r,children:"0:00"})}):jsxRuntime.jsxs("span",{className:"timeDisplay",children:[jsxRuntime.jsx("span",{ref:r,children:"0:00"}),jsxRuntime.jsx("span",{ref:s,style:{opacity:.6},children:" / 0:00"})]})});Xe.displayName="TimeDisplay";var ke=Xe;var Q={PlayButton:fe,PauseButton:pe,FullscreenButton:ve,PiPButton:he,TheaterButton:ge,VolumeControl:Le,ProgressBar:Pe,SettingsMenu:Te,TimeDisplay:ke};var xe=Dt.memo(function({videoRef:t,playerRef:r,playerContainerRef:s,playbackRates:a,enablePreview:p,thumbnailVtt:u,isPlaying:l,volume:L,isMuted:c,playbackRate:C,isFullscreen:k,isPictureInPicture:R,isTheaterMode:T,isAudioMode:m,showAudioButton:B,audioModeIcon:I,videoModeIcon:_,audioModeLabel:P,videoModeLabel:x,isLive:D,qualityLevels:N,currentQualityLevel:ne,controlBarItems:Z,autoHideControls:X}){let M=Dt.useRef(null),[G,U]=Dt.useState(true),ee=Dt.useRef({isPlaying:l,volume:L,isMuted:c,isLive:D});ee.current={isPlaying:l,volume:L,isMuted:c,isLive:D},Dt.useEffect(()=>{if(m||!X){U(true),M.current&&clearTimeout(M.current);return}if(!l){U(true),M.current&&clearTimeout(M.current);return}let h=s.current;if(!h)return;let E=()=>{U(true),M.current&&clearTimeout(M.current),M.current=setTimeout(()=>U(false),3e3);},g=()=>{M.current&&clearTimeout(M.current),U(false);};return h.addEventListener("mousemove",E),h.addEventListener("mouseenter",E),h.addEventListener("mouseleave",g),h.addEventListener("touchstart",E,{passive:true}),U(false),()=>{h.removeEventListener("mousemove",E),h.removeEventListener("mouseenter",E),h.removeEventListener("mouseleave",g),h.removeEventListener("touchstart",E),M.current&&clearTimeout(M.current);}},[l,m,X,s]),Dt.useEffect(()=>{let h=E=>{if(!s.current?.contains(document.activeElement))return;let g=E.target;if(g.tagName==="INPUT"||g.tagName==="TEXTAREA"||g.isContentEditable)return;let{isPlaying:A,volume:b,isLive:z}=ee.current,j=t.current?.currentTime??0,ae=t.current?.duration??0;switch(E.code){case "Space":case "KeyK":E.preventDefault(),A?r.pause():r.play();break;case "ArrowLeft":E.preventDefault(),r.seek(Math.max(0,j-5));break;case "ArrowRight":E.preventDefault(),r.seek(Math.min(ae||1/0,j+5));break;case "ArrowUp":E.preventDefault(),r.setVolume(Math.min(1,b+.1));break;case "ArrowDown":E.preventDefault(),r.setVolume(Math.max(0,b-.1));break;case "KeyM":E.preventDefault(),r.toggleMute();break;case "KeyF":E.preventDefault(),r.toggleFullscreen();break;case "KeyP":E.preventDefault(),r.togglePictureInPicture();break;case "KeyT":E.preventDefault(),r.toggleTheaterMode();break;case "KeyL":E.preventDefault(),z&&r.seekToLive();break;case "Digit0":case "Digit1":case "Digit2":case "Digit3":case "Digit4":case "Digit5":case "Digit6":case "Digit7":case "Digit8":case "Digit9":{E.preventDefault();let we=Number(E.code.replace("Digit",""))*10;r.seek(ae/100*we);break}}};return window.addEventListener("keydown",h),()=>window.removeEventListener("keydown",h)},[r,s,t]);let ie=Dt.useCallback(()=>r.play(),[r]),e=Dt.useCallback(()=>r.pause(),[r]),d=Dt.useCallback(h=>r.setVolume(h),[r]),v=Dt.useCallback(()=>r.toggleMute(),[r]),V=Dt.useCallback(h=>r.setPlaybackRate(h),[r]),O=Dt.useCallback(h=>r.setQualityLevel(h),[r]),o=Dt.useCallback(()=>r.togglePictureInPicture(),[r]),i=Dt.useCallback(()=>r.toggleTheaterMode(),[r]),f=Dt.useCallback(()=>r.toggleAudioMode(),[r]),y=Dt.useCallback(()=>r.toggleFullscreen(),[r]),S=Dt.useCallback(()=>r.seekToLive(),[r]);return jsxRuntime.jsx("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",justifyContent:"flex-end",opacity:G?1:0,transition:"opacity 0.3s",pointerEvents:"none",zIndex:2},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:G?"auto":"none"},role:"region","aria-label":"Video player controls",children:[jsxRuntime.jsx(Q.ProgressBar,{videoRef:t,playerRef:r,enablePreview:p,thumbnailVtt:u}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,marginTop:4},children:[l?jsxRuntime.jsx(Q.PauseButton,{onClick:e}):jsxRuntime.jsx(Q.PlayButton,{onClick:ie}),jsxRuntime.jsx(Q.VolumeControl,{volume:L,isMuted:c,onVolumeChange:d,onToggleMute:v}),jsxRuntime.jsx(Q.TimeDisplay,{videoRef:t,isLive:D}),jsxRuntime.jsx("div",{style:{flex:1}}),D&&jsxRuntime.jsx(Ze,{onClick:S}),B&&jsxRuntime.jsx(Je,{onClick:f,isAudioMode:m,audioModeIcon:I,videoModeIcon:_,audioModeLabel:P,videoModeLabel:x}),jsxRuntime.jsx(Q.SettingsMenu,{currentRate:C,playbackRates:a,onRateChange:V,qualityLevels:N,currentQualityLevel:ne,onQualityChange:O}),Z?.map(h=>jsxRuntime.jsx("button",{className:"controlButton","aria-label":h.label,title:h.title??h.label,onClick:h.onClick,children:h.icon},h.key)),jsxRuntime.jsx(Q.PiPButton,{onClick:o,isPiP:R}),jsxRuntime.jsx(Q.TheaterButton,{onClick:i,isTheater:T}),jsxRuntime.jsx(Q.FullscreenButton,{onClick:y,isFullscreen:k})]})]})})});xe.displayName="Controls";var Je=Dt.memo(({onClick:n,isAudioMode:t,audioModeIcon:r,videoModeIcon:s,audioModeLabel:a,videoModeLabel:p})=>{let u=t?p??"Video":a??"Audio";return jsxRuntime.jsxs("button",{onClick:n,className:"rvp-audio-toggle-btn","aria-label":u,title:u,"aria-pressed":t,children:[t?s??jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z"})}):r??jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M12 3a9 9 0 0 0-9 9v7c0 1.1.9 2 2 2h1a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1H4v-1a8 8 0 0 1 16 0v1h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h1a3 3 0 0 0 3-3v-4c0-4.97-4.03-9-9-9z"})}),u]})});Je.displayName="AudioModeButton";var Ze=Dt.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"}));Ze.displayName="GoLiveButton";var Ve=Dt.memo(({x:n,y:t,isPlaying:r,src:s,videoRef:a,playerRef:p,onClose:u,contextMenuItems:l})=>{let L=Dt.useRef(null),[c,C]=Dt.useState(()=>a.current?.loop??false),k=Math.min(n,window.innerWidth-220),R=Math.min(t,window.innerHeight-290);Dt.useEffect(()=>{let P=N=>{L.current&&!L.current.contains(N.target)&&u();},x=N=>{N.key==="Escape"&&u();},D=()=>u();return document.addEventListener("mousedown",P),document.addEventListener("keydown",x),window.addEventListener("scroll",D,true),()=>{document.removeEventListener("mousedown",P),document.removeEventListener("keydown",x),window.removeEventListener("scroll",D,true);}},[u]);let T=Dt.useCallback(()=>{r?p.pause():p.play(),u();},[r,p,u]),m=Dt.useCallback(()=>{let P=a.current;if(!P)return;let x=!c;P.loop=x,C(x);},[a,c]),B=Dt.useCallback(async()=>{try{await navigator.clipboard.writeText(s);}catch{}u();},[s,u]),I=Dt.useCallback(async()=>{let P=Math.floor(a.current?.currentTime??0);try{await navigator.clipboard.writeText(`${s}?t=${P}`);}catch{}u();},[s,a,u]),_=Dt.useCallback(()=>{p.togglePictureInPicture(),u();},[p,u]);return jsxRuntime.jsxs("div",{ref:L,className:"contextMenu",style:{left:k,top:R},children:[jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:T,children:r?"Pause":"Play"}),jsxRuntime.jsxs("button",{className:"contextMenuItem",onClick:m,children:[jsxRuntime.jsx("span",{children:"Loop"}),c&&jsxRuntime.jsx("span",{className:"contextMenuCheck",children:"\u2713"})]}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:B,children:"Copy video URL"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:I,children:"Copy video URL at current time"}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:_,children:"Picture-in-Picture"}),l&&l.length>0&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{className:"contextMenuDivider"}),l.map((P,x)=>jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:()=>{P.onClick(),u();},children:P.label},x))]})]})});Ve.displayName="ContextMenu";var Ae=Dt.memo(function({poster:t,logo:r,audioModeFallback:s,isBuffering:a=false,onOverlayClick:p}){return jsxRuntime.jsxs("div",{className:"rvp-audio-overlay",onClick:p,"data-test":"audio-mode-overlay",children:[t?jsxRuntime.jsx("div",{className:"rvp-audio-artwork-container",children:jsxRuntime.jsx("img",{src:t,alt:"Artwork",className:"rvp-audio-artwork",draggable:false})}):s?jsxRuntime.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center"},children:s}):r?typeof r=="string"?jsxRuntime.jsx("img",{src:r,alt:"Logo",className:"rvp-audio-logo",draggable:false}):jsxRuntime.jsx("div",{className:"rvp-audio-logo-node",children:r}):null,jsxRuntime.jsx("span",{className:"rvp-audio-label",children:"Audio Mode"}),a?jsxRuntime.jsx("div",{className:"rvp-audio-buffering-overlay","aria-label":"Buffering",children:jsxRuntime.jsx("div",{className:"rvp-audio-spinner"})}):null]})});Ae.displayName="AudioModeOverlay";var nt=Dt.forwardRef((n,t)=>{let{src:r,poster:s,className:a,controls:p=true,options:u={}}=n,{autoplay:l=false,muted:L=false,loop:c=false,preload:C="metadata",playbackRates:k=[.25,.5,.75,1,1.25,1.5,1.75,2],enableHLS:R=true,enablePreview:T=true,thumbnailVtt:m,hlsConfig:B,autoHideControls:I=true,subtitles:_,crossOrigin:P,logo:x,audioModeFallback:D,audioSrc:N,showAudioButton:ne,audioModeIcon:Z,videoModeIcon:X,audioModeLabel:M,videoModeLabel:G,defaultAudioMode:U,audioBandwidthThreshold:ee,onPlay:ie,onPause:e,onEnded:d,onError:v,onTimeUpdate:V,onDurationChange:O,onBuffering:o,onTheaterModeChange:i,onAudioModeChange:f,contextMenuItems:y,controlBarItems:S}=u,h=Dt.useRef(null),E=Dt.useRef(null),{state:g,ref:A,fullscreenContainerRef:b}=_e(h,r,{autoplay:l,muted:L,loop:c,playbackRates:k,enableHLS:R,hlsConfig:B,defaultAudioMode:U,audioBandwidthThreshold:ee,onPlay:ie,onPause:e,onEnded:d,onError:v,onTimeUpdate:V,onDurationChange:O,onBuffering:o,onTheaterModeChange:i,onAudioModeChange:f}),[z,j]=Dt.useState(null);Dt.useEffect(()=>{b.current=E.current;},[b]),Dt__default.default.useImperativeHandle(t,()=>A,[A]);let ae=Dt.useCallback(()=>{E.current?.focus(),g.isPlaying?A.pause():A.play();},[g.isPlaying,A]),we=Dt.useCallback(()=>{A.toggleFullscreen();},[A]),rt=Dt.useCallback(te=>{te.preventDefault(),j({x:te.clientX,y:te.clientY});},[]);return jsxRuntime.jsxs("div",{ref:E,tabIndex:0,style:{position:"relative",width:"100%",backgroundColor:"#000",aspectRatio:"16 / 9",userSelect:"none",outline:"none"},className:a,"data-test":"video-player-container","data-theater":g.isTheaterMode?"true":void 0,onContextMenu:rt,children:[jsxRuntime.jsx("video",{ref:h,poster:s,preload:C,crossOrigin:P,onClick:ae,onDoubleClick:we,playsInline:true,style:{width:"100%",height:"100%",display:"block",cursor:"pointer",visibility:g.isAudioMode?"hidden":"visible"},"data-test":"video-element",children:_?.map(te=>jsxRuntime.jsx("track",{kind:"subtitles",src:te.src,label:te.label,srcLang:te.srclang,default:te.default},te.id))}),g.isAudioMode&&jsxRuntime.jsx(Ae,{poster:s,logo:x,audioModeFallback:D,isBuffering:g.isBuffering,onOverlayClick:ae}),p&&jsxRuntime.jsx(xe,{videoRef:h,playerRef:A,playerContainerRef:E,playbackRates:k,enablePreview:T,thumbnailVtt:g.isAudioMode?void 0:m,isPlaying:g.isPlaying,volume:g.volume,isMuted:g.isMuted,playbackRate:g.playbackRate,isFullscreen:g.isFullscreen,isPictureInPicture:g.isPictureInPicture,isTheaterMode:g.isTheaterMode,isAudioMode:g.isAudioMode,showAudioButton:ne??!!N,audioModeIcon:Z,videoModeIcon:X,audioModeLabel:M,videoModeLabel:G,isLive:g.isLive,qualityLevels:g.qualityLevels,currentQualityLevel:g.currentQualityLevel,controlBarItems:S,autoHideControls:I}),z&&jsxRuntime.jsx(Ve,{x:z.x,y:z.y,isPlaying:g.isPlaying,src:r,videoRef:h,playerRef:A,onClose:()=>j(null),contextMenuItems:y}),g.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"}),g.isBuffering&&!g.error&&jsxRuntime.jsx("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"}})}),g.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:g.error.code==="MEDIA_ERR_SRC_NOT_SUPPORTED"?"Unsupported Format":g.error.code.startsWith("HLS")?"Stream Error":"Playback Error"}),jsxRuntime.jsx("p",{style:{margin:0,fontSize:13,opacity:.75},children:g.error.message})]})})]})});nt.displayName="VideoPlayer";var At=nt;var It={EXTREME:100,POOR:300,FAIR:700,GOOD:1500};exports.AUDIO_BANDWIDTH_THRESHOLDS=It;exports.ControlElements=Ge;exports.Controls=xe;exports.VideoPlayer=At;exports.findThumbnailCue=Se;exports.formatTime=se;exports.getMimeType=at;exports.isHLSUrl=ye;exports.parseThumbnailVtt=Re;//# sourceMappingURL=index.js.map
3
+ `),s=0;for(;s<u.length;){let h=u[s].trim();if(h.includes("-->")){let d=h.indexOf("-->"),a=Qe(h.slice(0,d)),L=Qe(h.slice(d+3));for(s++;s<u.length&&!u[s].trim();)s++;if(s<u.length){let l=u[s].trim(),T=l.lastIndexOf("#xywh="),S=l,F=0,C=0,p=160,x=90;if(T!==-1){S=l.slice(0,T);let P=l.slice(T+6).split(",").map(Number);F=P[0]??0,C=P[1]??0,p=P[2]??160,x=P[3]??90;}o.push({start:a,end:L,url:yt(r,S),x:F,y:C,w:p,h:x});}}s++;}return o}function He(i,r){if(!i.length)return null;let o=0,u=i.length-1;for(;o<=u;){let s=o+u>>1;if(i[s].end<=r)o=s+1;else if(i[s].start>r)u=s-1;else return i[s]}return null}var qe=ot.memo(({videoRef:i,playerRef:r,enablePreview:o=true,thumbnailVtt:u})=>{let s=ot.useRef(null),h=ot.useRef(null),d=ot.useRef(null),a=ot.useRef(null),L=ot.useRef(null),l=ot.useRef(null),T=ot.useRef(null),[S,F]=ot.useState([]),C=ot.useRef(false),p=ot.useRef(0),x=ot.useRef(0),P=ot.useRef(null),A=ot.useRef([]),b=ot.useRef(null);ot.useEffect(()=>{let t=()=>{b.current=null;};return window.addEventListener("resize",t,{passive:true}),()=>window.removeEventListener("resize",t)},[]);let B=ot.useCallback(()=>(!b.current&&s.current&&(b.current=s.current.getBoundingClientRect()),b.current),[]);ot.useEffect(()=>{if(!u){A.current=[];return}let t=false;return fetch(u).then(n=>n.text()).then(n=>{t||(A.current=Ne(n,u));}).catch(()=>{t||(A.current=[]);}),()=>{t=true;}},[u]),ot.useEffect(()=>{let t=i.current;if(!t)return;let n=()=>{let m=isFinite(t.duration)?t.duration:0,y=t.currentTime,k=m>0?y/m*100:0;h.current&&(h.current.style.width=`${k}%`),d.current&&(d.current.style.left=`${k}%`),s.current&&(s.current.setAttribute("aria-valuenow",String(Math.round(y))),s.current.setAttribute("aria-valuemax",String(Math.round(m))),s.current.setAttribute("aria-valuetext",ce(y)));};return t.addEventListener("timeupdate",n),t.addEventListener("durationchange",n),t.addEventListener("seeked",n),n(),()=>{t.removeEventListener("timeupdate",n),t.removeEventListener("durationchange",n),t.removeEventListener("seeked",n);}},[i]),ot.useEffect(()=>{let t=i.current;if(!t)return;let n=()=>{let m=[];for(let y=0;y<t.buffered.length;y++)m.push({start:t.buffered.start(y),end:t.buffered.end(y)});F(m);};return t.addEventListener("progress",n),()=>t.removeEventListener("progress",n)},[i]);let I=ot.useCallback(()=>{C.current=true,d.current?.classList.add("dragging");},[]),D=ot.useCallback(()=>{C.current=false,d.current?.classList.remove("dragging");},[]),te=ot.useCallback(()=>{o&&(b.current=null,a.current&&(a.current.style.display="block"),l.current&&(l.current.style.display="block"));},[o]),J=ot.useCallback(()=>{a.current&&(a.current.style.display="none"),l.current&&(l.current.style.display="none");},[]),j=ot.useCallback(t=>{if(!T.current||!A.current.length)return;let n=He(A.current,t);if(P.current=n,!n)return;let m=T.current;m.style.backgroundImage=`url(${n.url})`,m.style.backgroundPosition=`-${n.x}px -${n.y}px`,m.style.width=`${n.w}px`,m.style.height=`${n.h}px`;},[]),R=ot.useCallback(t=>{let n=B(),m=i.current?.duration;return !n||n.width===0||!m||!isFinite(m)?0:Math.max(0,Math.min(t-n.left,n.width))/n.width*m},[B,i]),G=ot.useCallback(t=>{let n=B();return n?Math.max(0,Math.min(t-n.left,n.width)):0},[B]),W=ot.useCallback(t=>{let n=i.current;if(!n)return;let m=n.currentTime,y=isFinite(n.duration)?n.duration:0;switch(t.key){case "ArrowLeft":case "ArrowRight":{t.preventDefault(),t.nativeEvent.stopImmediatePropagation();let k=t.shiftKey?10:5;r.seek(t.key==="ArrowLeft"?Math.max(0,m-k):Math.min(y,m+k));break}case "Home":t.preventDefault(),t.nativeEvent.stopImmediatePropagation(),r.seek(0);break;case "End":y>0&&(t.preventDefault(),t.nativeEvent.stopImmediatePropagation(),r.seek(y));break}},[i,r]),Z=ot.useCallback(t=>{let n=R(t.clientX),m=G(t.clientX);if(p.current=m,x.current=n,l.current&&(l.current.style.left=`${m}px`),L.current&&(L.current.textContent=ce(n)),j(n),a.current){let y=a.current.offsetWidth,k=B()?.width??0,c=y/2,f=Math.max(c,Math.min(m,k-c));a.current.style.left=`${f}px`;}C.current&&r.seek(n);},[r,j,R,G,B]),ne=ot.useCallback(()=>{J(),D();},[J,D]),re=ot.useCallback(t=>{t.preventDefault(),I(),r.seek(R(t.clientX));},[I,R,r]),oe=ot.useCallback(t=>{C.current||r.seek(R(t.clientX));},[R,r]);ot.useEffect(()=>{let t=s.current;if(!t)return;let n=m=>{C.current&&m.preventDefault();};return t.addEventListener("touchmove",n,{passive:false}),()=>t.removeEventListener("touchmove",n)},[]);let ie=ot.useCallback(t=>{b.current=null,I(),r.seek(R(t.touches[0].clientX));},[I,R,r]),ue=ot.useCallback(t=>{C.current&&r.seek(R(t.touches[0].clientX));},[R,r]);ot.useEffect(()=>{let t=()=>D();return window.addEventListener("mouseup",t),()=>window.removeEventListener("mouseup",t)},[D]);let e=ot.useMemo(()=>{let t=i.current,n=t&&isFinite(t.duration)?t.duration:0;return n<=0||!S.length?null:S.map((m,y)=>{let k=m.start/n*100,c=(m.end-m.start)/n*100;return jsxRuntime.jsx("div",{className:"bufferedSegment",style:{left:`${k}%`,width:`${c}%`}},y)})},[S,i]);return jsxRuntime.jsxs("div",{ref:s,className:"progressContainer",onMouseMove:Z,onMouseEnter:te,onMouseLeave:ne,onMouseDown:re,onMouseUp:D,onClick:oe,onTouchStart:ie,onTouchMove:ue,onTouchEnd:D,onKeyDown:W,role:"slider","aria-label":"Video progress","aria-valuemin":0,"aria-valuemax":0,"aria-valuenow":0,"aria-valuetext":"0:00",tabIndex:0,children:[o&&jsxRuntime.jsxs("div",{ref:a,className:"previewTooltip",style:{left:0,display:"none"},"aria-hidden":"true",children:[u&&jsxRuntime.jsx("div",{ref:T,className:"previewThumbnail"}),jsxRuntime.jsx("div",{ref:L,className:"previewTime"})]}),jsxRuntime.jsxs("div",{className:"progressBackground",children:[e,jsxRuntime.jsx("div",{ref:h,className:"progressFilled",style:{width:"0%"}}),o&&jsxRuntime.jsx("div",{ref:l,className:"hoverIndicator",style:{left:0,display:"none"},"aria-hidden":"true"})]}),jsxRuntime.jsx("div",{ref:d,className:"scrubHandle",style:{left:"0%"},"aria-hidden":"true"})]})});qe.displayName="ProgressBar";var xe=qe;var Ge=ot.memo(({currentRate:i,playbackRates:r,onRateChange:o,qualityLevels:u=[],currentQualityLevel:s=-1,onQualityChange:h})=>{let[d,a]=ot.useState(false),[L,l]=ot.useState("speed"),T=ot.useRef(null),S=u.length>0&&!!h;ot.useEffect(()=>{let p=x=>{T.current&&!T.current.contains(x.target)&&a(false);};return d&&document.addEventListener("mousedown",p),()=>document.removeEventListener("mousedown",p)},[d]);let F=ot.useMemo(()=>[...u].sort((p,x)=>x.bitrate-p.bitrate),[u]),C=ot.useMemo(()=>s===-1?"Auto":u.find(p=>p.id===s)?.name??"Auto",[u,s]);return jsxRuntime.jsxs("div",{ref:T,className:"settingsContainer",children:[jsxRuntime.jsx("button",{onClick:()=>a(p=>!p),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:[S&&jsxRuntime.jsxs("div",{className:"settingsTabs",children:[jsxRuntime.jsx("button",{className:`settingsTab${L==="speed"?" active":""}`,onClick:()=>l("speed"),children:"Speed"}),jsxRuntime.jsx("button",{className:`settingsTab${L==="quality"?" active":""}`,onClick:()=>l("quality"),children:"Quality"})]}),(!S||L==="speed")&&jsxRuntime.jsxs("div",{children:[!S&&jsxRuntime.jsx("div",{className:"settingsPanelLabel",children:"Playback Speed"}),r.map(p=>jsxRuntime.jsx("button",{onClick:()=>{o(p),a(false);},className:`settingsOption${i===p?" active":""}`,role:"menuitemradio","aria-checked":i===p,children:p===1?"Normal":`${p}\xD7`},p))]}),S&&L==="quality"&&jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{h(-1),a(false);},className:`settingsOption${s===-1?" active":""}`,role:"menuitemradio","aria-checked":s===-1,children:["Auto ",s===-1&&C!=="Auto"?`(${C})`:""]}),F.map(p=>jsxRuntime.jsxs("button",{onClick:()=>{h(p.id),a(false);},className:`settingsOption${s===p.id?" active":""}`,role:"menuitemradio","aria-checked":s===p.id,children:[p.name,p.bitrate>0&&jsxRuntime.jsxs("span",{className:"settingsOptionBadge",children:[Math.round(p.bitrate/1e3)," kbps"]})]},p.id))]})]})]})});Ge.displayName="SettingsMenu";var we=Ge;var Je=ot.memo(({videoRef:i,isLive:r=false})=>{let o=ot.useRef(null),u=ot.useRef(null);return ot.useEffect(()=>{let s=i.current;if(!s)return;let h=()=>{o.current&&(o.current.textContent=ce(s.currentTime));},d=()=>{if(u.current){let a=isFinite(s.duration)?s.duration:0;u.current.textContent=` / ${ce(a)}`;}};return s.addEventListener("timeupdate",h),s.addEventListener("durationchange",d),s.addEventListener("seeked",h),h(),d(),()=>{s.removeEventListener("timeupdate",h),s.removeEventListener("durationchange",d),s.removeEventListener("seeked",h);}},[i,r]),r?jsxRuntime.jsx("span",{className:"timeDisplay",style:{opacity:.7},children:jsxRuntime.jsx("span",{ref:o,children:"0:00"})}):jsxRuntime.jsxs("span",{className:"timeDisplay",children:[jsxRuntime.jsx("span",{ref:o,children:"0:00"}),jsxRuntime.jsx("span",{ref:u,style:{opacity:.6},children:" / 0:00"})]})});Je.displayName="TimeDisplay";var Be=Je;var q={PlayButton:he,PauseButton:ge,FullscreenButton:be,PiPButton:ye,TheaterButton:Ee,VolumeControl:ke,ProgressBar:xe,SettingsMenu:we,TimeDisplay:Be};var De=ot.memo(function({videoRef:r,playerRef:o,playerContainerRef:u,playbackRates:s,enablePreview:h,thumbnailVtt:d,isPlaying:a,volume:L,isMuted:l,playbackRate:T,isFullscreen:S,isPictureInPicture:F,isTheaterMode:C,isAudioMode:p,showAudioButton:x,audioModeIcon:P,videoModeIcon:A,audioModeLabel:b,videoModeLabel:B,isLive:I,qualityLevels:D,currentQualityLevel:te,controlBarItems:J,autoHideControls:j}){let R=ot.useRef(null),[G,W]=ot.useState(true),Z=ot.useRef({isPlaying:a,volume:L,isMuted:l,isLive:I});Z.current={isPlaying:a,volume:L,isMuted:l,isLive:I},ot.useEffect(()=>{if(p||!j){W(true),R.current&&clearTimeout(R.current);return}if(!a){W(true),R.current&&clearTimeout(R.current);return}let c=u.current;if(!c)return;let f=()=>{W(true),R.current&&clearTimeout(R.current),R.current=setTimeout(()=>W(false),3e3);},M=()=>{R.current&&clearTimeout(R.current),W(false);};return c.addEventListener("mousemove",f),c.addEventListener("mouseenter",f),c.addEventListener("mouseleave",M),c.addEventListener("touchstart",f,{passive:true}),W(false),()=>{c.removeEventListener("mousemove",f),c.removeEventListener("mouseenter",f),c.removeEventListener("mouseleave",M),c.removeEventListener("touchstart",f),R.current&&clearTimeout(R.current);}},[a,p,j,u]),ot.useEffect(()=>{let c=f=>{if(!u.current?.contains(document.activeElement))return;let M=f.target;if(M.tagName==="INPUT"||M.tagName==="TEXTAREA"||M.isContentEditable)return;let{isPlaying:w,volume:E,isLive:v}=Z.current,N=r.current?.currentTime??0,V=r.current?.duration??0;switch(f.code){case "Space":case "KeyK":f.preventDefault(),w?o.pause():o.play();break;case "ArrowLeft":f.preventDefault(),o.seek(Math.max(0,N-5));break;case "ArrowRight":f.preventDefault(),o.seek(Math.min(V||1/0,N+5));break;case "ArrowUp":f.preventDefault(),o.setVolume(Math.min(1,E+.1));break;case "ArrowDown":f.preventDefault(),o.setVolume(Math.max(0,E-.1));break;case "KeyM":f.preventDefault(),o.toggleMute();break;case "KeyF":f.preventDefault(),o.toggleFullscreen();break;case "KeyP":f.preventDefault(),o.togglePictureInPicture();break;case "KeyT":f.preventDefault(),o.toggleTheaterMode();break;case "KeyL":f.preventDefault(),v&&o.seekToLive();break;case "Digit0":case "Digit1":case "Digit2":case "Digit3":case "Digit4":case "Digit5":case "Digit6":case "Digit7":case "Digit8":case "Digit9":{f.preventDefault();let g=Number(f.code.replace("Digit",""))*10;o.seek(V/100*g);break}}};return window.addEventListener("keydown",c),()=>window.removeEventListener("keydown",c)},[o,u,r]);let ne=ot.useCallback(()=>o.play(),[o]),re=ot.useCallback(()=>o.pause(),[o]),oe=ot.useCallback(c=>o.setVolume(c),[o]),ie=ot.useCallback(()=>o.toggleMute(),[o]),ue=ot.useCallback(c=>o.setPlaybackRate(c),[o]),e=ot.useCallback(c=>o.setQualityLevel(c),[o]),t=ot.useCallback(()=>o.togglePictureInPicture(),[o]),n=ot.useCallback(()=>o.toggleTheaterMode(),[o]),m=ot.useCallback(()=>o.toggleAudioMode(),[o]),y=ot.useCallback(()=>o.toggleFullscreen(),[o]),k=ot.useCallback(()=>o.seekToLive(),[o]);return jsxRuntime.jsx("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",justifyContent:"flex-end",opacity:G?1:0,transition:"opacity 0.3s",pointerEvents:"none",zIndex:2},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:G?"auto":"none"},role:"region","aria-label":"Video player controls",children:[jsxRuntime.jsx(q.ProgressBar,{videoRef:r,playerRef:o,enablePreview:h,thumbnailVtt:d}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,marginTop:4},children:[a?jsxRuntime.jsx(q.PauseButton,{onClick:re}):jsxRuntime.jsx(q.PlayButton,{onClick:ne}),jsxRuntime.jsx(q.VolumeControl,{volume:L,isMuted:l,onVolumeChange:oe,onToggleMute:ie}),jsxRuntime.jsx(q.TimeDisplay,{videoRef:r,isLive:I}),jsxRuntime.jsx("div",{style:{flex:1}}),I&&jsxRuntime.jsx(rt,{onClick:k}),x&&jsxRuntime.jsx(nt,{onClick:m,isAudioMode:p,audioModeIcon:P,videoModeIcon:A,audioModeLabel:b,videoModeLabel:B}),jsxRuntime.jsx(q.SettingsMenu,{currentRate:T,playbackRates:s,onRateChange:ue,qualityLevels:D,currentQualityLevel:te,onQualityChange:e}),J?.map(c=>jsxRuntime.jsx("button",{className:"controlButton","aria-label":c.label,title:c.title??c.label,onClick:c.onClick,children:c.icon},c.key)),jsxRuntime.jsx(q.PiPButton,{onClick:t,isPiP:F}),jsxRuntime.jsx(q.TheaterButton,{onClick:n,isTheater:C}),jsxRuntime.jsx(q.FullscreenButton,{onClick:y,isFullscreen:S})]})]})})});De.displayName="Controls";var nt=ot.memo(({onClick:i,isAudioMode:r,audioModeIcon:o,videoModeIcon:u,audioModeLabel:s,videoModeLabel:h})=>{let d=r?h??"Video":s??"Audio";return jsxRuntime.jsxs("button",{onClick:i,className:"rvp-audio-toggle-btn","aria-label":d,title:d,"aria-pressed":r,children:[r?u??jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z"})}):o??jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M12 3a9 9 0 0 0-9 9v7c0 1.1.9 2 2 2h1a1 1 0 0 0 1-1v-5a1 1 0 0 0-1-1H4v-1a8 8 0 0 1 16 0v1h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h1a3 3 0 0 0 3-3v-4c0-4.97-4.03-9-9-9z"})}),d]})});nt.displayName="AudioModeButton";var rt=ot.memo(({onClick:i})=>jsxRuntime.jsx("button",{onClick:i,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"}));rt.displayName="GoLiveButton";var _e=ot.memo(({x:i,y:r,isPlaying:o,src:u,videoRef:s,playerRef:h,onClose:d,contextMenuItems:a})=>{let L=ot.useRef(null),[l,T]=ot.useState(()=>s.current?.loop??false),S=Math.min(i,window.innerWidth-220),F=Math.min(r,window.innerHeight-290);ot.useEffect(()=>{let b=D=>{L.current&&!L.current.contains(D.target)&&d();},B=D=>{D.key==="Escape"&&d();},I=()=>d();return document.addEventListener("mousedown",b),document.addEventListener("keydown",B),window.addEventListener("scroll",I,true),()=>{document.removeEventListener("mousedown",b),document.removeEventListener("keydown",B),window.removeEventListener("scroll",I,true);}},[d]);let C=ot.useCallback(()=>{o?h.pause():h.play(),d();},[o,h,d]),p=ot.useCallback(()=>{let b=s.current;if(!b)return;let B=!l;b.loop=B,T(B);},[s,l]),x=ot.useCallback(async()=>{try{await navigator.clipboard.writeText(u);}catch{}d();},[u,d]),P=ot.useCallback(async()=>{let b=Math.floor(s.current?.currentTime??0);try{await navigator.clipboard.writeText(`${u}?t=${b}`);}catch{}d();},[u,s,d]),A=ot.useCallback(()=>{h.togglePictureInPicture(),d();},[h,d]);return jsxRuntime.jsxs("div",{ref:L,className:"contextMenu",style:{left:S,top:F},children:[jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:C,children:o?"Pause":"Play"}),jsxRuntime.jsxs("button",{className:"contextMenuItem",onClick:p,children:[jsxRuntime.jsx("span",{children:"Loop"}),l&&jsxRuntime.jsx("span",{className:"contextMenuCheck",children:"\u2713"})]}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:x,children:"Copy video URL"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:P,children:"Copy video URL at current time"}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:A,children:"Picture-in-Picture"}),a&&a.length>0&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{className:"contextMenuDivider"}),a.map((b,B)=>jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:()=>{b.onClick(),d();},children:b.label},B))]})]})});_e.displayName="ContextMenu";var ze=ot.memo(function({poster:r,logo:o,audioModeFallback:u,isBuffering:s=false,onOverlayClick:h}){return jsxRuntime.jsxs("div",{className:"rvp-audio-overlay",onClick:h,"data-test":"audio-mode-overlay",children:[r?jsxRuntime.jsx("div",{className:"rvp-audio-artwork-container",children:jsxRuntime.jsx("img",{src:r,alt:"Artwork",className:"rvp-audio-artwork",draggable:false})}):u?jsxRuntime.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center"},children:u}):o?typeof o=="string"?jsxRuntime.jsx("img",{src:o,alt:"Logo",className:"rvp-audio-logo",draggable:false}):jsxRuntime.jsx("div",{className:"rvp-audio-logo-node",children:o}):null,jsxRuntime.jsx("span",{className:"rvp-audio-label",children:"Audio Mode"}),s?jsxRuntime.jsx("div",{className:"rvp-audio-buffering-overlay","aria-label":"Buffering",children:jsxRuntime.jsx("div",{className:"rvp-audio-spinner"})}):null]})});ze.displayName="AudioModeOverlay";var at=ot.forwardRef((i,r)=>{let{src:o,poster:u,className:s,controls:h=true,options:d={}}=i,{autoplay:a=false,muted:L=false,loop:l=false,preload:T="metadata",playbackRates:S=[.25,.5,.75,1,1.25,1.5,1.75,2],enableHLS:F=true,enablePreview:C=true,thumbnailVtt:p,hlsConfig:x,autoHideControls:P=true,subtitles:A,crossOrigin:b,logo:B,audioModeFallback:I,audioSrc:D,showAudioButton:te,audioModeIcon:J,videoModeIcon:j,audioModeLabel:R,videoModeLabel:G,defaultAudioMode:W,audioBandwidthThreshold:Z,audioModeSwitchLevel:ne,audioModeRecoveryInterval:re,onPlay:oe,onPause:ie,onEnded:ue,onError:e,onTimeUpdate:t,onDurationChange:n,onBuffering:m,onTheaterModeChange:y,onAudioModeChange:k,contextMenuItems:c,controlBarItems:f}=d,M=ot.useRef(null),w=ot.useRef(null),E=ot.useRef(null),{state:v,ref:N,fullscreenContainerRef:V}=$e(M,o,{autoplay:a,muted:L,loop:l,playbackRates:S,enableHLS:F,hlsConfig:x,defaultAudioMode:W,audioBandwidthThreshold:Z,audioModeSwitchLevel:ne,audioModeRecoveryInterval:re,onPlay:oe,onPause:ie,onEnded:ue,onError:e,onTimeUpdate:t,onDurationChange:n,onBuffering:m,onTheaterModeChange:y,onAudioModeChange:k,audioRef:w,audioSrc:D}),g=ot.useRef(null);ot__default.default.useLayoutEffect(()=>{g.current=v.isAudioMode&&D&&w.current?w.current:M.current;},[v.isAudioMode,D]),g.current===null&&(g.current=M.current);let[Q,le]=ot.useState(null);ot.useEffect(()=>{V.current=E.current;},[V]),ot__default.default.useImperativeHandle(r,()=>N,[N]);let Le=ot.useCallback(()=>{E.current?.focus(),v.isPlaying?N.pause():N.play();},[v.isPlaying,N]),st=ot.useCallback(()=>{N.toggleFullscreen();},[N]),ut=ot.useCallback(ee=>{ee.preventDefault(),le({x:ee.clientX,y:ee.clientY});},[]);return jsxRuntime.jsxs("div",{ref:E,tabIndex:0,style:{position:"relative",width:"100%",backgroundColor:"#000",aspectRatio:"16 / 9",userSelect:"none",outline:"none"},className:s,"data-test":"video-player-container","data-theater":v.isTheaterMode?"true":void 0,onContextMenu:ut,children:[jsxRuntime.jsx("video",{ref:M,poster:u,preload:T,crossOrigin:b,onClick:Le,onDoubleClick:st,playsInline:true,style:{width:"100%",height:"100%",display:"block",cursor:"pointer",visibility:v.isAudioMode?"hidden":"visible"},"data-test":"video-element",children:A?.map(ee=>jsxRuntime.jsx("track",{kind:"subtitles",src:ee.src,label:ee.label,srcLang:ee.srclang,default:ee.default},ee.id))}),D&&jsxRuntime.jsx("audio",{ref:w,preload:"none",style:{display:"none"},"aria-hidden":"true"}),v.isAudioMode&&jsxRuntime.jsx(ze,{poster:u,logo:B,audioModeFallback:I,isBuffering:v.isBuffering,onOverlayClick:Le}),h&&jsxRuntime.jsx(De,{videoRef:g,playerRef:N,playerContainerRef:E,playbackRates:S,enablePreview:C,thumbnailVtt:v.isAudioMode?void 0:p,isPlaying:v.isPlaying,volume:v.volume,isMuted:v.isMuted,playbackRate:v.playbackRate,isFullscreen:v.isFullscreen,isPictureInPicture:v.isPictureInPicture,isTheaterMode:v.isTheaterMode,isAudioMode:v.isAudioMode,showAudioButton:te??!!D,audioModeIcon:J,videoModeIcon:j,audioModeLabel:R,videoModeLabel:G,isLive:v.isLive,qualityLevels:v.qualityLevels,currentQualityLevel:v.currentQualityLevel,controlBarItems:f,autoHideControls:P}),Q&&jsxRuntime.jsx(_e,{x:Q.x,y:Q.y,isPlaying:v.isPlaying,src:o,videoRef:M,playerRef:N,onClose:()=>le(null),contextMenuItems:c}),v.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"}),v.isBuffering&&!v.error&&!v.isAudioMode&&jsxRuntime.jsx("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"}})}),v.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:v.error.code==="MEDIA_ERR_SRC_NOT_SUPPORTED"?"Unsupported Format":v.error.code.startsWith("HLS")?"Stream Error":"Playback Error"}),jsxRuntime.jsx("p",{style:{margin:0,fontSize:13,opacity:.75},children:v.error.message})]})})]})});at.displayName="VideoPlayer";var _t=at;var zt={EXTREME:100,POOR:300,FAIR:800,GOOD:1500},Wt={LOWEST:0,SECOND_LOWEST:1,DISABLED:-1};exports.AUDIO_BANDWIDTH_THRESHOLDS=zt;exports.AUDIO_SWITCH_LEVELS=Wt;exports.ControlElements=Ze;exports.Controls=De;exports.VideoPlayer=_t;exports.findThumbnailCue=He;exports.formatTime=ce;exports.getMimeType=dt;exports.isHLSUrl=Pe;exports.parseThumbnailVtt=Ne;//# sourceMappingURL=index.js.map
4
4
  //# sourceMappingURL=index.js.map