react-helios 2.8.0 → 2.9.2
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 +106 -4
- package/dist/index.d.mts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +92 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# react-helios
|
|
2
2
|
|
|
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.
|
|
3
|
+
Production-grade React video player with HLS streaming, zero-cost audio mode, adaptive quality selection, manual quality switching, live stream support, subtitle tracks, VTT sprite sheet thumbnail preview, waveform audio progress bar, Picture-in-Picture, and full keyboard control.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -69,6 +69,7 @@ Audio mode pauses the video element completely (stopping all video decoding), sh
|
|
|
69
69
|
controls
|
|
70
70
|
options={{
|
|
71
71
|
audioSrc: "https://example.com/audio-only.m3u8",
|
|
72
|
+
audioPoster: "https://example.com/audio-artwork.jpg",
|
|
72
73
|
audioModeLabel: "Switch to Audio",
|
|
73
74
|
videoModeLabel: "Switch to Video",
|
|
74
75
|
defaultAudioMode: false,
|
|
@@ -81,6 +82,40 @@ The audio toggle button only appears in the control bar when `audioSrc` is provi
|
|
|
81
82
|
|
|
82
83
|
When switching between modes, position, volume, and playback rate are synced automatically — the listener hears no gap.
|
|
83
84
|
|
|
85
|
+
### Audio mode poster
|
|
86
|
+
|
|
87
|
+
Use `audioPoster` to show a different image in audio mode than the video `poster`. If neither `audioPoster` nor `poster` is provided, the `audioModeFallback` content is shown instead:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<VideoPlayer
|
|
91
|
+
src="https://example.com/stream.m3u8"
|
|
92
|
+
poster="https://example.com/video-thumb.jpg"
|
|
93
|
+
options={{
|
|
94
|
+
audioSrc: "https://example.com/audio-only.m3u8",
|
|
95
|
+
// Show a dedicated artwork image in audio mode
|
|
96
|
+
audioPoster: "https://example.com/audio-artwork.jpg",
|
|
97
|
+
}}
|
|
98
|
+
/>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Priority order: `audioPoster` → `poster` (if `audioModeFallback` is not set) → `audioModeFallback` → `logo`.
|
|
102
|
+
|
|
103
|
+
Use `audioModeFallback` when you want to render arbitrary React content (e.g. an animated logo or custom component) instead of a static image:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
<VideoPlayer
|
|
107
|
+
src="https://example.com/stream.m3u8"
|
|
108
|
+
options={{
|
|
109
|
+
audioSrc: "https://example.com/audio-only.m3u8",
|
|
110
|
+
audioModeFallback: <MyAnimatedArtwork />,
|
|
111
|
+
}}
|
|
112
|
+
/>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Waveform progress bar
|
|
116
|
+
|
|
117
|
+
In audio mode the normal video progress bar is replaced by a **waveform-style bar graph** — 200 pseudo-random bars that reveal left-to-right as the audio plays. Buffered/preloaded content is shown in a lighter shade behind the played bars. No configuration is needed; the waveform appears automatically whenever audio mode is active.
|
|
118
|
+
|
|
84
119
|
### Automatic switching
|
|
85
120
|
|
|
86
121
|
The player uses two independent signals to detect poor conditions and switch to audio mode automatically. Either one firing is enough.
|
|
@@ -153,6 +188,18 @@ Hover over the progress bar to see a time tooltip. For rich sprite-sheet thumbna
|
|
|
153
188
|
/>
|
|
154
189
|
```
|
|
155
190
|
|
|
191
|
+
If the image paths inside the VTT file are relative, supply `thumbnailVttBaseUrl` so the player can resolve them:
|
|
192
|
+
|
|
193
|
+
```tsx
|
|
194
|
+
<VideoPlayer
|
|
195
|
+
src="https://example.com/video.mp4"
|
|
196
|
+
options={{
|
|
197
|
+
thumbnailVtt: "/thumbs/storyboard.vtt",
|
|
198
|
+
thumbnailVttBaseUrl: "https://example.com",
|
|
199
|
+
}}
|
|
200
|
+
/>
|
|
201
|
+
```
|
|
202
|
+
|
|
156
203
|
### VTT format
|
|
157
204
|
|
|
158
205
|
Each cue in the `.vtt` file maps a time range to a rectangular region inside a sprite image using the `#xywh=x,y,w,h` fragment:
|
|
@@ -215,6 +262,7 @@ To disable the preview entirely:
|
|
|
215
262
|
|--------|------|---------|-------------|
|
|
216
263
|
| `enablePreview` | `boolean` | `true` | Show thumbnail / time tooltip on progress bar hover |
|
|
217
264
|
| `thumbnailVtt` | `string` | — | URL to a WebVTT sprite sheet file for rich thumbnail preview |
|
|
265
|
+
| `thumbnailVttBaseUrl` | `string` | — | Base URL prepended to relative image paths inside the VTT file |
|
|
218
266
|
|
|
219
267
|
### `options` — UI
|
|
220
268
|
|
|
@@ -229,12 +277,13 @@ To disable the preview entirely:
|
|
|
229
277
|
| `audioSrc` | `string` | — | Audio-only stream URL; the audio toggle button only shows when this is set |
|
|
230
278
|
| `showAudioButton` | `boolean` | `!!audioSrc` | Force-show or hide the audio toggle button |
|
|
231
279
|
| `defaultAudioMode` | `boolean` | `false` | Start in audio mode |
|
|
280
|
+
| `audioPoster` | `string` | — | Image shown in audio mode (takes priority over `poster`) |
|
|
232
281
|
| `audioModeLabel` | `string` | `"Audio"` | Label on the toggle button when in video mode |
|
|
233
282
|
| `videoModeLabel` | `string` | `"Video"` | Label on the toggle button when in audio mode |
|
|
234
283
|
| `audioModeIcon` | `ReactNode` | built-in headphones icon | Icon shown when in video mode (click → audio) |
|
|
235
284
|
| `videoModeIcon` | `ReactNode` | built-in video icon | Icon shown when in audio mode (click → video) |
|
|
236
|
-
| `audioModeFallback` | `ReactNode` | — | Custom content shown in audio mode when
|
|
237
|
-
| `logo` | `string \| ReactNode` | — | Logo shown in audio mode when no
|
|
285
|
+
| `audioModeFallback` | `ReactNode` | — | Custom React content shown in audio mode when neither `audioPoster` nor `poster` is set |
|
|
286
|
+
| `logo` | `string \| ReactNode` | — | Logo shown in audio mode when no poster or fallback is set |
|
|
238
287
|
| `audioBandwidthThreshold` | `number` | `300` | Kbps — switch when per-fragment bandwidth average drops below this. `0` = disabled (HLS only) |
|
|
239
288
|
| `audioModeSwitchLevel` | `number` | — | HLS quality level index — switch when HLS.js drops to this level or below. `0` = lowest. `-1` = disabled |
|
|
240
289
|
| `audioModeRecoveryInterval` | `number` | `30000` | Ms between recovery probes while in auto-switched audio mode |
|
|
@@ -262,10 +311,12 @@ To disable the preview entirely:
|
|
|
262
311
|
|
|
263
312
|
## Quality Selection
|
|
264
313
|
|
|
314
|
+
### HLS adaptive quality
|
|
315
|
+
|
|
265
316
|
For HLS streams (`.m3u8`) the player automatically parses the available quality levels from the manifest. Once levels are available, the **Settings (⚙)** button in the control bar grows a **Speed / Quality** tab bar:
|
|
266
317
|
|
|
267
318
|
- **Speed tab** — always visible, lets you change playback rate.
|
|
268
|
-
- **Quality tab** — appears
|
|
319
|
+
- **Quality tab** — appears for HLS streams. Lists all levels sorted by bitrate (e.g. 1080p, 720p, 480p) plus an **Auto** option that enables ABR (adaptive bitrate). The current auto-selected level is shown in parentheses next to "Auto".
|
|
269
320
|
|
|
270
321
|
You can also switch quality programmatically via the ref:
|
|
271
322
|
|
|
@@ -274,6 +325,47 @@ playerRef.current?.setQualityLevel(0); // pin to highest level
|
|
|
274
325
|
playerRef.current?.setQualityLevel(-1); // back to ABR auto
|
|
275
326
|
```
|
|
276
327
|
|
|
328
|
+
### Manual quality selection
|
|
329
|
+
|
|
330
|
+
For non-HLS sources (or when you want to control quality URLs yourself), pass a `manualQualityLevels` array. Each item has a human-readable `label` and the `src` URL to load when the user selects it.
|
|
331
|
+
|
|
332
|
+
```tsx
|
|
333
|
+
import { VideoPlayer } from "react-helios";
|
|
334
|
+
import type { ManualQualityLevel } from "react-helios";
|
|
335
|
+
|
|
336
|
+
const qualityLevels: ManualQualityLevel[] = [
|
|
337
|
+
{ label: "1080p", src: "https://example.com/video-1080p.mp4" },
|
|
338
|
+
{ label: "720p", src: "https://example.com/video-720p.mp4" },
|
|
339
|
+
{ label: "480p", src: "https://example.com/video-480p.mp4" },
|
|
340
|
+
{ label: "360p", src: "https://example.com/video-360p.mp4" },
|
|
341
|
+
];
|
|
342
|
+
|
|
343
|
+
<VideoPlayer
|
|
344
|
+
src="https://example.com/video-720p.mp4"
|
|
345
|
+
controls
|
|
346
|
+
options={{
|
|
347
|
+
manualQualityLevels: qualityLevels,
|
|
348
|
+
}}
|
|
349
|
+
/>
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
When `manualQualityLevels` is provided, the **Quality tab** appears automatically in the Settings menu. Selecting an option swaps the player `src` and resumes playback at the same position.
|
|
353
|
+
|
|
354
|
+
Use `showQualityMenu: true` to force the Quality tab open even when no quality levels have been detected yet (useful during the initial HLS manifest load):
|
|
355
|
+
|
|
356
|
+
```tsx
|
|
357
|
+
options={{ showQualityMenu: true }}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Both manual and HLS quality levels can coexist in the same Quality tab — manual levels appear at the top, HLS ABR levels below a divider.
|
|
361
|
+
|
|
362
|
+
### `options` — Quality
|
|
363
|
+
|
|
364
|
+
| Option | Type | Default | Description |
|
|
365
|
+
|--------|------|---------|-------------|
|
|
366
|
+
| `manualQualityLevels` | `ManualQualityLevel[]` | — | Src-based quality options shown in the Settings → Quality tab |
|
|
367
|
+
| `showQualityMenu` | `boolean` | `false` | Force-show the Quality tab in Settings even before HLS levels are detected |
|
|
368
|
+
|
|
277
369
|
## Custom Control Bar Buttons
|
|
278
370
|
|
|
279
371
|
Inject your own icon buttons into the right side of the control bar using `controlBarItems`:
|
|
@@ -437,6 +529,7 @@ import type {
|
|
|
437
529
|
PlayerState,
|
|
438
530
|
PlaybackRate,
|
|
439
531
|
HLSQualityLevel,
|
|
532
|
+
ManualQualityLevel,
|
|
440
533
|
SubtitleTrack,
|
|
441
534
|
BufferedRange,
|
|
442
535
|
VideoError,
|
|
@@ -514,6 +607,15 @@ interface ContextMenuItem {
|
|
|
514
607
|
}
|
|
515
608
|
```
|
|
516
609
|
|
|
610
|
+
### `ManualQualityLevel`
|
|
611
|
+
|
|
612
|
+
```ts
|
|
613
|
+
interface ManualQualityLevel {
|
|
614
|
+
label: string; // Display name shown in the Settings menu (e.g. "1080p", "HD", "Low")
|
|
615
|
+
src: string; // URL to load when this quality level is selected
|
|
616
|
+
}
|
|
617
|
+
```
|
|
618
|
+
|
|
517
619
|
### `ThumbnailCue`
|
|
518
620
|
|
|
519
621
|
```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -117,6 +117,12 @@ interface VideoPlayerRef {
|
|
|
117
117
|
getState: () => PlayerState;
|
|
118
118
|
getVideoElement: () => HTMLVideoElement | null;
|
|
119
119
|
}
|
|
120
|
+
interface ManualQualityLevel {
|
|
121
|
+
/** Display label shown in the Quality menu, e.g. "360p", "720p", "1080p" */
|
|
122
|
+
label: string;
|
|
123
|
+
/** URL to load when this quality is selected (HLS m3u8 or direct MP4) */
|
|
124
|
+
src: string;
|
|
125
|
+
}
|
|
120
126
|
interface ContextMenuItem {
|
|
121
127
|
label: string;
|
|
122
128
|
onClick: () => void;
|
|
@@ -190,6 +196,20 @@ interface VideoPlayerOptions {
|
|
|
190
196
|
onBuffering?: (isBuffering: boolean) => void;
|
|
191
197
|
onTheaterModeChange?: (isTheater: boolean) => void;
|
|
192
198
|
onAudioModeChange?: (isAudio: boolean) => void;
|
|
199
|
+
/** Force-show the Quality tab in the Settings menu (useful with manualQualityLevels). */
|
|
200
|
+
showQualityMenu?: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Manual quality levels for non-adaptive sources.
|
|
203
|
+
* Each entry has a display label and a src URL to load when selected.
|
|
204
|
+
* Works alongside the automatic HLS quality levels — both can be shown at the same time.
|
|
205
|
+
* @example
|
|
206
|
+
* manualQualityLevels={[
|
|
207
|
+
* { label: "1080p", src: "https://cdn.example.com/video_1080.m3u8" },
|
|
208
|
+
* { label: "720p", src: "https://cdn.example.com/video_720.m3u8" },
|
|
209
|
+
* { label: "360p", src: "https://cdn.example.com/video_360.mp4" },
|
|
210
|
+
* ]}
|
|
211
|
+
*/
|
|
212
|
+
manualQualityLevels?: ManualQualityLevel[];
|
|
193
213
|
contextMenuItems?: ContextMenuItem[];
|
|
194
214
|
controlBarItems?: ControlBarItem[];
|
|
195
215
|
}
|
|
@@ -227,6 +247,10 @@ interface ControlsProps {
|
|
|
227
247
|
isLive: boolean;
|
|
228
248
|
qualityLevels: HLSQualityLevel[];
|
|
229
249
|
currentQualityLevel: number;
|
|
250
|
+
showQualityMenu?: boolean;
|
|
251
|
+
manualQualityLevels?: ManualQualityLevel[];
|
|
252
|
+
activeManualSrc?: string;
|
|
253
|
+
onManualQualityChange?: (src: string) => void;
|
|
230
254
|
controlBarItems?: ControlBarItem[];
|
|
231
255
|
autoHideControls: boolean;
|
|
232
256
|
}
|
|
@@ -251,6 +275,11 @@ interface SettingsMenuProps {
|
|
|
251
275
|
qualityLevels?: HLSQualityLevel[];
|
|
252
276
|
currentQualityLevel?: number;
|
|
253
277
|
onQualityChange?: (level: number) => void;
|
|
278
|
+
showQualityMenu?: boolean;
|
|
279
|
+
manualQualityLevels?: ManualQualityLevel[];
|
|
280
|
+
activeManualSrc?: string;
|
|
281
|
+
onManualQualityChange?: (src: string) => void;
|
|
282
|
+
isAudioMode?: boolean;
|
|
254
283
|
}
|
|
255
284
|
declare const SettingsMenu: react.NamedExoticComponent<SettingsMenuProps>;
|
|
256
285
|
|
|
@@ -375,4 +404,4 @@ declare function parseThumbnailVtt(text: string, baseUrl?: string, absoluteRootB
|
|
|
375
404
|
*/
|
|
376
405
|
declare function findThumbnailCue(cues: ThumbnailCue[], time: number): ThumbnailCue | null;
|
|
377
406
|
|
|
378
|
-
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 };
|
|
407
|
+
export { AUDIO_BANDWIDTH_THRESHOLDS, AUDIO_SWITCH_LEVELS, type BufferedRange, type ContextMenuItem, type ControlBarItem, index as ControlElements, Controls, type HLSQualityLevel, type ManualQualityLevel, 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
|
@@ -117,6 +117,12 @@ interface VideoPlayerRef {
|
|
|
117
117
|
getState: () => PlayerState;
|
|
118
118
|
getVideoElement: () => HTMLVideoElement | null;
|
|
119
119
|
}
|
|
120
|
+
interface ManualQualityLevel {
|
|
121
|
+
/** Display label shown in the Quality menu, e.g. "360p", "720p", "1080p" */
|
|
122
|
+
label: string;
|
|
123
|
+
/** URL to load when this quality is selected (HLS m3u8 or direct MP4) */
|
|
124
|
+
src: string;
|
|
125
|
+
}
|
|
120
126
|
interface ContextMenuItem {
|
|
121
127
|
label: string;
|
|
122
128
|
onClick: () => void;
|
|
@@ -190,6 +196,20 @@ interface VideoPlayerOptions {
|
|
|
190
196
|
onBuffering?: (isBuffering: boolean) => void;
|
|
191
197
|
onTheaterModeChange?: (isTheater: boolean) => void;
|
|
192
198
|
onAudioModeChange?: (isAudio: boolean) => void;
|
|
199
|
+
/** Force-show the Quality tab in the Settings menu (useful with manualQualityLevels). */
|
|
200
|
+
showQualityMenu?: boolean;
|
|
201
|
+
/**
|
|
202
|
+
* Manual quality levels for non-adaptive sources.
|
|
203
|
+
* Each entry has a display label and a src URL to load when selected.
|
|
204
|
+
* Works alongside the automatic HLS quality levels — both can be shown at the same time.
|
|
205
|
+
* @example
|
|
206
|
+
* manualQualityLevels={[
|
|
207
|
+
* { label: "1080p", src: "https://cdn.example.com/video_1080.m3u8" },
|
|
208
|
+
* { label: "720p", src: "https://cdn.example.com/video_720.m3u8" },
|
|
209
|
+
* { label: "360p", src: "https://cdn.example.com/video_360.mp4" },
|
|
210
|
+
* ]}
|
|
211
|
+
*/
|
|
212
|
+
manualQualityLevels?: ManualQualityLevel[];
|
|
193
213
|
contextMenuItems?: ContextMenuItem[];
|
|
194
214
|
controlBarItems?: ControlBarItem[];
|
|
195
215
|
}
|
|
@@ -227,6 +247,10 @@ interface ControlsProps {
|
|
|
227
247
|
isLive: boolean;
|
|
228
248
|
qualityLevels: HLSQualityLevel[];
|
|
229
249
|
currentQualityLevel: number;
|
|
250
|
+
showQualityMenu?: boolean;
|
|
251
|
+
manualQualityLevels?: ManualQualityLevel[];
|
|
252
|
+
activeManualSrc?: string;
|
|
253
|
+
onManualQualityChange?: (src: string) => void;
|
|
230
254
|
controlBarItems?: ControlBarItem[];
|
|
231
255
|
autoHideControls: boolean;
|
|
232
256
|
}
|
|
@@ -251,6 +275,11 @@ interface SettingsMenuProps {
|
|
|
251
275
|
qualityLevels?: HLSQualityLevel[];
|
|
252
276
|
currentQualityLevel?: number;
|
|
253
277
|
onQualityChange?: (level: number) => void;
|
|
278
|
+
showQualityMenu?: boolean;
|
|
279
|
+
manualQualityLevels?: ManualQualityLevel[];
|
|
280
|
+
activeManualSrc?: string;
|
|
281
|
+
onManualQualityChange?: (src: string) => void;
|
|
282
|
+
isAudioMode?: boolean;
|
|
254
283
|
}
|
|
255
284
|
declare const SettingsMenu: react.NamedExoticComponent<SettingsMenuProps>;
|
|
256
285
|
|
|
@@ -375,4 +404,4 @@ declare function parseThumbnailVtt(text: string, baseUrl?: string, absoluteRootB
|
|
|
375
404
|
*/
|
|
376
405
|
declare function findThumbnailCue(cues: ThumbnailCue[], time: number): ThumbnailCue | null;
|
|
377
406
|
|
|
378
|
-
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 };
|
|
407
|
+
export { AUDIO_BANDWIDTH_THRESHOLDS, AUDIO_SWITCH_LEVELS, type BufferedRange, type ContextMenuItem, type ControlBarItem, index as ControlElements, Controls, type HLSQualityLevel, type ManualQualityLevel, 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 ut=require('react'),he=require('hls.js'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var ut__default=/*#__PURE__*/_interopDefault(ut);var he__default=/*#__PURE__*/_interopDefault(he);var mt=Object.defineProperty;var ft=(o,r)=>{for(var a in r)mt(o,a,{get:r[a],enumerable:true});};function ve(o){if(!Number.isFinite(o)||o<0)return "0:00";let r=Math.floor(o),a=Math.floor(r/3600),l=Math.floor(r%3600/60),f=r%60;return a>0?`${a}:${String(l).padStart(2,"0")}:${String(f).padStart(2,"0")}`:`${l}:${String(f).padStart(2,"0")}`}function ye(o){try{return new URL(o,"https://x").pathname.toLowerCase().endsWith(".m3u8")||/\/hls\//i.test(o)||/\/stream\.m3u8/i.test(o)}catch{return o.toLowerCase().includes(".m3u8")}}function vt(o){if(ye(o))return "application/x-mpegURL";let r=o.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 Qe(o){return o.map((r,a)=>({id:a,height:r.height??0,width:r.width??0,bitrate:r.bitrate??0,name:r.height?`${r.height}p`:`Level ${a+1}`}))}var gt={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 qe(o,r,a={}){let l=ut.useRef(null),f=ut.useRef(null),v=ut.useRef(null),m=ut.useRef(1),M=ut.useRef(0),L=ut.useRef(0),T=ut.useRef(r),c=ut.useRef(a);c.current=a;let[R,h]=ut.useState({...gt,isMuted:a.muted??false,volume:a.muted?0:1,isAudioMode:a.defaultAudioMode??false}),w=ut.useRef(R);w.current=R;let E=ut.useRef([]),S=ut.useRef(0),D=ut.useRef(false),N=ut.useRef(false),x=ut.useRef(null),C=ut.useRef(null),F=ut.useRef(false),k=ut.useCallback(()=>{let e=c.current;return w.current.isAudioMode&&e.audioSrc&&e.audioRef?.current?e.audioRef.current:o.current},[o]);ut.useEffect(()=>{let e=o.current;if(!e)return;let s=false;if(l.current&&(l.current.destroy(),l.current=null),M.current=0,L.current=0,E.current=[],S.current=0,D.current=false,N.current=false,x.current&&(clearTimeout(x.current),x.current=null),C.current&&(clearTimeout(C.current),C.current=null),F.current=false,h(t=>({...t,currentTime:0,duration:0,error:null,isPlaying:false,isBuffering:!!r,isLive:false,qualityLevels:[],currentQualityLevel:-1,isAudioMode:c.current.defaultAudioMode??false})),!r)return ()=>{s=true;};let d=c.current;if(d.enableHLS!==false&&ye(r))if(he__default.default.isSupported()){let t=new he__default.default({autoStartLoad:true,startLevel:-1,capLevelToPlayerSize:true,capLevelOnFPSDrop:true,enableWorker:true,maxBufferLength:30,maxMaxBufferLength:600,maxBufferSize:6e7,liveBackBufferLength:30,liveSyncDurationCount:3,...d.hlsConfig});t.attachMedia(e),t.loadSource(r),t.on(he.Events.MANIFEST_PARSED,(b,g)=>{if(s)return;let p=Qe(g.levels);h(P=>({...P,qualityLevels:p,currentQualityLevel:-1})),c.current.autoplay&&e.play().catch(()=>{});}),t.on(he.Events.LEVEL_SWITCHED,(b,g)=>{if(s)return;h(u=>({...u,currentQualityLevel:g.level}));let p=c.current,P=p.audioModeSwitchLevel;P===void 0||P<0||!p.audioSrc||N.current||S.current<3||h(u=>!u.isAudioMode&&g.level<=P?(D.current=true,c.current.onAudioModeChange?.(true),{...u,isAudioMode:true}):u);}),t.on(he.Events.FRAG_LOADED,(b,g)=>{if(s)return;L.current=0;let p=c.current;if(!p.audioSrc)return;S.current+=1;let P=g.stats.loading.end-g.stats.loading.start,u=P>0&&g.stats.total>0?g.stats.total*8/P:0,B=p.audioBandwidthThreshold??300;if(F.current){F.current=false,u>0&&B&&u>B*1.5?(D.current=false,t.startLoad(),c.current.onAudioModeChange?.(false),h(y=>({...y,isAudioMode:false}))):(t.stopLoad(),n());return}if(!B||N.current||u<=0)return;let _=E.current;if(_.push(u),_.length>5&&_.shift(),_.length<2)return;let J=_.reduce((y,X)=>y+X,0)/_.length;h(y=>!y.isAudioMode&&J<B?(D.current=true,c.current.onAudioModeChange?.(true),{...y,isAudioMode:true}):y);});let n=()=>{C.current&&clearTimeout(C.current);let b=c.current.audioModeRecoveryInterval??3e4;C.current=setTimeout(()=>{!D.current||!w.current.isAudioMode||(F.current=true,t.startLoad());},b);},i=3;t.on(he.Events.ERROR,(b,g)=>{if(!s){if(!g.fatal){console.warn("[hls] non-fatal:",g.details);return}switch(g.type){case he__default.default.ErrorTypes.NETWORK_ERROR:if(M.current<i){M.current+=1;let p=1e3*M.current;console.warn(`[hls] network error \u2013 retry ${M.current}/${i} in ${p}ms`),setTimeout(()=>{l.current===t&&t.startLoad();},p);}else {let p={code:"HLS_NETWORK_ERROR",message:"Failed to load stream after multiple retries."};h(P=>({...P,error:p})),c.current.onError?.(p);}break;case he__default.default.ErrorTypes.MEDIA_ERROR:if(L.current<i)L.current+=1,console.warn(`[hls] media error \u2013 recovery attempt ${L.current}/${i}`),t.recoverMediaError();else {t.destroy(),l.current=null;let p={code:"HLS_FATAL_ERROR",message:"An unrecoverable media error occurred."};h(P=>({...P,error:p})),c.current.onError?.(p);}break;default:{t.destroy(),l.current=null;let p={code:"HLS_FATAL_ERROR",message:"An unrecoverable HLS error occurred."};h(P=>({...P,error:p})),c.current.onError?.(p);break}}}}),l.current=t;}else e.canPlayType("application/vnd.apple.mpegurl")&&(e.src=r,e.load(),d.autoplay&&e.play().catch(()=>{}));else e.src=r,e.load(),d.autoplay&&e.play().catch(()=>{});return ()=>{s=true,l.current&&(l.current.destroy(),l.current=null),x.current&&(clearTimeout(x.current),x.current=null),C.current&&(clearTimeout(C.current),C.current=null),F.current=false,f.current&&(f.current.destroy(),f.current=null);let t=c.current.audioRef?.current;t&&(t.pause(),t.removeAttribute("src"),t.load());}},[r,o]),ut.useEffect(()=>{let e=o.current;if(!e)return;c.current.muted&&(e.muted=true),c.current.loop&&(e.loop=true);let s=()=>{h(y=>({...y,isPlaying:true})),c.current.onPlay?.();},d=()=>{h(y=>({...y,isPlaying:false})),c.current.onPause?.();},t=()=>{h(y=>({...y,isPlaying:false})),c.current.onEnded?.();},n=()=>{w.current.isAudioMode&&c.current.audioSrc||c.current.onTimeUpdate?.(e.currentTime);},i=()=>{let y=e.duration,X=!Number.isFinite(y);h(fe=>({...fe,duration:X?0:y,isLive:X})),X||c.current.onDurationChange?.(y);},b=()=>{let y=e.volume;y>0&&!e.muted&&(m.current=y),h(X=>({...X,volume:y,isMuted:e.muted||y===0}));},g=()=>{h(y=>({...y,playbackRate:e.playbackRate}));},p=()=>{let y=e.error;if(!y||l.current)return;let fe={code:{1:"MEDIA_ERR_ABORTED",2:"MEDIA_ERR_NETWORK",3:"MEDIA_ERR_DECODE",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"}[y.code]??"UNKNOWN",message:y.message||"Unknown media error"};h(Ie=>({...Ie,error:fe})),c.current.onError?.(fe);},P=()=>{h(y=>({...y,isBuffering:true})),c.current.onBuffering?.(true);},u=()=>{h(y=>({...y,isBuffering:false})),c.current.onBuffering?.(false);},B=()=>h(y=>({...y,isBuffering:false})),_=()=>{let y=!!(document.fullscreenElement||document.webkitFullscreenElement);h(X=>({...X,isFullscreen:y}));},J=()=>{h(y=>({...y,isPictureInPicture:document.pictureInPictureElement===e}));};return e.addEventListener("play",s),e.addEventListener("pause",d),e.addEventListener("ended",t),e.addEventListener("timeupdate",n),e.addEventListener("durationchange",i),e.addEventListener("volumechange",b),e.addEventListener("ratechange",g),e.addEventListener("error",p),e.addEventListener("waiting",P),e.addEventListener("canplay",u),e.addEventListener("playing",B),document.addEventListener("fullscreenchange",_),document.addEventListener("webkitfullscreenchange",_),e.addEventListener("enterpictureinpicture",J),e.addEventListener("leavepictureinpicture",J),()=>{e.removeEventListener("play",s),e.removeEventListener("pause",d),e.removeEventListener("ended",t),e.removeEventListener("timeupdate",n),e.removeEventListener("durationchange",i),e.removeEventListener("volumechange",b),e.removeEventListener("ratechange",g),e.removeEventListener("error",p),e.removeEventListener("waiting",P),e.removeEventListener("canplay",u),e.removeEventListener("playing",B),document.removeEventListener("fullscreenchange",_),document.removeEventListener("webkitfullscreenchange",_),e.removeEventListener("enterpictureinpicture",J),e.removeEventListener("leavepictureinpicture",J);}},[o]),ut.useEffect(()=>{let e=c.current.audioRef?.current;if(!e||!c.current.audioSrc)return;let s=()=>{h(u=>({...u,isPlaying:true})),c.current.onPlay?.();},d=()=>{h(u=>({...u,isPlaying:false})),c.current.onPause?.();},t=()=>{h(u=>({...u,isPlaying:false})),c.current.onEnded?.();},n=()=>{h(u=>({...u,isBuffering:true})),c.current.onBuffering?.(true);},i=()=>{h(u=>({...u,isBuffering:false})),c.current.onBuffering?.(false);},b=()=>h(u=>({...u,isBuffering:false})),g=()=>{w.current.isAudioMode&&c.current.onTimeUpdate?.(e.currentTime);},p=()=>{let u=e.duration;isFinite(u)&&(h(B=>({...B,duration:u})),c.current.onDurationChange?.(u));},P=()=>{if(f.current)return;let u={code:"MEDIA_ERR_NETWORK",message:"Audio source failed to load."};h(B=>({...B,error:u})),c.current.onError?.(u);};return e.addEventListener("play",s),e.addEventListener("pause",d),e.addEventListener("ended",t),e.addEventListener("waiting",n),e.addEventListener("canplay",i),e.addEventListener("playing",b),e.addEventListener("timeupdate",g),e.addEventListener("durationchange",p),e.addEventListener("error",P),()=>{e.removeEventListener("play",s),e.removeEventListener("pause",d),e.removeEventListener("ended",t),e.removeEventListener("waiting",n),e.removeEventListener("canplay",i),e.removeEventListener("playing",b),e.removeEventListener("timeupdate",g),e.removeEventListener("durationchange",p),e.removeEventListener("error",P);}},[r]),ut.useEffect(()=>{let e=c.current,s=o.current,d=e.audioRef?.current;if(!(!s||!d||!e.audioSrc)){if(T.current!==r){T.current=r;return}if(T.current=r,R.isAudioMode){let t=s.currentTime,n=!s.paused,i=s.volume,b=s.muted,g=s.playbackRate;if(s.pause(),l.current?.stopLoad(),ye(e.audioSrc)&&he__default.default.isSupported())if(f.current)d.currentTime=t,n&&d.play().catch(()=>{});else {let p=new he__default.default({autoStartLoad:true,startLevel:-1,enableWorker:true,maxBufferLength:30,...e.hlsConfig});p.attachMedia(d),p.loadSource(e.audioSrc),p.once(he.Events.MANIFEST_PARSED,()=>{d.currentTime=t,d.volume=i,d.muted=b,d.playbackRate=g,n&&d.play().catch(()=>{});}),f.current=p;}else d.getAttribute("src")||(d.src=e.audioSrc),d.currentTime=t,d.volume=i,d.muted=b,d.playbackRate=g,n&&d.play().catch(()=>{});if(D.current){C.current&&clearTimeout(C.current);let p=e.audioModeRecoveryInterval??3e4;C.current=setTimeout(()=>{!D.current||!w.current.isAudioMode||(F.current=true,l.current?.startLoad());},p);}}else {let t=d.currentTime,n=!d.paused;d.pause(),f.current&&(f.current.destroy(),f.current=null,d.removeAttribute("src"),d.load()),C.current&&(clearTimeout(C.current),C.current=null),F.current=false,l.current?.startLoad(),s.currentTime=t,s.volume=d.volume,n&&s.play().catch(()=>{});}}},[R.isAudioMode,o,r]);let q=ut.useCallback(async()=>{let e=k();if(e)try{await e.play();}catch(s){s instanceof Error&&s.name!=="AbortError"&&console.error("[player] play() failed:",s);}},[k]),I=ut.useCallback(()=>{k()?.pause();},[k]),Y=ut.useCallback(e=>{let s=k();s&&(s.currentTime=Math.max(0,Math.min(e,s.duration||e)));},[k]),K=ut.useCallback(e=>{let s=k();if(!s)return;let d=Math.max(0,Math.min(e,1));d>0&&(m.current=d),s.volume=d,s.muted=d===0;},[k]),H=ut.useCallback(()=>{let e=k();if(e)if(e.muted||e.volume===0){let s=m.current>0?m.current:1;e.volume=s,e.muted=false;}else m.current=e.volume,e.muted=true;},[k]),te=ut.useCallback(e=>{let s=o.current;s&&(s.playbackRate=e);let d=c.current.audioRef?.current;d&&(d.playbackRate=e);},[o]),Q=ut.useCallback(e=>{let s=l.current;s&&(s.currentLevel=e,h(d=>({...d,currentQualityLevel:e})));},[]),V=ut.useCallback(()=>{let e=l.current,s=o.current;if(!e||!s)return;let d=e.liveSyncPosition;d!=null&&Number.isFinite(d)&&(s.currentTime=d);},[o]),ne=ut.useCallback(async()=>{let e=o.current;if(!e)return;let s=v.current??e.parentElement;if(s)try{!document.fullscreenElement&&!document.webkitFullscreenElement?s.requestFullscreen?await s.requestFullscreen():s.webkitRequestFullscreen?.():document.exitFullscreen?await document.exitFullscreen():document.webkitExitFullscreen?.();}catch(d){console.error("[player] fullscreen toggle failed:",d);}},[o]),ae=ut.useCallback(async()=>{let e=o.current;if(e)try{document.pictureInPictureElement?await document.exitPictureInPicture():await e.requestPictureInPicture();}catch(s){console.error("[player] PiP toggle failed:",s);}},[o]),ie=ut.useCallback(()=>{let e=!w.current.isTheaterMode;h(s=>({...s,isTheaterMode:e})),c.current.onTheaterModeChange?.(e);},[]),se=ut.useCallback(()=>{x.current&&clearTimeout(x.current),D.current=false,N.current=true,x.current=setTimeout(()=>{N.current=false,E.current=[];},6e4);let e=!w.current.isAudioMode;h(s=>({...s,isAudioMode:e})),c.current.onAudioModeChange?.(e);},[]),ue=ut.useCallback(()=>{let e=k(),s=e?.currentTime??0,d=[];if(e)for(let t=0;t<e.buffered.length;t++)d.push({start:e.buffered.start(t),end:e.buffered.end(t)});return {...w.current,currentTime:s,bufferedRanges:d}},[k]),le=ut.useCallback(()=>o.current??null,[o]),me=ut.useMemo(()=>({play:q,pause:I,seek:Y,setVolume:K,toggleMute:H,setPlaybackRate:te,setQualityLevel:Q,seekToLive:V,toggleFullscreen:ne,togglePictureInPicture:ae,toggleTheaterMode:ie,toggleAudioMode:se,getState:ue,getVideoElement:le}),[q,I,Y,K,H,te,Q,V,ne,ae,ie,se,ue,le]);return {state:R,ref:me,hlsRef:l,fullscreenContainerRef:v}}var nt={};ft(nt,{ControlElements:()=>Z,FullscreenButton:()=>Te,PauseButton:()=>Pe,PiPButton:()=>Re,PlayButton:()=>Le,ProgressBar:()=>Be,SettingsMenu:()=>Ne,TheaterButton:()=>Ce,TimeDisplay:()=>Ae,VolumeControl:()=>Se});var Le=ut.memo(({onClick:o})=>jsxRuntime.jsx("button",{onClick:o,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"})})}));Le.displayName="PlayButton";var Pe=ut.memo(({onClick:o})=>jsxRuntime.jsx("button",{onClick:o,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 Te=ut.memo(({onClick:o,isFullscreen:r=false})=>jsxRuntime.jsx("button",{onClick:o,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"})})}));Te.displayName="FullscreenButton";var Re=ut.memo(({onClick:o,isPiP:r=false})=>jsxRuntime.jsx("button",{onClick:o,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"})})}));Re.displayName="PiPButton";var Ce=ut.memo(({onClick:o,isTheater:r=false})=>jsxRuntime.jsx("button",{onClick:o,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"})})}));Ce.displayName="TheaterButton";var Xe=ut.memo(({volume:o,isMuted:r,onVolumeChange:a,onToggleMute:l})=>{let[f,v]=ut.useState(false),m=r?0:o,M=m*100,L=ut.useMemo(()=>`linear-gradient(to right, #60a5fa 0%, #60a5fa ${M}%, rgba(255,255,255,0.3) ${M}%, rgba(255,255,255,0.3) 100%)`,[M]);return jsxRuntime.jsxs("div",{className:"volumeContainer",onMouseEnter:()=>v(true),onMouseLeave:()=>v(false),children:[jsxRuntime.jsx("button",{onClick:l,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:m===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"}):m<.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"})})}),f&&jsxRuntime.jsx("input",{type:"range",min:"0",max:"100",value:M,onChange:T=>a(Number(T.target.value)/100),className:"volumeSlider",style:{background:L},"aria-label":"Volume","aria-valuenow":Math.round(M)})]})});Xe.displayName="VolumeControl";var Se=Xe;function je(o){let r=o.trim().split(":");return r.length===3?+r[0]*3600+ +r[1]*60+parseFloat(r[2]):+r[0]*60+parseFloat(r[1])}function Lt(o,r,a){if(/^https?:\/\//i.test(r))return r;if(r.startsWith("/")&&a)return a.replace(/\/+$/,"")+r;try{return new URL(r,o).href}catch{return r}}function Oe(o,r="",a){let l=[],f=o.replace(/\r\n/g,`
|
|
1
|
+
'use strict';var Tt=require('react'),ye=require('hls.js'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Tt__default=/*#__PURE__*/_interopDefault(Tt);var ye__default=/*#__PURE__*/_interopDefault(ye);var St=Object.defineProperty;var Bt=(r,n)=>{for(var o in n)St(r,o,{get:n[o],enumerable:true});};function ge(r){if(!Number.isFinite(r)||r<0)return "0:00";let n=Math.floor(r),o=Math.floor(n/3600),l=Math.floor(n%3600/60),c=n%60;return o>0?`${o}:${String(l).padStart(2,"0")}:${String(c).padStart(2,"0")}`:`${l}:${String(c).padStart(2,"0")}`}function Ee(r){try{return new URL(r,"https://x").pathname.toLowerCase().endsWith(".m3u8")||/\/hls\//i.test(r)||/\/stream\.m3u8/i.test(r)}catch{return r.toLowerCase().includes(".m3u8")}}function Nt(r){if(Ee(r))return "application/x-mpegURL";let n=r.toLowerCase().split("?")[0];return n.endsWith(".mp4")?"video/mp4":n.endsWith(".webm")?"video/webm":n.endsWith(".ogv")||n.endsWith(".ogg")?"video/ogg":n.endsWith(".mov")?"video/quicktime":"video/mp4"}function it(r){return r.map((n,o)=>({id:o,height:n.height??0,width:n.width??0,bitrate:n.bitrate??0,name:n.height?`${n.height}p`:`Level ${o+1}`}))}var Ht={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 st(r,n,o={}){let l=Tt.useRef(null),c=Tt.useRef(null),p=Tt.useRef(null),v=Tt.useRef(1),P=Tt.useRef(0),T=Tt.useRef(0),k=Tt.useRef(n),u=Tt.useRef(o);u.current=o;let[R,g]=Tt.useState({...Ht,isMuted:o.muted??false,volume:o.muted?0:1,isAudioMode:o.defaultAudioMode??false}),A=Tt.useRef(R);A.current=R;let N=Tt.useRef([]),H=Tt.useRef(0),V=Tt.useRef(false),S=Tt.useRef(false),B=Tt.useRef(null),w=Tt.useRef(null),F=Tt.useRef(false),C=Tt.useCallback(()=>{let e=u.current;return A.current.isAudioMode&&e.audioSrc&&e.audioRef?.current?e.audioRef.current:r.current},[r]);Tt.useEffect(()=>{let e=r.current;if(!e)return;let s=false;if(l.current&&(l.current.destroy(),l.current=null),P.current=0,T.current=0,N.current=[],H.current=0,V.current=false,S.current=false,B.current&&(clearTimeout(B.current),B.current=null),w.current&&(clearTimeout(w.current),w.current=null),F.current=false,g(t=>({...t,currentTime:0,duration:0,error:null,isPlaying:false,isBuffering:!!n,isLive:false,qualityLevels:[],currentQualityLevel:-1,isAudioMode:u.current.defaultAudioMode??false})),!n)return ()=>{s=true;};let d=u.current;if(d.enableHLS!==false&&Ee(n))if(ye__default.default.isSupported()){let t=new ye__default.default({autoStartLoad:true,startLevel:-1,capLevelToPlayerSize:true,capLevelOnFPSDrop:true,enableWorker:true,maxBufferLength:30,maxMaxBufferLength:600,maxBufferSize:6e7,liveBackBufferLength:30,liveSyncDurationCount:3,...d.hlsConfig});t.attachMedia(e),t.loadSource(n),t.on(ye.Events.MANIFEST_PARSED,(E,y)=>{if(s)return;let i=it(y.levels);g(m=>({...m,qualityLevels:i,currentQualityLevel:-1})),u.current.autoplay&&e.play().catch(()=>{});}),t.on(ye.Events.LEVEL_SWITCHED,(E,y)=>{if(s)return;g(b=>({...b,currentQualityLevel:y.level}));let i=u.current,m=i.audioModeSwitchLevel;m===void 0||m<0||!i.audioSrc||S.current||H.current<3||g(b=>!b.isAudioMode&&y.level<=m?(V.current=true,u.current.onAudioModeChange?.(true),{...b,isAudioMode:true}):b);}),t.on(ye.Events.FRAG_LOADED,(E,y)=>{if(s)return;T.current=0;let i=u.current;if(!i.audioSrc)return;H.current+=1;let m=y.stats.loading.end-y.stats.loading.start,b=m>0&&y.stats.total>0?y.stats.total*8/m:0,z=i.audioBandwidthThreshold??300;if(F.current){F.current=false,b>0&&z&&b>z*1.5?(V.current=false,t.startLoad(),u.current.onAudioModeChange?.(false),g(M=>({...M,isAudioMode:false}))):(t.stopLoad(),a());return}if(!z||S.current||b<=0)return;let K=N.current;if(K.push(b),K.length>5&&K.shift(),K.length<2)return;let ne=K.reduce((M,X)=>M+X,0)/K.length;g(M=>!M.isAudioMode&&ne<z?(V.current=true,u.current.onAudioModeChange?.(true),{...M,isAudioMode:true}):M);});let a=()=>{w.current&&clearTimeout(w.current);let E=u.current.audioModeRecoveryInterval??3e4;w.current=setTimeout(()=>{!V.current||!A.current.isAudioMode||(F.current=true,t.startLoad());},E);},f=3;t.on(ye.Events.ERROR,(E,y)=>{if(!s){if(!y.fatal){console.warn("[hls] non-fatal:",y.details);return}switch(y.type){case ye__default.default.ErrorTypes.NETWORK_ERROR:if(P.current<f){P.current+=1;let i=1e3*P.current;console.warn(`[hls] network error \u2013 retry ${P.current}/${f} in ${i}ms`),setTimeout(()=>{l.current===t&&t.startLoad();},i);}else {let i={code:"HLS_NETWORK_ERROR",message:"Failed to load stream after multiple retries."};g(m=>({...m,error:i})),u.current.onError?.(i);}break;case ye__default.default.ErrorTypes.MEDIA_ERROR:if(T.current<f)T.current+=1,console.warn(`[hls] media error \u2013 recovery attempt ${T.current}/${f}`),t.recoverMediaError();else {t.destroy(),l.current=null;let i={code:"HLS_FATAL_ERROR",message:"An unrecoverable media error occurred."};g(m=>({...m,error:i})),u.current.onError?.(i);}break;default:{t.destroy(),l.current=null;let i={code:"HLS_FATAL_ERROR",message:"An unrecoverable HLS error occurred."};g(m=>({...m,error:i})),u.current.onError?.(i);break}}}}),l.current=t;}else e.canPlayType("application/vnd.apple.mpegurl")&&(e.src=n,e.load(),d.autoplay&&e.play().catch(()=>{}));else e.src=n,e.load(),d.autoplay&&e.play().catch(()=>{});return ()=>{s=true,l.current&&(l.current.destroy(),l.current=null),B.current&&(clearTimeout(B.current),B.current=null),w.current&&(clearTimeout(w.current),w.current=null),F.current=false,c.current&&(c.current.destroy(),c.current=null);let t=u.current.audioRef?.current;t&&(t.pause(),t.removeAttribute("src"),t.load());}},[n,r]),Tt.useEffect(()=>{let e=r.current;if(!e)return;u.current.muted&&(e.muted=true),u.current.loop&&(e.loop=true);let s=()=>{g(M=>({...M,isPlaying:true})),u.current.onPlay?.();},d=()=>{g(M=>({...M,isPlaying:false})),u.current.onPause?.();},t=()=>{g(M=>({...M,isPlaying:false})),u.current.onEnded?.();},a=()=>{A.current.isAudioMode&&u.current.audioSrc||u.current.onTimeUpdate?.(e.currentTime);},f=()=>{let M=e.duration,X=!Number.isFinite(M);g(ae=>({...ae,duration:X?0:M,isLive:X})),X||u.current.onDurationChange?.(M);},E=()=>{let M=e.volume;M>0&&!e.muted&&(v.current=M),g(X=>({...X,volume:M,isMuted:e.muted||M===0}));},y=()=>{g(M=>({...M,playbackRate:e.playbackRate}));},i=()=>{let M=e.error;if(!M||l.current)return;let ae={code:{1:"MEDIA_ERR_ABORTED",2:"MEDIA_ERR_NETWORK",3:"MEDIA_ERR_DECODE",4:"MEDIA_ERR_SRC_NOT_SUPPORTED"}[M.code]??"UNKNOWN",message:M.message||"Unknown media error"};g(Ue=>({...Ue,error:ae})),u.current.onError?.(ae);},m=()=>{g(M=>({...M,isBuffering:true})),u.current.onBuffering?.(true);},b=()=>{g(M=>({...M,isBuffering:false})),u.current.onBuffering?.(false);},z=()=>g(M=>({...M,isBuffering:false})),K=()=>{let M=!!(document.fullscreenElement||document.webkitFullscreenElement);g(X=>({...X,isFullscreen:M}));},ne=()=>{g(M=>({...M,isPictureInPicture:document.pictureInPictureElement===e}));};return e.addEventListener("play",s),e.addEventListener("pause",d),e.addEventListener("ended",t),e.addEventListener("timeupdate",a),e.addEventListener("durationchange",f),e.addEventListener("volumechange",E),e.addEventListener("ratechange",y),e.addEventListener("error",i),e.addEventListener("waiting",m),e.addEventListener("canplay",b),e.addEventListener("playing",z),document.addEventListener("fullscreenchange",K),document.addEventListener("webkitfullscreenchange",K),e.addEventListener("enterpictureinpicture",ne),e.addEventListener("leavepictureinpicture",ne),()=>{e.removeEventListener("play",s),e.removeEventListener("pause",d),e.removeEventListener("ended",t),e.removeEventListener("timeupdate",a),e.removeEventListener("durationchange",f),e.removeEventListener("volumechange",E),e.removeEventListener("ratechange",y),e.removeEventListener("error",i),e.removeEventListener("waiting",m),e.removeEventListener("canplay",b),e.removeEventListener("playing",z),document.removeEventListener("fullscreenchange",K),document.removeEventListener("webkitfullscreenchange",K),e.removeEventListener("enterpictureinpicture",ne),e.removeEventListener("leavepictureinpicture",ne);}},[r]),Tt.useEffect(()=>{let e=u.current.audioRef?.current;if(!e||!u.current.audioSrc)return;let s=()=>{g(b=>({...b,isPlaying:true})),u.current.onPlay?.();},d=()=>{g(b=>({...b,isPlaying:false})),u.current.onPause?.();},t=()=>{g(b=>({...b,isPlaying:false})),u.current.onEnded?.();},a=()=>{g(b=>({...b,isBuffering:true})),u.current.onBuffering?.(true);},f=()=>{g(b=>({...b,isBuffering:false})),u.current.onBuffering?.(false);},E=()=>g(b=>({...b,isBuffering:false})),y=()=>{A.current.isAudioMode&&u.current.onTimeUpdate?.(e.currentTime);},i=()=>{let b=e.duration;isFinite(b)&&(g(z=>({...z,duration:b})),u.current.onDurationChange?.(b));},m=()=>{if(c.current)return;let b={code:"MEDIA_ERR_NETWORK",message:"Audio source failed to load."};g(z=>({...z,error:b})),u.current.onError?.(b);};return e.addEventListener("play",s),e.addEventListener("pause",d),e.addEventListener("ended",t),e.addEventListener("waiting",a),e.addEventListener("canplay",f),e.addEventListener("playing",E),e.addEventListener("timeupdate",y),e.addEventListener("durationchange",i),e.addEventListener("error",m),()=>{e.removeEventListener("play",s),e.removeEventListener("pause",d),e.removeEventListener("ended",t),e.removeEventListener("waiting",a),e.removeEventListener("canplay",f),e.removeEventListener("playing",E),e.removeEventListener("timeupdate",y),e.removeEventListener("durationchange",i),e.removeEventListener("error",m);}},[n]),Tt.useEffect(()=>{let e=u.current,s=r.current,d=e.audioRef?.current;if(!(!s||!d||!e.audioSrc)){if(k.current!==n){k.current=n;return}if(k.current=n,R.isAudioMode){let t=s.currentTime,a=!s.paused,f=s.volume,E=s.muted,y=s.playbackRate;if(s.pause(),l.current?.stopLoad(),Ee(e.audioSrc)&&ye__default.default.isSupported())if(c.current)d.currentTime=t,a&&d.play().catch(()=>{});else {let i=new ye__default.default({autoStartLoad:true,startLevel:-1,enableWorker:true,maxBufferLength:30,...e.hlsConfig});i.attachMedia(d),i.loadSource(e.audioSrc),i.once(ye.Events.MANIFEST_PARSED,()=>{d.currentTime=t,d.volume=f,d.muted=E,d.playbackRate=y,a&&d.play().catch(()=>{});}),c.current=i;}else d.getAttribute("src")||(d.src=e.audioSrc),d.currentTime=t,d.volume=f,d.muted=E,d.playbackRate=y,a&&d.play().catch(()=>{});if(V.current){w.current&&clearTimeout(w.current);let i=e.audioModeRecoveryInterval??3e4;w.current=setTimeout(()=>{!V.current||!A.current.isAudioMode||(F.current=true,l.current?.startLoad());},i);}}else {let t=d.currentTime,a=!d.paused;d.pause(),c.current&&(c.current.destroy(),c.current=null,d.removeAttribute("src"),d.load()),w.current&&(clearTimeout(w.current),w.current=null),F.current=false,l.current?.startLoad(),s.currentTime=t,s.volume=d.volume,a&&s.play().catch(()=>{});}}},[R.isAudioMode,r,n]);let W=Tt.useCallback(async()=>{let e=C();if(e)try{await e.play();}catch(s){s instanceof Error&&s.name!=="AbortError"&&console.error("[player] play() failed:",s);}},[C]),h=Tt.useCallback(()=>{C()?.pause();},[C]),D=Tt.useCallback(e=>{let s=C();s&&(s.currentTime=Math.max(0,Math.min(e,s.duration||e)));},[C]),J=Tt.useCallback(e=>{let s=C();if(!s)return;let d=Math.max(0,Math.min(e,1));d>0&&(v.current=d),s.volume=d,s.muted=d===0;},[C]),me=Tt.useCallback(()=>{let e=C();if(e)if(e.muted||e.volume===0){let s=v.current>0?v.current:1;e.volume=s,e.muted=false;}else v.current=e.volume,e.muted=true;},[C]),se=Tt.useCallback(e=>{let s=r.current;s&&(s.playbackRate=e);let d=u.current.audioRef?.current;d&&(d.playbackRate=e);},[r]),le=Tt.useCallback(e=>{let s=l.current;s&&(s.currentLevel=e,g(d=>({...d,currentQualityLevel:e})));},[]),_=Tt.useCallback(()=>{let e=l.current,s=r.current;if(!e||!s)return;let d=e.liveSyncPosition;d!=null&&Number.isFinite(d)&&(s.currentTime=d);},[r]),I=Tt.useCallback(async()=>{let e=r.current;if(!e)return;let s=p.current??e.parentElement;if(s)try{!document.fullscreenElement&&!document.webkitFullscreenElement?s.requestFullscreen?await s.requestFullscreen():s.webkitRequestFullscreen?.():document.exitFullscreen?await document.exitFullscreen():document.webkitExitFullscreen?.();}catch(d){console.error("[player] fullscreen toggle failed:",d);}},[r]),ue=Tt.useCallback(async()=>{let e=r.current;if(e)try{document.pictureInPictureElement?await document.exitPictureInPicture():await e.requestPictureInPicture();}catch(s){console.error("[player] PiP toggle failed:",s);}},[r]),Z=Tt.useCallback(()=>{let e=!A.current.isTheaterMode;g(s=>({...s,isTheaterMode:e})),u.current.onTheaterModeChange?.(e);},[]),ce=Tt.useCallback(()=>{B.current&&clearTimeout(B.current),V.current=false,S.current=true,B.current=setTimeout(()=>{S.current=false,N.current=[];},6e4);let e=!A.current.isAudioMode;g(s=>({...s,isAudioMode:e})),u.current.onAudioModeChange?.(e);},[]),fe=Tt.useCallback(()=>{let e=C(),s=e?.currentTime??0,d=[];if(e)for(let t=0;t<e.buffered.length;t++)d.push({start:e.buffered.start(t),end:e.buffered.end(t)});return {...A.current,currentTime:s,bufferedRanges:d}},[C]),ve=Tt.useCallback(()=>r.current??null,[r]),he=Tt.useMemo(()=>({play:W,pause:h,seek:D,setVolume:J,toggleMute:me,setPlaybackRate:se,setQualityLevel:le,seekToLive:_,toggleFullscreen:I,togglePictureInPicture:ue,toggleTheaterMode:Z,toggleAudioMode:ce,getState:fe,getVideoElement:ve}),[W,h,D,J,me,se,le,_,I,ue,Z,ce,fe,ve]);return {state:R,ref:he,hlsRef:l,fullscreenContainerRef:p}}var yt={};Bt(yt,{ControlElements:()=>re,FullscreenButton:()=>we,PauseButton:()=>Re,PiPButton:()=>ke,PlayButton:()=>Ce,ProgressBar:()=>Ve,SettingsMenu:()=>Oe,TheaterButton:()=>xe,TimeDisplay:()=>_e,VolumeControl:()=>He});var Ce=Tt.memo(({onClick:r})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":"Play",title:"Play (Space)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M8 5v14l11-7z"})})}));Ce.displayName="PlayButton";var Re=Tt.memo(({onClick:r})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":"Pause",title:"Pause (Space)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M6 4h4v16H6V4zm8 0h4v16h-4V4z"})})}));Re.displayName="PauseButton";var we=Tt.memo(({onClick:r,isFullscreen:n=false})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":n?"Exit Fullscreen":"Fullscreen",title:n?"Exit Fullscreen (F)":"Fullscreen (F)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:n?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"})})}));we.displayName="FullscreenButton";var ke=Tt.memo(({onClick:r,isPiP:n=false})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":n?"Exit Picture-in-Picture":"Picture-in-Picture",title:n?"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"})})}));ke.displayName="PiPButton";var xe=Tt.memo(({onClick:r,isTheater:n=false})=>jsxRuntime.jsx("button",{onClick:r,className:"controlButton","aria-label":n?"Exit Theater Mode":"Theater Mode",title:n?"Exit Theater Mode (T)":"Theater Mode (T)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:n?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"})})}));xe.displayName="TheaterButton";var lt=Tt.memo(({volume:r,isMuted:n,onVolumeChange:o,onToggleMute:l})=>{let[c,p]=Tt.useState(false),v=n?0:r,P=v*100,T=Tt.useMemo(()=>`linear-gradient(to right, #60a5fa 0%, #60a5fa ${P}%, rgba(255,255,255,0.3) ${P}%, rgba(255,255,255,0.3) 100%)`,[P]);return jsxRuntime.jsxs("div",{className:"volumeContainer",onMouseEnter:()=>p(true),onMouseLeave:()=>p(false),children:[jsxRuntime.jsx("button",{onClick:l,className:"controlButton","aria-label":n?"Unmute":"Mute",title:n?"Unmute (M)":"Mute (M)",children:jsxRuntime.jsx("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"currentColor",children:v===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"}):v<.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"})})}),c&&jsxRuntime.jsx("input",{type:"range",min:"0",max:"100",value:P,onChange:k=>o(Number(k.target.value)/100),className:"volumeSlider",style:{background:T},"aria-label":"Volume","aria-valuenow":Math.round(P)})]})});lt.displayName="VolumeControl";var He=lt;function ut(r){let n=r.trim().split(":");return n.length===3?+n[0]*3600+ +n[1]*60+parseFloat(n[2]):+n[0]*60+parseFloat(n[1])}function _t(r,n,o){if(/^https?:\/\//i.test(n))return n;if(n.startsWith("/")&&o)return o.replace(/\/+$/,"")+n;try{return new URL(n,r).href}catch{return n}}function Ke(r,n="",o){let l=[],c=r.replace(/\r\n/g,`
|
|
2
2
|
`).split(`
|
|
3
|
-
`),v=0;for(;v<f.length;){let m=f[v].trim();if(m.includes("-->")){let M=m.indexOf("-->"),L=je(m.slice(0,M)),T=je(m.slice(M+3));for(v++;v<f.length&&!f[v].trim();)v++;if(v<f.length){let c=f[v].trim(),R=c.lastIndexOf("#xywh="),h=c,w=0,E=0,S=160,D=90;if(R!==-1){h=c.slice(0,R);let N=c.slice(R+6).split(",").map(Number);w=N[0]??0,E=N[1]??0,S=N[2]??160,D=N[3]??90;}l.push({start:L,end:T,url:Lt(r,h,a),x:w,y:E,w:S,h:D});}}v++;}return l}function Fe(o,r){if(!o.length)return null;let a=0,l=o.length-1;for(;a<=l;){let f=a+l>>1;if(o[f].end<=r)a=f+1;else if(o[f].start>r)l=f-1;else return o[f]}return null}var Ye=ut.memo(({videoRef:o,playerRef:r,enablePreview:a=true,thumbnailVtt:l,thumbnailVttBaseUrl:f,isAudioMode:v=false})=>{let m=ut.useRef(null),M=ut.useRef(null),L=ut.useRef(null),T=ut.useRef(null),c=ut.useRef(null),R=ut.useRef(null),h=ut.useRef(null),w=ut.useRef(null),E=ut.useRef(null),[S,D]=ut.useState([]),N=ut.useRef(false),x=ut.useRef(0),C=ut.useRef(0),F=ut.useRef(null),k=ut.useRef([]),q=ut.useRef(null);ut.useEffect(()=>{let t=()=>{q.current=null;};return window.addEventListener("resize",t,{passive:true}),()=>window.removeEventListener("resize",t)},[]);let I=ut.useCallback(()=>(!q.current&&m.current&&(q.current=m.current.getBoundingClientRect()),q.current),[]);ut.useEffect(()=>{if(!l){k.current=[];return}let t=false;return fetch(l).then(n=>n.text()).then(n=>{t||(k.current=Oe(n,l,f));}).catch(()=>{t||(k.current=[]);}),()=>{t=true;}},[l]),ut.useEffect(()=>{let t=o.current;if(!t)return;let n=()=>{let i=isFinite(t.duration)?t.duration:0,b=t.currentTime,g=i>0?b/i*100:0;M.current&&(M.current.style.width=`${g}%`),L.current&&(L.current.style.left=`${g}%`),w.current&&(w.current.style.clipPath=`inset(0 ${(100-g).toFixed(2)}% 0 0)`),m.current&&(m.current.setAttribute("aria-valuenow",String(Math.round(b))),m.current.setAttribute("aria-valuemax",String(Math.round(i))),m.current.setAttribute("aria-valuetext",ve(b)));};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);}},[o,v]),ut.useEffect(()=>{let t=o.current;if(!t)return;let n=()=>{let i=[];for(let b=0;b<t.buffered.length;b++)i.push({start:t.buffered.start(b),end:t.buffered.end(b)});if(v||D(i),E.current&&isFinite(t.duration)&&t.duration>0){let g=i.reduce((p,P)=>Math.max(p,P.end),0)/t.duration*100;E.current.style.clipPath=`inset(0 ${(100-g).toFixed(2)}% 0 0)`;}};return t.addEventListener("progress",n),()=>t.removeEventListener("progress",n)},[o,v]);let Y=ut.useCallback(()=>{N.current=true,L.current?.classList.add("dragging");},[]),K=ut.useCallback(()=>{N.current=false,L.current?.classList.remove("dragging");},[]),H=ut.useCallback(()=>{!a||v||(q.current=null,T.current&&(T.current.style.display="block"),R.current&&(R.current.style.display="block"));},[a,v]),te=ut.useCallback(()=>{T.current&&(T.current.style.display="none"),R.current&&(R.current.style.display="none");},[]),Q=ut.useCallback(t=>{if(!h.current||!k.current.length)return;let n=Fe(k.current,t);if(F.current=n,!n)return;let i=h.current;i.style.backgroundImage=`url(${n.url})`,i.style.backgroundPosition=`-${n.x}px -${n.y}px`,i.style.width=`${n.w}px`,i.style.height=`${n.h}px`;},[]),V=ut.useCallback(t=>{let n=I(),i=o.current?.duration;return !n||n.width===0||!i||!isFinite(i)?0:Math.max(0,Math.min(t-n.left,n.width))/n.width*i},[I,o]),ne=ut.useCallback(t=>{let n=I();return n?Math.max(0,Math.min(t-n.left,n.width)):0},[I]),ae=ut.useCallback(t=>{let n=o.current;if(!n)return;let i=n.currentTime,b=isFinite(n.duration)?n.duration:0;switch(t.key){case "ArrowLeft":case "ArrowRight":{t.preventDefault(),t.nativeEvent.stopImmediatePropagation();let g=t.shiftKey?10:5;r.seek(t.key==="ArrowLeft"?Math.max(0,i-g):Math.min(b,i+g));break}case "Home":t.preventDefault(),t.nativeEvent.stopImmediatePropagation(),r.seek(0);break;case "End":b>0&&(t.preventDefault(),t.nativeEvent.stopImmediatePropagation(),r.seek(b));break}},[o,r]),ie=ut.useCallback(t=>{let n=V(t.clientX),i=ne(t.clientX);if(x.current=i,C.current=n,R.current&&(R.current.style.left=`${i}px`),c.current&&(c.current.textContent=ve(n)),Q(n),T.current){let b=T.current.offsetWidth,g=I()?.width??0,p=b/2,P=Math.max(p,Math.min(i,g-p));T.current.style.left=`${P}px`;}N.current&&r.seek(n);},[r,Q,V,ne,I]),se=ut.useCallback(()=>{te(),K();},[te,K]),ue=ut.useCallback(t=>{t.preventDefault(),Y(),r.seek(V(t.clientX));},[Y,V,r]),le=ut.useCallback(t=>{N.current||r.seek(V(t.clientX));},[V,r]);ut.useEffect(()=>{let t=m.current;if(!t)return;let n=i=>{N.current&&i.preventDefault();};return t.addEventListener("touchmove",n,{passive:false}),()=>t.removeEventListener("touchmove",n)},[]);let me=ut.useCallback(t=>{q.current=null,Y(),r.seek(V(t.touches[0].clientX));},[Y,V,r]),e=ut.useCallback(t=>{N.current&&r.seek(V(t.touches[0].clientX));},[V,r]);ut.useEffect(()=>{let t=()=>K();return window.addEventListener("mouseup",t),()=>window.removeEventListener("mouseup",t)},[K]);let s=ut.useMemo(()=>{let n=[],i=3735928559,b=()=>(i^=i<<13,i^=i>>17,i^=i<<5,(i>>>0)/4294967295);for(let g=0;g<200;g++){let p=g/200*Math.PI*5,P=.15+.55*Math.abs(Math.sin(p))+.3*b();n.push(Math.max(.1,Math.min(1,P)));}return n},[]),d=ut.useMemo(()=>{let t=o.current,n=t&&isFinite(t.duration)?t.duration:0;return n<=0||!S.length?null:S.map((i,b)=>{let g=i.start/n*100,p=(i.end-i.start)/n*100;return jsxRuntime.jsx("div",{className:"bufferedSegment",style:{left:`${g}%`,width:`${p}%`}},b)})},[S,o]);return jsxRuntime.jsxs("div",{ref:m,className:"progressContainer",onMouseMove:ie,onMouseEnter:H,onMouseLeave:se,onMouseDown:ue,onMouseUp:K,onClick:le,onTouchStart:me,onTouchMove:e,onTouchEnd:K,onKeyDown:ae,role:"slider","aria-label":v?"Audio progress":"Video progress","aria-valuemin":0,"aria-valuemax":0,"aria-valuenow":0,"aria-valuetext":"0:00",tabIndex:0,children:[a&&jsxRuntime.jsxs("div",{ref:T,className:"previewTooltip",style:{left:0,display:"none"},"aria-hidden":"true",children:[l&&jsxRuntime.jsx("div",{ref:h,className:"previewThumbnail"}),jsxRuntime.jsx("div",{ref:c,className:"previewTime"})]}),v?jsxRuntime.jsxs("div",{className:"rvp-waveform","aria-hidden":"true",children:[jsxRuntime.jsx("div",{className:"rvp-waveform-base",children:s.map((t,n)=>jsxRuntime.jsx("div",{className:"rvp-waveform-dot"},n))}),jsxRuntime.jsx("div",{ref:E,className:"rvp-waveform-buffered",style:{clipPath:"inset(0 100% 0 0)"},children:s.map((t,n)=>jsxRuntime.jsx("div",{className:"rvp-waveform-buffered-bar",style:{height:`${Math.round(t*100)}%`}},n))}),jsxRuntime.jsx("div",{ref:w,className:"rvp-waveform-filled",children:s.map((t,n)=>jsxRuntime.jsx("div",{className:"rvp-waveform-bar",style:{height:`${Math.round(t*100)}%`}},n))})]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"progressBackground",children:[d,jsxRuntime.jsx("div",{ref:M,className:"progressFilled",style:{width:"0%"}}),a&&jsxRuntime.jsx("div",{ref:R,className:"hoverIndicator",style:{left:0,display:"none"},"aria-hidden":"true"})]}),jsxRuntime.jsx("div",{ref:L,className:"scrubHandle",style:{left:"0%"},"aria-hidden":"true"})]})]})});Ye.displayName="ProgressBar";var Be=Ye;var et=ut.memo(({currentRate:o,playbackRates:r,onRateChange:a,qualityLevels:l=[],currentQualityLevel:f=-1,onQualityChange:v})=>{let[m,M]=ut.useState(false),[L,T]=ut.useState("speed"),c=ut.useRef(null),R=l.length>0&&!!v;ut.useEffect(()=>{let E=S=>{c.current&&!c.current.contains(S.target)&&M(false);};return m&&document.addEventListener("mousedown",E),()=>document.removeEventListener("mousedown",E)},[m]);let h=ut.useMemo(()=>[...l].sort((E,S)=>S.bitrate-E.bitrate),[l]),w=ut.useMemo(()=>f===-1?"Auto":l.find(E=>E.id===f)?.name??"Auto",[l,f]);return jsxRuntime.jsxs("div",{ref:c,className:"settingsContainer",children:[jsxRuntime.jsx("button",{onClick:()=>M(E=>!E),className:"controlButton","aria-label":"Settings",title:"Settings","aria-expanded":m,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"})})}),m&&jsxRuntime.jsxs("div",{className:"settingsDropdown",role:"menu",children:[R&&jsxRuntime.jsxs("div",{className:"settingsTabs",children:[jsxRuntime.jsx("button",{className:`settingsTab${L==="speed"?" active":""}`,onClick:()=>T("speed"),children:"Speed"}),jsxRuntime.jsx("button",{className:`settingsTab${L==="quality"?" active":""}`,onClick:()=>T("quality"),children:"Quality"})]}),(!R||L==="speed")&&jsxRuntime.jsxs("div",{children:[!R&&jsxRuntime.jsx("div",{className:"settingsPanelLabel",children:"Playback Speed"}),r.map(E=>jsxRuntime.jsx("button",{onClick:()=>{a(E),M(false);},className:`settingsOption${o===E?" active":""}`,role:"menuitemradio","aria-checked":o===E,children:E===1?"Normal":`${E}\xD7`},E))]}),R&&L==="quality"&&jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("button",{onClick:()=>{v(-1),M(false);},className:`settingsOption${f===-1?" active":""}`,role:"menuitemradio","aria-checked":f===-1,children:["Auto ",f===-1&&w!=="Auto"?`(${w})`:""]}),h.map(E=>jsxRuntime.jsxs("button",{onClick:()=>{v(E.id),M(false);},className:`settingsOption${f===E.id?" active":""}`,role:"menuitemradio","aria-checked":f===E.id,children:[E.name,E.bitrate>0&&jsxRuntime.jsxs("span",{className:"settingsOptionBadge",children:[Math.round(E.bitrate/1e3)," kbps"]})]},E.id))]})]})]})});et.displayName="SettingsMenu";var Ne=et;var rt=ut.memo(({videoRef:o,isLive:r=false,isAudioMode:a=false})=>{let l=ut.useRef(null),f=ut.useRef(null);return ut.useEffect(()=>{let v=o.current;if(!v)return;let m=()=>{l.current&&(l.current.textContent=ve(v.currentTime));},M=()=>{if(f.current){let L=isFinite(v.duration)?v.duration:0;f.current.textContent=` / ${ve(L)}`;}};return v.addEventListener("timeupdate",m),v.addEventListener("durationchange",M),v.addEventListener("seeked",m),m(),M(),()=>{v.removeEventListener("timeupdate",m),v.removeEventListener("durationchange",M),v.removeEventListener("seeked",m);}},[o,r,a]),r?jsxRuntime.jsx("span",{className:"timeDisplay",style:{opacity:.7},children:jsxRuntime.jsx("span",{ref:l,children:"0:00"})}):jsxRuntime.jsxs("span",{className:"timeDisplay",children:[jsxRuntime.jsx("span",{ref:l,children:"0:00"}),jsxRuntime.jsx("span",{ref:f,style:{opacity:.6},children:" / 0:00"})]})});rt.displayName="TimeDisplay";var Ae=rt;var Z={PlayButton:Le,PauseButton:Pe,FullscreenButton:Te,PiPButton:Re,TheaterButton:Ce,VolumeControl:Se,ProgressBar:Be,SettingsMenu:Ne,TimeDisplay:Ae};var He=ut.memo(function({videoRef:r,playerRef:a,playerContainerRef:l,playbackRates:f,enablePreview:v,thumbnailVtt:m,thumbnailVttBaseUrl:M,isPlaying:L,volume:T,isMuted:c,playbackRate:R,isFullscreen:h,isPictureInPicture:w,isTheaterMode:E,isAudioMode:S,showAudioButton:D,audioModeIcon:N,videoModeIcon:x,audioModeLabel:C,videoModeLabel:F,isLive:k,qualityLevels:q,currentQualityLevel:I,controlBarItems:Y,autoHideControls:K}){let H=ut.useRef(null),[te,Q]=ut.useState(true),V=ut.useRef({isPlaying:L,volume:T,isMuted:c,isLive:k});V.current={isPlaying:L,volume:T,isMuted:c,isLive:k},ut.useEffect(()=>{if(S||!K){Q(true),H.current&&clearTimeout(H.current);return}if(!L){Q(true),H.current&&clearTimeout(H.current);return}let n=l.current;if(!n)return;let i=()=>{Q(true),H.current&&clearTimeout(H.current),H.current=setTimeout(()=>Q(false),3e3);},b=()=>{H.current&&clearTimeout(H.current),Q(false);};return n.addEventListener("mousemove",i),n.addEventListener("mouseenter",i),n.addEventListener("mouseleave",b),n.addEventListener("touchstart",i,{passive:true}),Q(false),()=>{n.removeEventListener("mousemove",i),n.removeEventListener("mouseenter",i),n.removeEventListener("mouseleave",b),n.removeEventListener("touchstart",i),H.current&&clearTimeout(H.current);}},[L,S,K,l]),ut.useEffect(()=>{let n=i=>{if(!l.current?.contains(document.activeElement))return;let b=i.target;if(b.tagName==="INPUT"||b.tagName==="TEXTAREA"||b.isContentEditable)return;let{isPlaying:g,volume:p,isLive:P}=V.current,u=r.current?.currentTime??0,B=r.current?.duration??0;switch(i.code){case "Space":case "KeyK":i.preventDefault(),g?a.pause():a.play();break;case "ArrowLeft":i.preventDefault(),a.seek(Math.max(0,u-5));break;case "ArrowRight":i.preventDefault(),a.seek(Math.min(B||1/0,u+5));break;case "ArrowUp":i.preventDefault(),a.setVolume(Math.min(1,p+.1));break;case "ArrowDown":i.preventDefault(),a.setVolume(Math.max(0,p-.1));break;case "KeyM":i.preventDefault(),a.toggleMute();break;case "KeyF":i.preventDefault(),a.toggleFullscreen();break;case "KeyP":i.preventDefault(),a.togglePictureInPicture();break;case "KeyT":i.preventDefault(),a.toggleTheaterMode();break;case "KeyL":i.preventDefault(),P&&a.seekToLive();break;case "Digit0":case "Digit1":case "Digit2":case "Digit3":case "Digit4":case "Digit5":case "Digit6":case "Digit7":case "Digit8":case "Digit9":{i.preventDefault();let _=Number(i.code.replace("Digit",""))*10;a.seek(B/100*_);break}}};return window.addEventListener("keydown",n),()=>window.removeEventListener("keydown",n)},[a,l,r]);let ne=ut.useCallback(()=>a.play(),[a]),ae=ut.useCallback(()=>a.pause(),[a]),ie=ut.useCallback(n=>a.setVolume(n),[a]),se=ut.useCallback(()=>a.toggleMute(),[a]),ue=ut.useCallback(n=>a.setPlaybackRate(n),[a]),le=ut.useCallback(n=>a.setQualityLevel(n),[a]),me=ut.useCallback(()=>a.togglePictureInPicture(),[a]),e=ut.useCallback(()=>a.toggleTheaterMode(),[a]),s=ut.useCallback(()=>a.toggleAudioMode(),[a]),d=ut.useCallback(()=>a.toggleFullscreen(),[a]),t=ut.useCallback(()=>a.seekToLive(),[a]);return jsxRuntime.jsx("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",justifyContent:"flex-end",opacity:te?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:te?"auto":"none"},role:"region","aria-label":"Video player controls",children:[jsxRuntime.jsx(Z.ProgressBar,{videoRef:r,playerRef:a,enablePreview:v,thumbnailVtt:m,thumbnailVttBaseUrl:M,isAudioMode:S}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,marginTop:4},children:[L?jsxRuntime.jsx(Z.PauseButton,{onClick:ae}):jsxRuntime.jsx(Z.PlayButton,{onClick:ne}),jsxRuntime.jsx(Z.VolumeControl,{volume:T,isMuted:c,onVolumeChange:ie,onToggleMute:se}),jsxRuntime.jsx(Z.TimeDisplay,{videoRef:r,isLive:k,isAudioMode:S}),jsxRuntime.jsx("div",{style:{flex:1}}),k&&jsxRuntime.jsx(st,{onClick:t}),D&&jsxRuntime.jsx(it,{onClick:s,isAudioMode:S,audioModeIcon:N,videoModeIcon:x,audioModeLabel:C,videoModeLabel:F}),jsxRuntime.jsx(Z.SettingsMenu,{currentRate:R,playbackRates:f,onRateChange:ue,qualityLevels:q,currentQualityLevel:I,onQualityChange:le}),Y?.map(n=>jsxRuntime.jsx("button",{className:"controlButton","aria-label":n.label,title:n.title??n.label,onClick:n.onClick,children:n.icon},n.key)),jsxRuntime.jsx(Z.PiPButton,{onClick:me,isPiP:w}),jsxRuntime.jsx(Z.TheaterButton,{onClick:e,isTheater:E}),jsxRuntime.jsx(Z.FullscreenButton,{onClick:d,isFullscreen:h})]})]})})});He.displayName="Controls";var it=ut.memo(({onClick:o,isAudioMode:r,audioModeIcon:a,videoModeIcon:l,audioModeLabel:f,videoModeLabel:v})=>{let m=r?v??"Video":f??"Audio";return jsxRuntime.jsxs("button",{onClick:o,className:"rvp-audio-toggle-btn","aria-label":m,title:m,"aria-pressed":r,children:[r?l??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"})}):a??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"})}),m]})});it.displayName="AudioModeButton";var st=ut.memo(({onClick:o})=>jsxRuntime.jsx("button",{onClick:o,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"}));st.displayName="GoLiveButton";var $e=ut.memo(({x:o,y:r,isPlaying:a,src:l,videoRef:f,playerRef:v,onClose:m,contextMenuItems:M})=>{let L=ut.useRef(null),[T,c]=ut.useState(()=>f.current?.loop??false),R=Math.min(o,window.innerWidth-220),h=Math.min(r,window.innerHeight-290);ut.useEffect(()=>{let x=k=>{L.current&&!L.current.contains(k.target)&&m();},C=k=>{k.key==="Escape"&&m();},F=()=>m();return document.addEventListener("mousedown",x),document.addEventListener("keydown",C),window.addEventListener("scroll",F,true),()=>{document.removeEventListener("mousedown",x),document.removeEventListener("keydown",C),window.removeEventListener("scroll",F,true);}},[m]);let w=ut.useCallback(()=>{a?v.pause():v.play(),m();},[a,v,m]),E=ut.useCallback(()=>{let x=f.current;if(!x)return;let C=!T;x.loop=C,c(C);},[f,T]),S=ut.useCallback(async()=>{try{await navigator.clipboard.writeText(l);}catch{}m();},[l,m]),D=ut.useCallback(async()=>{let x=Math.floor(f.current?.currentTime??0);try{await navigator.clipboard.writeText(`${l}?t=${x}`);}catch{}m();},[l,f,m]),N=ut.useCallback(()=>{v.togglePictureInPicture(),m();},[v,m]);return jsxRuntime.jsxs("div",{ref:L,className:"contextMenu",style:{left:R,top:h},children:[jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:w,children:a?"Pause":"Play"}),jsxRuntime.jsxs("button",{className:"contextMenuItem",onClick:E,children:[jsxRuntime.jsx("span",{children:"Loop"}),T&&jsxRuntime.jsx("span",{className:"contextMenuCheck",children:"\u2713"})]}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:S,children:"Copy video URL"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:D,children:"Copy video URL at current time"}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:N,children:"Picture-in-Picture"}),M&&M.length>0&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{className:"contextMenuDivider"}),M.map((x,C)=>jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:()=>{x.onClick(),m();},children:x.label},C))]})]})});$e.displayName="ContextMenu";var We=ut.memo(function({poster:r,logo:a,audioModeFallback:l,isBuffering:f=false,onOverlayClick:v}){return jsxRuntime.jsxs("div",{className:"rvp-audio-overlay",onClick:v,"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})}):l?jsxRuntime.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center"},children:l}):a?typeof a=="string"?jsxRuntime.jsx("img",{src:a,alt:"Logo",className:"rvp-audio-logo",draggable:false}):jsxRuntime.jsx("div",{className:"rvp-audio-logo-node",children:a}):null,jsxRuntime.jsx("span",{className:"rvp-audio-label",children:"Audio Mode"}),f?jsxRuntime.jsx("div",{className:"rvp-audio-buffering-overlay","aria-label":"Buffering",children:jsxRuntime.jsx("div",{className:"rvp-audio-spinner"})}):null]})});We.displayName="AudioModeOverlay";var ct=ut.forwardRef((o,r)=>{let{src:a,poster:l,className:f,controls:v=true,options:m={}}=o,{autoplay:M=false,muted:L=false,loop:T=false,preload:c="metadata",playbackRates:R=[.25,.5,.75,1,1.25,1.5,1.75,2],enableHLS:h=true,enablePreview:w=true,thumbnailVtt:E,thumbnailVttBaseUrl:S,hlsConfig:D,autoHideControls:N=true,subtitles:x,crossOrigin:C,logo:F,audioModeFallback:k,audioPoster:q,audioSrc:I,showAudioButton:Y,audioModeIcon:K,videoModeIcon:H,audioModeLabel:te,videoModeLabel:Q,defaultAudioMode:V,audioBandwidthThreshold:ne,audioModeSwitchLevel:ae,audioModeRecoveryInterval:ie,onPlay:se,onPause:ue,onEnded:le,onError:me,onTimeUpdate:e,onDurationChange:s,onBuffering:d,onTheaterModeChange:t,onAudioModeChange:n,contextMenuItems:i,controlBarItems:b}=m,g=ut.useRef(null),p=ut.useRef(null),P=ut.useRef(null),{state:u,ref:B,fullscreenContainerRef:_}=qe(g,a,{autoplay:M,muted:L,loop:T,playbackRates:R,enableHLS:h,hlsConfig:D,defaultAudioMode:V,audioBandwidthThreshold:ne,audioModeSwitchLevel:ae,audioModeRecoveryInterval:ie,onPlay:se,onPause:ue,onEnded:le,onError:me,onTimeUpdate:e,onDurationChange:s,onBuffering:d,onTheaterModeChange:t,onAudioModeChange:n,audioRef:p,audioSrc:I}),J=ut.useRef(null);ut__default.default.useLayoutEffect(()=>{J.current=u.isAudioMode&&I&&p.current?p.current:g.current;},[u.isAudioMode,I]),J.current===null&&(J.current=g.current);let[y,X]=ut.useState(null);ut.useEffect(()=>{_.current=P.current;},[_]),ut__default.default.useImperativeHandle(r,()=>B,[B]);let fe=ut.useCallback(()=>{P.current?.focus(),u.isPlaying?B.pause():B.play();},[u.isPlaying,B]),Ie=ut.useCallback(()=>{B.toggleFullscreen();},[B]),dt=ut.useCallback(oe=>{oe.preventDefault(),X({x:oe.clientX,y:oe.clientY});},[]);return jsxRuntime.jsxs("div",{ref:P,tabIndex:0,style:{position:"relative",width:"100%",backgroundColor:"#000",aspectRatio:"16 / 9",userSelect:"none",outline:"none"},className:f,"data-test":"video-player-container","data-theater":u.isTheaterMode?"true":void 0,onContextMenu:dt,children:[jsxRuntime.jsx("video",{ref:g,poster:l,preload:c,crossOrigin:C,onClick:fe,onDoubleClick:Ie,playsInline:true,style:{width:"100%",height:"100%",display:"block",cursor:"pointer",visibility:u.isAudioMode?"hidden":"visible"},"data-test":"video-element",children:x?.map(oe=>jsxRuntime.jsx("track",{kind:"subtitles",src:oe.src,label:oe.label,srcLang:oe.srclang,default:oe.default},oe.id))}),I&&jsxRuntime.jsx("audio",{ref:p,preload:"none",style:{display:"none"},"aria-hidden":"true"}),u.isAudioMode&&jsxRuntime.jsx(We,{poster:q??l,logo:F,audioModeFallback:k,isBuffering:u.isBuffering,onOverlayClick:fe}),v&&jsxRuntime.jsx(He,{videoRef:J,playerRef:B,playerContainerRef:P,playbackRates:R,enablePreview:w,thumbnailVtt:u.isAudioMode?void 0:E,thumbnailVttBaseUrl:S,isPlaying:u.isPlaying,volume:u.volume,isMuted:u.isMuted,playbackRate:u.playbackRate,isFullscreen:u.isFullscreen,isPictureInPicture:u.isPictureInPicture,isTheaterMode:u.isTheaterMode,isAudioMode:u.isAudioMode,showAudioButton:Y??!!I,audioModeIcon:K,videoModeIcon:H,audioModeLabel:te,videoModeLabel:Q,isLive:u.isLive,qualityLevels:u.qualityLevels,currentQualityLevel:u.currentQualityLevel,controlBarItems:b,autoHideControls:N}),y&&jsxRuntime.jsx($e,{x:y.x,y:y.y,isPlaying:u.isPlaying,src:a,videoRef:g,playerRef:B,onClose:()=>X(null),contextMenuItems:i}),u.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"}),u.isBuffering&&!u.error&&!u.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"}})}),u.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:u.error.code==="MEDIA_ERR_SRC_NOT_SUPPORTED"?"Unsupported Format":u.error.code.startsWith("HLS")?"Stream Error":"Playback Error"}),jsxRuntime.jsx("p",{style:{margin:0,fontSize:13,opacity:.75},children:u.error.message})]})})]})});ct.displayName="VideoPlayer";var $t=ct;var Wt={EXTREME:100,POOR:300,FAIR:800,GOOD:1500},Kt={LOWEST:0,SECOND_LOWEST:1,DISABLED:-1};exports.AUDIO_BANDWIDTH_THRESHOLDS=Wt;exports.AUDIO_SWITCH_LEVELS=Kt;exports.ControlElements=nt;exports.Controls=He;exports.VideoPlayer=$t;exports.findThumbnailCue=Fe;exports.formatTime=ve;exports.getMimeType=vt;exports.isHLSUrl=ye;exports.parseThumbnailVtt=Oe;//# sourceMappingURL=index.js.map
|
|
3
|
+
`),p=0;for(;p<c.length;){let v=c[p].trim();if(v.includes("-->")){let P=v.indexOf("-->"),T=ut(v.slice(0,P)),k=ut(v.slice(P+3));for(p++;p<c.length&&!c[p].trim();)p++;if(p<c.length){let u=c[p].trim(),R=u.lastIndexOf("#xywh="),g=u,A=0,N=0,H=160,V=90;if(R!==-1){g=u.slice(0,R);let S=u.slice(R+6).split(",").map(Number);A=S[0]??0,N=S[1]??0,H=S[2]??160,V=S[3]??90;}l.push({start:T,end:k,url:_t(n,g,o),x:A,y:N,w:H,h:V});}}p++;}return l}function Xe(r,n){if(!r.length)return null;let o=0,l=r.length-1;for(;o<=l;){let c=o+l>>1;if(r[c].end<=n)o=c+1;else if(r[c].start>n)l=c-1;else return r[c]}return null}var dt=Tt.memo(({videoRef:r,playerRef:n,enablePreview:o=true,thumbnailVtt:l,thumbnailVttBaseUrl:c,isAudioMode:p=false})=>{let v=Tt.useRef(null),P=Tt.useRef(null),T=Tt.useRef(null),k=Tt.useRef(null),u=Tt.useRef(null),R=Tt.useRef(null),g=Tt.useRef(null),A=Tt.useRef(null),N=Tt.useRef(null),[H,V]=Tt.useState([]),S=Tt.useRef(false),B=Tt.useRef(0),w=Tt.useRef(0),F=Tt.useRef(null),C=Tt.useRef([]),W=Tt.useRef(null);Tt.useEffect(()=>{let t=()=>{W.current=null;};return window.addEventListener("resize",t,{passive:true}),()=>window.removeEventListener("resize",t)},[]);let h=Tt.useCallback(()=>(!W.current&&v.current&&(W.current=v.current.getBoundingClientRect()),W.current),[]);Tt.useEffect(()=>{if(!l){C.current=[];return}let t=false;return fetch(l).then(a=>a.text()).then(a=>{t||(C.current=Ke(a,l,c));}).catch(()=>{t||(C.current=[]);}),()=>{t=true;}},[l]),Tt.useEffect(()=>{let t=r.current;if(!t)return;let a=()=>{let f=isFinite(t.duration)?t.duration:0,E=t.currentTime,y=f>0?E/f*100:0;P.current&&(P.current.style.width=`${y}%`),T.current&&(T.current.style.left=`${y}%`),A.current&&(A.current.style.clipPath=`inset(0 ${(100-y).toFixed(2)}% 0 0)`),v.current&&(v.current.setAttribute("aria-valuenow",String(Math.round(E))),v.current.setAttribute("aria-valuemax",String(Math.round(f))),v.current.setAttribute("aria-valuetext",ge(E)));};return t.addEventListener("timeupdate",a),t.addEventListener("durationchange",a),t.addEventListener("seeked",a),a(),()=>{t.removeEventListener("timeupdate",a),t.removeEventListener("durationchange",a),t.removeEventListener("seeked",a);}},[r,p]),Tt.useEffect(()=>{let t=r.current;if(!t)return;let a=()=>{let f=[];for(let E=0;E<t.buffered.length;E++)f.push({start:t.buffered.start(E),end:t.buffered.end(E)});if(p||V(f),N.current&&isFinite(t.duration)&&t.duration>0){let y=f.reduce((i,m)=>Math.max(i,m.end),0)/t.duration*100;N.current.style.clipPath=`inset(0 ${(100-y).toFixed(2)}% 0 0)`;}};return t.addEventListener("progress",a),()=>t.removeEventListener("progress",a)},[r,p]);let D=Tt.useCallback(()=>{S.current=true,T.current?.classList.add("dragging");},[]),J=Tt.useCallback(()=>{S.current=false,T.current?.classList.remove("dragging");},[]),me=Tt.useCallback(()=>{!o||p||(W.current=null,k.current&&(k.current.style.display="block"),R.current&&(R.current.style.display="block"));},[o,p]),se=Tt.useCallback(()=>{k.current&&(k.current.style.display="none"),R.current&&(R.current.style.display="none");},[]),le=Tt.useCallback(t=>{if(!g.current||!C.current.length)return;let a=Xe(C.current,t);if(F.current=a,!a)return;let f=g.current;f.style.backgroundImage=`url(${a.url})`,f.style.backgroundPosition=`-${a.x}px -${a.y}px`,f.style.width=`${a.w}px`,f.style.height=`${a.h}px`;},[]),_=Tt.useCallback(t=>{let a=h(),f=r.current?.duration;return !a||a.width===0||!f||!isFinite(f)?0:Math.max(0,Math.min(t-a.left,a.width))/a.width*f},[h,r]),I=Tt.useCallback(t=>{let a=h();return a?Math.max(0,Math.min(t-a.left,a.width)):0},[h]),ue=Tt.useCallback(t=>{let a=r.current;if(!a)return;let f=a.currentTime,E=isFinite(a.duration)?a.duration:0;switch(t.key){case "ArrowLeft":case "ArrowRight":{t.preventDefault(),t.nativeEvent.stopImmediatePropagation();let y=t.shiftKey?10:5;n.seek(t.key==="ArrowLeft"?Math.max(0,f-y):Math.min(E,f+y));break}case "Home":t.preventDefault(),t.nativeEvent.stopImmediatePropagation(),n.seek(0);break;case "End":E>0&&(t.preventDefault(),t.nativeEvent.stopImmediatePropagation(),n.seek(E));break}},[r,n]),Z=Tt.useCallback(t=>{let a=_(t.clientX),f=I(t.clientX);if(B.current=f,w.current=a,R.current&&(R.current.style.left=`${f}px`),u.current&&(u.current.textContent=ge(a)),le(a),k.current){let E=k.current.offsetWidth,y=h()?.width??0,i=E/2,m=Math.max(i,Math.min(f,y-i));k.current.style.left=`${m}px`;}S.current&&n.seek(a);},[n,le,_,I,h]),ce=Tt.useCallback(()=>{se(),J();},[se,J]),fe=Tt.useCallback(t=>{t.preventDefault(),D(),n.seek(_(t.clientX));},[D,_,n]),ve=Tt.useCallback(t=>{S.current||n.seek(_(t.clientX));},[_,n]);Tt.useEffect(()=>{let t=v.current;if(!t)return;let a=f=>{S.current&&f.preventDefault();};return t.addEventListener("touchmove",a,{passive:false}),()=>t.removeEventListener("touchmove",a)},[]);let he=Tt.useCallback(t=>{W.current=null,D(),n.seek(_(t.touches[0].clientX));},[D,_,n]),e=Tt.useCallback(t=>{S.current&&n.seek(_(t.touches[0].clientX));},[_,n]);Tt.useEffect(()=>{let t=()=>J();return window.addEventListener("mouseup",t),()=>window.removeEventListener("mouseup",t)},[J]);let s=Tt.useMemo(()=>{let a=[],f=3735928559,E=()=>(f^=f<<13,f^=f>>17,f^=f<<5,(f>>>0)/4294967295);for(let y=0;y<200;y++){let i=y/200*Math.PI*5,m=.15+.55*Math.abs(Math.sin(i))+.3*E();a.push(Math.max(.1,Math.min(1,m)));}return a},[]),d=Tt.useMemo(()=>{let t=r.current,a=t&&isFinite(t.duration)?t.duration:0;return a<=0||!H.length?null:H.map((f,E)=>{let y=f.start/a*100,i=(f.end-f.start)/a*100;return jsxRuntime.jsx("div",{className:"bufferedSegment",style:{left:`${y}%`,width:`${i}%`}},E)})},[H,r]);return jsxRuntime.jsxs("div",{ref:v,className:"progressContainer",onMouseMove:Z,onMouseEnter:me,onMouseLeave:ce,onMouseDown:fe,onMouseUp:J,onClick:ve,onTouchStart:he,onTouchMove:e,onTouchEnd:J,onKeyDown:ue,role:"slider","aria-label":p?"Audio progress":"Video progress","aria-valuemin":0,"aria-valuemax":0,"aria-valuenow":0,"aria-valuetext":"0:00",tabIndex:0,children:[o&&jsxRuntime.jsxs("div",{ref:k,className:"previewTooltip",style:{left:0,display:"none"},"aria-hidden":"true",children:[l&&jsxRuntime.jsx("div",{ref:g,className:"previewThumbnail"}),jsxRuntime.jsx("div",{ref:u,className:"previewTime"})]}),p?jsxRuntime.jsxs("div",{className:"rvp-waveform","aria-hidden":"true",children:[jsxRuntime.jsx("div",{className:"rvp-waveform-base",children:s.map((t,a)=>jsxRuntime.jsx("div",{className:"rvp-waveform-dot"},a))}),jsxRuntime.jsx("div",{ref:N,className:"rvp-waveform-buffered",style:{clipPath:"inset(0 100% 0 0)"},children:s.map((t,a)=>jsxRuntime.jsx("div",{className:"rvp-waveform-buffered-bar",style:{height:`${Math.round(t*100)}%`}},a))}),jsxRuntime.jsx("div",{ref:A,className:"rvp-waveform-filled",children:s.map((t,a)=>jsxRuntime.jsx("div",{className:"rvp-waveform-bar",style:{height:`${Math.round(t*100)}%`}},a))})]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"progressBackground",children:[d,jsxRuntime.jsx("div",{ref:P,className:"progressFilled",style:{width:"0%"}}),o&&jsxRuntime.jsx("div",{ref:R,className:"hoverIndicator",style:{left:0,display:"none"},"aria-hidden":"true"})]}),jsxRuntime.jsx("div",{ref:T,className:"scrubHandle",style:{left:"0%"},"aria-hidden":"true"})]})]})});dt.displayName="ProgressBar";var Ve=dt;var Kt=()=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M20.38 8.57l-1.23 1.85a8 8 0 0 1-.22 7.58H5.07A8 8 0 0 1 15.58 6.85l1.85-1.23A10 10 0 0 0 3.35 19a2 2 0 0 0 1.72 1h13.85a2 2 0 0 0 1.74-1 10 10 0 0 0-.27-10.44zm-9.79 6.84a2 2 0 0 0 2.83 0l5.66-8.49-8.49 5.66a2 2 0 0 0 0 2.83z"})}),Xt=()=>jsxRuntime.jsx("svg",{width:"16",height:"16",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M3 17v2h6v-2H3zM3 5v2h10V5H3zm10 16v-2h8v-2h-8v-2h-2v6h2zM7 9v2H3v2h4v2h2V9H7zm14 4v-2H11v2h10zm-6-4h2V7h4V5h-4V3h-2v6z"})}),ft=()=>jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"})}),vt=()=>jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"})}),Ie=()=>jsxRuntime.jsx("svg",{width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor",children:jsxRuntime.jsx("path",{d:"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"})}),ht=Tt.memo(({currentRate:r,playbackRates:n,onRateChange:o,qualityLevels:l=[],currentQualityLevel:c=-1,onQualityChange:p,showQualityMenu:v=false,manualQualityLevels:P,activeManualSrc:T,onManualQualityChange:k,isAudioMode:u=false})=>{let[R,g]=Tt.useState(false),[A,N]=Tt.useState(null),H=Tt.useRef(null),V=l.length>0&&!!p,S=!!P?.length&&!!k,B=!u&&(V||S||v);Tt.useEffect(()=>{R||N(null);},[R]),Tt.useEffect(()=>{u&&N(h=>h==="quality"?null:h);},[u]),Tt.useEffect(()=>{let h=D=>{H.current&&!H.current.contains(D.target)&&g(false);};return R&&document.addEventListener("mousedown",h),()=>document.removeEventListener("mousedown",h)},[R]);let w=Tt.useMemo(()=>[...l].sort((h,D)=>D.bitrate-h.bitrate),[l]),F=r===1?"Normal":`${r}\xD7`,C=Tt.useMemo(()=>S&&T?P.find(h=>h.src===T)?.label??"Auto":V?c===-1?"Auto":l.find(h=>h.id===c)?.name??"Auto":"Auto",[S,V,T,P,l,c]),W=Tt.useMemo(()=>c===-1?null:l.find(h=>h.id===c)?.name??null,[l,c]);return jsxRuntime.jsxs("div",{ref:H,className:"settingsContainer",children:[jsxRuntime.jsx("button",{onClick:()=>g(h=>!h),className:"controlButton","aria-label":"Settings",title:"Settings","aria-expanded":R,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"})})}),R&&jsxRuntime.jsxs("div",{className:"settingsDropdown",role:"menu",children:[A===null&&jsxRuntime.jsxs("div",{className:"settingsMainPanel",children:[jsxRuntime.jsxs("button",{className:"settingsRow",onClick:()=>N("speed"),children:[jsxRuntime.jsx("span",{className:"settingsRowIcon",children:jsxRuntime.jsx(Kt,{})}),jsxRuntime.jsx("span",{className:"settingsRowLabel",children:"Playback speed"}),jsxRuntime.jsx("span",{className:"settingsRowValue",children:F}),jsxRuntime.jsx("span",{className:"settingsRowChevron",children:jsxRuntime.jsx(ft,{})})]}),B&&jsxRuntime.jsxs("button",{className:"settingsRow",onClick:()=>N("quality"),children:[jsxRuntime.jsx("span",{className:"settingsRowIcon",children:jsxRuntime.jsx(Xt,{})}),jsxRuntime.jsx("span",{className:"settingsRowLabel",children:"Quality"}),jsxRuntime.jsx("span",{className:"settingsRowValue",children:C}),jsxRuntime.jsx("span",{className:"settingsRowChevron",children:jsxRuntime.jsx(ft,{})})]})]}),A==="speed"&&jsxRuntime.jsxs("div",{className:"settingsSubPanel",children:[jsxRuntime.jsxs("button",{className:"settingsBackRow",onClick:()=>N(null),children:[jsxRuntime.jsx(vt,{}),jsxRuntime.jsx("span",{children:"Playback speed"})]}),jsxRuntime.jsx("div",{className:"settingsDivider"}),n.map(h=>{let D=r===h;return jsxRuntime.jsxs("button",{onClick:()=>{o(h),N(null);},className:`settingsOption${D?" active":""}`,role:"menuitemradio","aria-checked":D,children:[jsxRuntime.jsx("span",{className:"settingsOptionCheck",children:D&&jsxRuntime.jsx(Ie,{})}),h===1?"Normal":`${h}\xD7`]},h)})]}),A==="quality"&&jsxRuntime.jsxs("div",{className:"settingsSubPanel",children:[jsxRuntime.jsxs("button",{className:"settingsBackRow",onClick:()=>N(null),children:[jsxRuntime.jsx(vt,{}),jsxRuntime.jsx("span",{children:"Quality"})]}),jsxRuntime.jsx("div",{className:"settingsDivider"}),S&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[P.map(h=>{let D=T===h.src;return jsxRuntime.jsxs("button",{onClick:()=>{k(h.src),N(null);},className:`settingsOption${D?" active":""}`,role:"menuitemradio","aria-checked":D,children:[jsxRuntime.jsx("span",{className:"settingsOptionCheck",children:D&&jsxRuntime.jsx(Ie,{})}),h.label]},h.src)}),V&&jsxRuntime.jsx("div",{className:"settingsDivider"})]}),V&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("button",{onClick:()=>{p(-1),N(null);},className:`settingsOption${c===-1?" active":""}`,role:"menuitemradio","aria-checked":c===-1,children:[jsxRuntime.jsx("span",{className:"settingsOptionCheck",children:c===-1&&jsxRuntime.jsx(Ie,{})}),jsxRuntime.jsxs("span",{children:["Auto",W&&jsxRuntime.jsxs("span",{className:"settingsOptionBadge",children:[" (",W,")"]})]})]}),w.map(h=>{let D=c===h.id;return jsxRuntime.jsxs("button",{onClick:()=>{p(h.id),N(null);},className:`settingsOption${D?" active":""}`,role:"menuitemradio","aria-checked":D,children:[jsxRuntime.jsx("span",{className:"settingsOptionCheck",children:D&&jsxRuntime.jsx(Ie,{})}),jsxRuntime.jsx("span",{style:{flex:1},children:h.name}),h.bitrate>0&&jsxRuntime.jsxs("span",{className:"settingsOptionBadge",children:[Math.round(h.bitrate/1e3)," kbps"]})]},h.id)})]})]})]})]})});ht.displayName="SettingsMenu";var Oe=ht;var bt=Tt.memo(({videoRef:r,isLive:n=false,isAudioMode:o=false})=>{let l=Tt.useRef(null),c=Tt.useRef(null);return Tt.useEffect(()=>{let p=r.current;if(!p)return;let v=()=>{l.current&&(l.current.textContent=ge(p.currentTime));},P=()=>{if(c.current){let T=isFinite(p.duration)?p.duration:0;c.current.textContent=` / ${ge(T)}`;}};return p.addEventListener("timeupdate",v),p.addEventListener("durationchange",P),p.addEventListener("seeked",v),v(),P(),()=>{p.removeEventListener("timeupdate",v),p.removeEventListener("durationchange",P),p.removeEventListener("seeked",v);}},[r,n,o]),n?jsxRuntime.jsx("span",{className:"timeDisplay",style:{opacity:.7},children:jsxRuntime.jsx("span",{ref:l,children:"0:00"})}):jsxRuntime.jsxs("span",{className:"timeDisplay",children:[jsxRuntime.jsx("span",{ref:l,children:"0:00"}),jsxRuntime.jsx("span",{ref:c,style:{opacity:.6},children:" / 0:00"})]})});bt.displayName="TimeDisplay";var _e=bt;var re={PlayButton:Ce,PauseButton:Re,FullscreenButton:we,PiPButton:ke,TheaterButton:xe,VolumeControl:He,ProgressBar:Ve,SettingsMenu:Oe,TimeDisplay:_e};var ze=Tt.memo(function({videoRef:n,playerRef:o,playerContainerRef:l,playbackRates:c,enablePreview:p,thumbnailVtt:v,thumbnailVttBaseUrl:P,isPlaying:T,volume:k,isMuted:u,playbackRate:R,isFullscreen:g,isPictureInPicture:A,isTheaterMode:N,isAudioMode:H,showAudioButton:V,audioModeIcon:S,videoModeIcon:B,audioModeLabel:w,videoModeLabel:F,isLive:C,qualityLevels:W,currentQualityLevel:h,showQualityMenu:D,manualQualityLevels:J,activeManualSrc:me,onManualQualityChange:se,controlBarItems:le,autoHideControls:_}){let I=Tt.useRef(null),[ue,Z]=Tt.useState(true),ce=Tt.useRef({isPlaying:T,volume:k,isMuted:u,isLive:C});ce.current={isPlaying:T,volume:k,isMuted:u,isLive:C},Tt.useEffect(()=>{if(H||!_){Z(true),I.current&&clearTimeout(I.current);return}if(!T){Z(true),I.current&&clearTimeout(I.current);return}let i=l.current;if(!i)return;let m=()=>{Z(true),I.current&&clearTimeout(I.current),I.current=setTimeout(()=>Z(false),3e3);},b=()=>{I.current&&clearTimeout(I.current),Z(false);};return i.addEventListener("mousemove",m),i.addEventListener("mouseenter",m),i.addEventListener("mouseleave",b),i.addEventListener("touchstart",m,{passive:true}),Z(false),()=>{i.removeEventListener("mousemove",m),i.removeEventListener("mouseenter",m),i.removeEventListener("mouseleave",b),i.removeEventListener("touchstart",m),I.current&&clearTimeout(I.current);}},[T,H,_,l]),Tt.useEffect(()=>{let i=m=>{if(!l.current?.contains(document.activeElement))return;let b=m.target;if(b.tagName==="INPUT"||b.tagName==="TEXTAREA"||b.isContentEditable)return;let{isPlaying:z,volume:K,isLive:ne}=ce.current,M=n.current?.currentTime??0,X=n.current?.duration??0;switch(m.code){case "Space":case "KeyK":m.preventDefault(),z?o.pause():o.play();break;case "ArrowLeft":m.preventDefault(),o.seek(Math.max(0,M-5));break;case "ArrowRight":m.preventDefault(),o.seek(Math.min(X||1/0,M+5));break;case "ArrowUp":m.preventDefault(),o.setVolume(Math.min(1,K+.1));break;case "ArrowDown":m.preventDefault(),o.setVolume(Math.max(0,K-.1));break;case "KeyM":m.preventDefault(),o.toggleMute();break;case "KeyF":m.preventDefault(),o.toggleFullscreen();break;case "KeyP":m.preventDefault(),o.togglePictureInPicture();break;case "KeyT":m.preventDefault(),o.toggleTheaterMode();break;case "KeyL":m.preventDefault(),ne&&o.seekToLive();break;case "Digit0":case "Digit1":case "Digit2":case "Digit3":case "Digit4":case "Digit5":case "Digit6":case "Digit7":case "Digit8":case "Digit9":{m.preventDefault();let ae=Number(m.code.replace("Digit",""))*10;o.seek(X/100*ae);break}}};return window.addEventListener("keydown",i),()=>window.removeEventListener("keydown",i)},[o,l,n]);let fe=Tt.useCallback(()=>o.play(),[o]),ve=Tt.useCallback(()=>o.pause(),[o]),he=Tt.useCallback(i=>o.setVolume(i),[o]),e=Tt.useCallback(()=>o.toggleMute(),[o]),s=Tt.useCallback(i=>o.setPlaybackRate(i),[o]),d=Tt.useCallback(i=>o.setQualityLevel(i),[o]),t=Tt.useCallback(()=>o.togglePictureInPicture(),[o]),a=Tt.useCallback(()=>o.toggleTheaterMode(),[o]),f=Tt.useCallback(()=>o.toggleAudioMode(),[o]),E=Tt.useCallback(()=>o.toggleFullscreen(),[o]),y=Tt.useCallback(()=>o.seekToLive(),[o]);return jsxRuntime.jsx("div",{style:{position:"absolute",inset:0,display:"flex",flexDirection:"column",justifyContent:"flex-end",opacity:ue?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:ue?"auto":"none"},role:"region","aria-label":"Video player controls",children:[jsxRuntime.jsx(re.ProgressBar,{videoRef:n,playerRef:o,enablePreview:p,thumbnailVtt:v,thumbnailVttBaseUrl:P,isAudioMode:H}),jsxRuntime.jsxs("div",{style:{display:"flex",alignItems:"center",gap:4,marginTop:4},children:[T?jsxRuntime.jsx(re.PauseButton,{onClick:ve}):jsxRuntime.jsx(re.PlayButton,{onClick:fe}),jsxRuntime.jsx(re.VolumeControl,{volume:k,isMuted:u,onVolumeChange:he,onToggleMute:e}),jsxRuntime.jsx(re.TimeDisplay,{videoRef:n,isLive:C,isAudioMode:H}),jsxRuntime.jsx("div",{style:{flex:1}}),C&&jsxRuntime.jsx(Pt,{onClick:y}),V&&jsxRuntime.jsx(Et,{onClick:f,isAudioMode:H,audioModeIcon:S,videoModeIcon:B,audioModeLabel:w,videoModeLabel:F}),jsxRuntime.jsx(re.SettingsMenu,{currentRate:R,playbackRates:c,onRateChange:s,qualityLevels:W,currentQualityLevel:h,onQualityChange:d,showQualityMenu:D,manualQualityLevels:J,activeManualSrc:me,onManualQualityChange:se,isAudioMode:H}),le?.map(i=>jsxRuntime.jsx("button",{className:"controlButton","aria-label":i.label,title:i.title??i.label,onClick:i.onClick,children:i.icon},i.key)),jsxRuntime.jsx(re.PiPButton,{onClick:t,isPiP:A}),jsxRuntime.jsx(re.TheaterButton,{onClick:a,isTheater:N}),jsxRuntime.jsx(re.FullscreenButton,{onClick:E,isFullscreen:g})]})]})})});ze.displayName="Controls";var Et=Tt.memo(({onClick:r,isAudioMode:n,audioModeIcon:o,videoModeIcon:l,audioModeLabel:c,videoModeLabel:p})=>{let v=n?p??"Video":c??"Audio";return jsxRuntime.jsxs("button",{onClick:r,className:"rvp-audio-toggle-btn","aria-label":v,title:v,"aria-pressed":n,children:[n?l??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"})}),v]})});Et.displayName="AudioModeButton";var Pt=Tt.memo(({onClick:r})=>jsxRuntime.jsx("button",{onClick:r,style:{background:"none",border:"1px solid rgba(255,255,255,0.6)",color:"#fff",borderRadius:3,padding:"2px 8px",fontSize:11,fontWeight:700,cursor:"pointer",letterSpacing:"0.06em"},title:"Go to live (L)",children:"GO LIVE"}));Pt.displayName="GoLiveButton";var Ze=Tt.memo(({x:r,y:n,isPlaying:o,src:l,videoRef:c,playerRef:p,onClose:v,contextMenuItems:P})=>{let T=Tt.useRef(null),[k,u]=Tt.useState(()=>c.current?.loop??false),R=Math.min(r,window.innerWidth-220),g=Math.min(n,window.innerHeight-290);Tt.useEffect(()=>{let B=C=>{T.current&&!T.current.contains(C.target)&&v();},w=C=>{C.key==="Escape"&&v();},F=()=>v();return document.addEventListener("mousedown",B),document.addEventListener("keydown",w),window.addEventListener("scroll",F,true),()=>{document.removeEventListener("mousedown",B),document.removeEventListener("keydown",w),window.removeEventListener("scroll",F,true);}},[v]);let A=Tt.useCallback(()=>{o?p.pause():p.play(),v();},[o,p,v]),N=Tt.useCallback(()=>{let B=c.current;if(!B)return;let w=!k;B.loop=w,u(w);},[c,k]),H=Tt.useCallback(async()=>{try{await navigator.clipboard.writeText(l);}catch{}v();},[l,v]),V=Tt.useCallback(async()=>{let B=Math.floor(c.current?.currentTime??0);try{await navigator.clipboard.writeText(`${l}?t=${B}`);}catch{}v();},[l,c,v]),S=Tt.useCallback(()=>{p.togglePictureInPicture(),v();},[p,v]);return jsxRuntime.jsxs("div",{ref:T,className:"contextMenu",style:{left:R,top:g},children:[jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:A,children:o?"Pause":"Play"}),jsxRuntime.jsxs("button",{className:"contextMenuItem",onClick:N,children:[jsxRuntime.jsx("span",{children:"Loop"}),k&&jsxRuntime.jsx("span",{className:"contextMenuCheck",children:"\u2713"})]}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:H,children:"Copy video URL"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:V,children:"Copy video URL at current time"}),jsxRuntime.jsx("div",{className:"contextMenuDivider"}),jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:S,children:"Picture-in-Picture"}),P&&P.length>0&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{className:"contextMenuDivider"}),P.map((B,w)=>jsxRuntime.jsx("button",{className:"contextMenuItem",onClick:()=>{B.onClick(),v();},children:B.label},w))]})]})});Ze.displayName="ContextMenu";var et=Tt.memo(function({poster:n,logo:o,audioModeFallback:l,isBuffering:c=false,onOverlayClick:p}){return jsxRuntime.jsxs("div",{className:"rvp-audio-overlay",onClick:p,"data-test":"audio-mode-overlay",children:[n?jsxRuntime.jsx("div",{className:"rvp-audio-artwork-container",children:jsxRuntime.jsx("img",{src:n,alt:"Artwork",className:"rvp-audio-artwork",draggable:false})}):l?jsxRuntime.jsx("div",{style:{display:"flex",alignItems:"center",justifyContent:"center"},children:l}):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"}),c?jsxRuntime.jsx("div",{className:"rvp-audio-buffering-overlay","aria-label":"Buffering",children:jsxRuntime.jsx("div",{className:"rvp-audio-spinner"})}):null]})});et.displayName="AudioModeOverlay";var Rt=Tt.forwardRef((r,n)=>{let{src:o,poster:l,className:c,controls:p=true,options:v={}}=r,{autoplay:P=false,muted:T=false,loop:k=false,preload:u="metadata",playbackRates:R=[.25,.5,.75,1,1.25,1.5,1.75,2],enableHLS:g=true,enablePreview:A=true,thumbnailVtt:N,thumbnailVttBaseUrl:H,hlsConfig:V,autoHideControls:S=true,subtitles:B,crossOrigin:w,logo:F,audioModeFallback:C,audioPoster:W,audioSrc:h,showAudioButton:D,audioModeIcon:J,videoModeIcon:me,audioModeLabel:se,videoModeLabel:le,defaultAudioMode:_,showQualityMenu:I,manualQualityLevels:ue,audioBandwidthThreshold:Z,audioModeSwitchLevel:ce,audioModeRecoveryInterval:fe,onPlay:ve,onPause:he,onEnded:e,onError:s,onTimeUpdate:d,onDurationChange:t,onBuffering:a,onTheaterModeChange:f,onAudioModeChange:E,contextMenuItems:y,controlBarItems:i}=v,m=Tt.useRef(null),b=Tt.useRef(null),z=Tt.useRef(null),[K,ne]=Tt.useState(void 0),[M,X]=Tt.useState(void 0),ae=Tt.useRef(null);Tt.useEffect(()=>{ne(void 0),X(void 0);},[o]),Tt.useEffect(()=>{let Q=m.current;if(!Q)return;let be=()=>{let We=ae.current;We&&(ae.current=null,Q.currentTime=We.time,We.playing&&Q.play().catch(()=>{}));};return Q.addEventListener("loadedmetadata",be),()=>Q.removeEventListener("loadedmetadata",be)},[m]);let Ue=Tt.useCallback(Q=>{let be=m.current;ae.current={time:be?.currentTime??0,playing:be?!be.paused:false},ne(Q),X(Q);},[m]),wt=K??o,{state:x,ref:de,fullscreenContainerRef:rt}=st(m,wt,{autoplay:P,muted:T,loop:k,playbackRates:R,enableHLS:g,hlsConfig:V,defaultAudioMode:_,audioBandwidthThreshold:Z,audioModeSwitchLevel:ce,audioModeRecoveryInterval:fe,onPlay:ve,onPause:he,onEnded:e,onError:s,onTimeUpdate:d,onDurationChange:t,onBuffering:a,onTheaterModeChange:f,onAudioModeChange:E,audioRef:b,audioSrc:h}),De=Tt.useRef(null);Tt__default.default.useLayoutEffect(()=>{De.current=x.isAudioMode&&h&&b.current?b.current:m.current;},[x.isAudioMode,h]),De.current===null&&(De.current=m.current);let[$e,ot]=Tt.useState(null);Tt.useEffect(()=>{rt.current=z.current;},[rt]),Tt__default.default.useImperativeHandle(n,()=>de,[de]);let at=Tt.useCallback(()=>{z.current?.focus(),x.isPlaying?de.pause():de.play();},[x.isPlaying,de]),kt=Tt.useCallback(()=>{de.toggleFullscreen();},[de]),xt=Tt.useCallback(Q=>{Q.preventDefault(),ot({x:Q.clientX,y:Q.clientY});},[]);return jsxRuntime.jsxs("div",{ref:z,tabIndex:0,style:{position:"relative",width:"100%",backgroundColor:"#000",aspectRatio:"16 / 9",userSelect:"none",outline:"none"},className:c,"data-test":"video-player-container","data-theater":x.isTheaterMode?"true":void 0,onContextMenu:xt,children:[jsxRuntime.jsx("video",{ref:m,poster:l,preload:u,crossOrigin:w,onClick:at,onDoubleClick:kt,playsInline:true,style:{width:"100%",height:"100%",display:"block",cursor:"pointer",visibility:x.isAudioMode?"hidden":"visible"},"data-test":"video-element",children:B?.map(Q=>jsxRuntime.jsx("track",{kind:"subtitles",src:Q.src,label:Q.label,srcLang:Q.srclang,default:Q.default},Q.id))}),h&&jsxRuntime.jsx("audio",{ref:b,preload:"none",style:{display:"none"},"aria-hidden":"true"}),x.isAudioMode&&jsxRuntime.jsx(et,{poster:W??(C?void 0:l),logo:F,audioModeFallback:C,isBuffering:x.isBuffering,onOverlayClick:at}),p&&jsxRuntime.jsx(ze,{videoRef:De,playerRef:de,playerContainerRef:z,playbackRates:R,enablePreview:A,thumbnailVtt:x.isAudioMode?void 0:N,thumbnailVttBaseUrl:H,isPlaying:x.isPlaying,volume:x.volume,isMuted:x.isMuted,playbackRate:x.playbackRate,isFullscreen:x.isFullscreen,isPictureInPicture:x.isPictureInPicture,isTheaterMode:x.isTheaterMode,isAudioMode:x.isAudioMode,showAudioButton:D??!!h,audioModeIcon:J,videoModeIcon:me,audioModeLabel:se,videoModeLabel:le,isLive:x.isLive,qualityLevels:x.qualityLevels,currentQualityLevel:x.currentQualityLevel,showQualityMenu:I,manualQualityLevels:ue,activeManualSrc:M,onManualQualityChange:Ue,controlBarItems:i,autoHideControls:S}),$e&&jsxRuntime.jsx(Ze,{x:$e.x,y:$e.y,isPlaying:x.isPlaying,src:o,videoRef:m,playerRef:de,onClose:()=>ot(null),contextMenuItems:y}),x.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"}),x.isBuffering&&!x.error&&!x.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"}})}),x.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:x.error.code==="MEDIA_ERR_SRC_NOT_SUPPORTED"?"Unsupported Format":x.error.code.startsWith("HLS")?"Stream Error":"Playback Error"}),jsxRuntime.jsx("p",{style:{margin:0,fontSize:13,opacity:.75},children:x.error.message})]})})]})});Rt.displayName="VideoPlayer";var sn=Rt;var ln={EXTREME:100,POOR:300,FAIR:800,GOOD:1500},un={LOWEST:0,SECOND_LOWEST:1,DISABLED:-1};exports.AUDIO_BANDWIDTH_THRESHOLDS=ln;exports.AUDIO_SWITCH_LEVELS=un;exports.ControlElements=yt;exports.Controls=ze;exports.VideoPlayer=sn;exports.findThumbnailCue=Xe;exports.formatTime=ge;exports.getMimeType=Nt;exports.isHLSUrl=Ee;exports.parseThumbnailVtt=Ke;//# sourceMappingURL=index.js.map
|
|
4
4
|
//# sourceMappingURL=index.js.map
|