@glitchlab/vue-video-player 1.3.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,11 +14,21 @@ A lightweight, HLS-capable Vue 3 video player with a polished overlay UI, device
14
14
  ## Why this player
15
15
 
16
16
  - **HLS streaming** via `hls.js` with automatic native fallback (Safari)
17
+ - **YouTube support** — pass a YouTube URL and it embeds automatically, no extra config
18
+ - **Custom control bar** (default) — play/seek/time/speed/quality/captions/volume/PiP/fullscreen, consistent across every browser and OS. Or use `"native"` controls, or none.
19
+ - **Thumbnail seek preview** — hover the seek bar to see a frame preview from a WebVTT storyboard sprite
20
+ - **Chapters** — named timeline segments with tick marks on the seek bar, from a WebVTT file or an inline array
21
+ - **Playlist** — play a list of videos in sequence with auto-advance and prev/next buttons
22
+ - **Quality selector** — `Auto` + per-resolution switching for multi-rendition HLS streams
23
+ - **Audio-track switcher** — pick between multiple audio tracks (e.g. languages) when the stream provides them
24
+ - **Captions** — `<track>` subtitles/captions with an in-bar menu
25
+ - **Event emits** — `play`, `pause`, `ended`, `time-update`, `seeked`, `volume-change`, `milestone`, `error`
26
+ - **Keyboard shortcuts** — space, arrows, `M`, `F`, `P`
17
27
  - **Nuxt 3 module** — `modules: ["@glitchlab/vue-video-player/nuxt"]` and you're done
18
28
  - **Scoped CSS, no preflight** — all styles live under `.gvp-root`. No `*` resets, no theme tokens leaked into your design system
19
29
  - **Device-mode toggle** — flip between desktop (16:9) and mobile (9:16) presets
20
30
  - **Hover-to-play** with safe play/pause race handling
21
- - Tiny: ~3 KB CSS gzipped, ~3.6 KB JS gzipped
31
+ - Lightweight: ~2 KB CSS + ~13 KB JS gzipped (hls.js is a peer dependency, loaded once)
22
32
  - Fully typed; SSR-safe
23
33
 
24
34
  ---
@@ -89,8 +99,13 @@ Then use the component anywhere — no manual import required:
89
99
 
90
100
  | Prop | Type | Default | Description |
91
101
  |---------------------|---------------------------------------------------|-----------------------------------------|------------------------------------------------------------------------------------------|
92
- | `src` | `string` | — | **Required.** Video URL. `.m3u8` is routed through HLS automatically. |
102
+ | `src` | `string` | — | Video URL. `.m3u8` is routed through HLS automatically. Optional when `playlist` is set. |
93
103
  | `poster` | `string` | — | Poster image shown before playback starts. |
104
+ | `playlist` | `PlaylistItem[]` | — | A list of videos to play in sequence. Auto-advances on end; prev/next buttons appear. Takes precedence over `src`. See [Playlist](#playlist). |
105
+ | `defaultIndex` | `number` | `0` | Index of the playlist item to start on. |
106
+ | `autoAdvance` | `boolean` | `true` | Auto-advance to the next playlist item when one ends. |
107
+ | `thumbnails` | `string` | — | URL of a WebVTT storyboard for seek-bar thumbnail previews. See [Thumbnails](#thumbnail-seek-preview). |
108
+ | `chapters` | `string \| Chapter[]` | — | WebVTT chapters URL, or an inline array of `{ start, title }`. See [Chapters](#chapters). |
94
109
  | `showDeviceToggle` | `boolean` | `true` | Show the desktop/mobile toggle pill in the top-left. |
95
110
  | `defaultDevice` | `"desktop" \| "mobile"` | `"desktop"` | Initial device mode. |
96
111
  | `hoverPlay` | `boolean` | `false` | Start playback on mouse-enter, pause on mouse-leave. |
@@ -108,11 +123,18 @@ Then use the component anywhere — no manual import required:
108
123
 
109
124
  ## Events
110
125
 
111
- | Event | Payload | Description |
112
- |---------|---------|----------------------------------------------------------------------|
113
- | `close` | — | Emitted when the close button is clicked. Requires `closable=true`. |
114
- | `play` | — | Emitted when playback starts. |
115
- | `pause` | — | Emitted when playback pauses. |
126
+ | Event | Payload | Description |
127
+ |-------------------|-------------------------------|----------------------------------------------------------------------|
128
+ | `close` | — | Emitted when the close button is clicked. Requires `closable=true`. |
129
+ | `play` | — | Emitted when playback starts or resumes. |
130
+ | `pause` | — | Emitted when playback pauses. |
131
+ | `ended` | — | Emitted when the current video reaches its end. |
132
+ | `time-update` | `(currentTime, duration)` | Emitted on every `timeupdate` (~4×/sec); times in seconds. |
133
+ | `seeked` | `(currentTime)` | Emitted after a seek completes, with the new time in seconds. |
134
+ | `volume-change` | `(volume, muted)` | Emitted when volume or mute state changes. |
135
+ | `milestone` | `(percent)` | Emitted once when watch progress crosses 25%, 50%, 75% and 100%. |
136
+ | `error` | — | Emitted when the underlying media element reports an error. |
137
+ | `playlist-change` | `(index, item)` | Emitted when the active playlist item changes. |
116
138
 
117
139
  ## Slots
118
140
 
@@ -146,6 +168,7 @@ The bar includes, left to right:
146
168
  - **Seek bar** with a buffered indicator (live scrub — the video previews as you drag)
147
169
  - **Time** — `current / duration`
148
170
  - **Playback speed** — `0.5×` to `2×` menu
171
+ - **Quality** — resolution selector (`Auto` + each height) — appears only for HLS streams with more than one quality level
149
172
  - **Captions** — appears only when the source has `<track>` subtitle/caption tracks
150
173
  - **Volume** — mute toggle + slider (slider expands on hover)
151
174
  - **Picture-in-Picture** — appears only where the browser supports it
@@ -187,6 +210,100 @@ Every part has a `.gvp-*` class hook — override what you need:
187
210
 
188
211
  ---
189
212
 
213
+ ## Thumbnail seek preview
214
+
215
+ Hover the seek bar to see a frame preview. Pass `thumbnails` a URL to a **WebVTT storyboard** file — the format YouTube and Vimeo use. Each cue maps a time range to a region of a sprite image:
216
+
217
+ ```
218
+ WEBVTT
219
+
220
+ 00:00:00.000 --> 00:00:05.000
221
+ storyboard.jpg#xywh=0,0,160,90
222
+
223
+ 00:00:05.000 --> 00:00:10.000
224
+ storyboard.jpg#xywh=160,0,160,90
225
+ ```
226
+
227
+ ```vue
228
+ <VueVideoPlayer src="/videos/movie.m3u8" thumbnails="/videos/storyboard.vtt" />
229
+ ```
230
+
231
+ The `#xywh=x,y,w,h` fragment crops a tile out of the sprite; relative image paths resolve against the VTT's own URL. A cue with no `#xywh` uses the whole image. You can generate a storyboard from a video with `ffmpeg`:
232
+
233
+ ```bash
234
+ ffmpeg -i video.mp4 -vf "fps=1/5,scale=160:90,tile=5x100" storyboard.jpg
235
+ ```
236
+
237
+ Only used with the custom control bar.
238
+
239
+ ---
240
+
241
+ ## Chapters
242
+
243
+ Segment the timeline into named chapters. They add tick marks to the seek bar and show the chapter title in the hover preview. Pass either a WebVTT chapters URL or an inline array:
244
+
245
+ ```vue
246
+ <!-- Inline -->
247
+ <VueVideoPlayer
248
+ src="/videos/tutorial.m3u8"
249
+ :chapters="[
250
+ { start: 0, title: 'Introduction' },
251
+ { start: 150, title: 'Getting started' },
252
+ { start: 600, title: 'Advanced topics' },
253
+ ]"
254
+ />
255
+
256
+ <!-- From a WebVTT chapters file -->
257
+ <VueVideoPlayer src="/videos/tutorial.m3u8" chapters="/videos/chapters.vtt" />
258
+ ```
259
+
260
+ Inline items may omit `end` — it's filled from the next chapter's `start` (or the video duration). Only used with the custom control bar.
261
+
262
+ ---
263
+
264
+ ## Playlist
265
+
266
+ Pass `playlist` an array of items to play videos in sequence. The player auto-advances when one ends and shows prev/next buttons in the control bar. Each item can carry its own `poster`, `thumbnails` and `chapters`:
267
+
268
+ ```vue
269
+ <VueVideoPlayer
270
+ :playlist="[
271
+ { src: '/videos/ep1.m3u8', title: 'Episode 1', thumbnails: '/videos/ep1.vtt' },
272
+ { src: '/videos/ep2.m3u8', title: 'Episode 2' },
273
+ { src: '/videos/ep3.m3u8', title: 'Episode 3' },
274
+ ]"
275
+ :default-index="0"
276
+ auto-advance
277
+ @playlist-change="(index, item) => console.log('Now playing', item.title)"
278
+ />
279
+ ```
280
+
281
+ `playlist` takes precedence over `src`. Set `:auto-advance="false"` to require a manual next click. `PlaylistItem` is exported for typing.
282
+
283
+ ---
284
+
285
+ ## Event emits
286
+
287
+ Wire the player's playback events into your own analytics or UI without a separate timer:
288
+
289
+ ```vue
290
+ <VueVideoPlayer
291
+ src="/videos/movie.m3u8"
292
+ @play="track('video_play')"
293
+ @pause="track('video_pause')"
294
+ @ended="track('video_complete')"
295
+ @time-update="(time, duration) => (progress = time / duration)"
296
+ @seeked="(time) => track('video_seek', { time })"
297
+ @volume-change="(volume, muted) => console.log(volume, muted)"
298
+ @milestone="(percent) => track(`watched_${percent}`)"
299
+ @error="showRetry()"
300
+ />
301
+ ```
302
+
303
+ `milestone` fires exactly once each as watch progress crosses 25%, 50%, 75% and 100% — handy for completion analytics. Milestone tracking resets per source (including playlist advances).
304
+
305
+ ---
306
+
190
307
  ## YouTube URLs
191
308
 
192
309
  Pass any common YouTube URL as `src` and the player swaps the `<video>` element for a privacy-enhanced (`youtube-nocookie.com`) embed inside the same styled frame — no extra prop needed:
@@ -1,5 +1,6 @@
1
1
  import { HlsConfig } from 'hls.js';
2
2
  import { AudioTrackInfo } from './utils/audio-tracks';
3
+ import { QualityLevelInfo } from './utils/quality-levels';
3
4
 
4
5
  declare function __VLS_template(): {
5
6
  default?(_: {}): any;
@@ -18,6 +19,8 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
18
19
  class?: string;
19
20
  /** Index of the audio track to activate; `-1` means "leave at source default". */
20
21
  audioTrackIndex?: number;
22
+ /** Quality level to switch to: `-1` is Auto, `>=0` pins a level. */
23
+ qualityLevelIndex?: number;
21
24
  }>, {
22
25
  muted: boolean;
23
26
  loop: boolean;
@@ -26,12 +29,16 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
26
29
  playsInline: boolean;
27
30
  preload: string;
28
31
  audioTrackIndex: number;
32
+ qualityLevelIndex: number;
29
33
  }>>, {
30
34
  videoEl: import('vue').Ref<HTMLVideoElement | null, HTMLVideoElement | null>;
31
35
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
32
36
  play: () => void;
33
37
  pause: () => void;
38
+ ended: () => void;
34
39
  "audio-tracks": (tracks: AudioTrackInfo[]) => void;
40
+ "quality-levels": (levels: QualityLevelInfo[]) => void;
41
+ "current-level": (index: number) => void;
35
42
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
36
43
  src: string;
37
44
  hlsConfig?: HlsConfig;
@@ -46,6 +53,8 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
46
53
  class?: string;
47
54
  /** Index of the audio track to activate; `-1` means "leave at source default". */
48
55
  audioTrackIndex?: number;
56
+ /** Quality level to switch to: `-1` is Auto, `>=0` pins a level. */
57
+ qualityLevelIndex?: number;
49
58
  }>, {
50
59
  muted: boolean;
51
60
  loop: boolean;
@@ -54,10 +63,14 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
54
63
  playsInline: boolean;
55
64
  preload: string;
56
65
  audioTrackIndex: number;
66
+ qualityLevelIndex: number;
57
67
  }>>> & Readonly<{
58
68
  onPlay?: (() => any) | undefined;
59
69
  onPause?: (() => any) | undefined;
70
+ onEnded?: (() => any) | undefined;
60
71
  "onAudio-tracks"?: ((tracks: AudioTrackInfo[]) => any) | undefined;
72
+ "onQuality-levels"?: ((levels: QualityLevelInfo[]) => any) | undefined;
73
+ "onCurrent-level"?: ((index: number) => any) | undefined;
61
74
  }>, {
62
75
  muted: boolean;
63
76
  loop: boolean;
@@ -66,6 +79,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
66
79
  playsInline: boolean;
67
80
  preload: string;
68
81
  audioTrackIndex: number;
82
+ qualityLevelIndex: number;
69
83
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
70
84
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
71
85
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"HLSPlayer.vue.d.ts","sourceRoot":"","sources":["../src/HLSPlayer.vue"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAiM5E,iBAAS,cAAc;qBAoDO,GAAG;EAGhC;AAyBD,QAAA,MAAM,eAAe;SAOZ,MAAM;gBACC,SAAS;YACb,OAAO;YACP,OAAO;WACR,OAAO;eACH,OAAO;eACP,OAAO;kBACJ,OAAO;cACX,MAAM;aACP,MAAM;YACP,MAAM;IACd,kFAAkF;sBAChE,MAAM;;;;;;;;;;;;;;;;SAZnB,MAAM;gBACC,SAAS;YACb,OAAO;YACP,OAAO;WACR,OAAO;eACH,OAAO;eACP,OAAO;kBACJ,OAAO;cACX,MAAM;aACP,MAAM;YACP,MAAM;IACd,kFAAkF;sBAChE,MAAM;;;;;;;;;;;;;;WAThB,OAAO;UACR,OAAO;cACH,OAAO;cACP,OAAO;iBACJ,OAAO;aACX,MAAM;qBAIE,MAAM;4EAG1B,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAAvG,wBAAwG;AACxG,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC;AAC9M,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI;KAE1B,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QACxE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;KACb,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACT,CAAC;AACN,KAAK,cAAc,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC;AACxD,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAAE,QAAO;QAClD,MAAM,EAAE,CAAC,CAAC;KACT,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"HLSPlayer.vue.d.ts","sourceRoot":"","sources":["../src/HLSPlayer.vue"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAsOlF,iBAAS,cAAc;qBA2DO,GAAG;EAGhC;AA2BD,QAAA,MAAM,eAAe;SAOZ,MAAM;gBACC,SAAS;YACb,OAAO;YACP,OAAO;WACR,OAAO;eACH,OAAO;eACP,OAAO;kBACJ,OAAO;cACX,MAAM;aACP,MAAM;YACP,MAAM;IACd,kFAAkF;sBAChE,MAAM;IACxB,oEAAoE;wBAChD,MAAM;;;;;;;;;;;;;;;;;;;;SAdrB,MAAM;gBACC,SAAS;YACb,OAAO;YACP,OAAO;WACR,OAAO;eACH,OAAO;eACP,OAAO;kBACJ,OAAO;cACX,MAAM;aACP,MAAM;YACP,MAAM;IACd,kFAAkF;sBAChE,MAAM;IACxB,oEAAoE;wBAChD,MAAM;;;;;;;;;;;;;;;;;;WAXlB,OAAO;UACR,OAAO;cACH,OAAO;cACP,OAAO;iBACJ,OAAO;aACX,MAAM;qBAIE,MAAM;uBAEJ,MAAM;4EAG5B,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAAvG,wBAAwG;AACxG,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC;AAC9M,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI;KAE1B,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QACxE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;KACb,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACT,CAAC;AACN,KAAK,cAAc,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC;AACxD,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAAE,QAAO;QAClD,MAAM,EAAE,CAAC,CAAC;KACT,CAAA;CAAE,CAAC"}
@@ -1,4 +1,4 @@
1
- import { DeviceMode, VideoPlayerProps } from './utils/types';
1
+ import { DeviceMode, PlaylistItem, VideoPlayerProps } from './utils/types';
2
2
 
3
3
  declare function __VLS_template(): {
4
4
  default?(_: {}): any;
@@ -15,11 +15,20 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
15
15
  controls: boolean;
16
16
  autoPlay: boolean;
17
17
  closable: boolean;
18
+ defaultIndex: number;
19
+ autoAdvance: boolean;
18
20
  class: string;
19
21
  }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
20
22
  play: () => void;
21
23
  pause: () => void;
24
+ ended: () => void;
22
25
  close: () => void;
26
+ error: () => void;
27
+ seeked: (currentTime: number) => void;
28
+ "time-update": (currentTime: number, duration: number) => void;
29
+ "volume-change": (volume: number, muted: boolean) => void;
30
+ milestone: (percent: 100 | 25 | 50 | 75) => void;
31
+ "playlist-change": (index: number, item: PlaylistItem) => void;
23
32
  }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<VideoPlayerProps & {
24
33
  class?: string;
25
34
  closable?: boolean;
@@ -32,17 +41,28 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
32
41
  controls: boolean;
33
42
  autoPlay: boolean;
34
43
  closable: boolean;
44
+ defaultIndex: number;
45
+ autoAdvance: boolean;
35
46
  class: string;
36
47
  }>>> & Readonly<{
37
48
  onPlay?: (() => any) | undefined;
38
49
  onPause?: (() => any) | undefined;
50
+ onEnded?: (() => any) | undefined;
39
51
  onClose?: (() => any) | undefined;
52
+ onError?: (() => any) | undefined;
53
+ onSeeked?: ((currentTime: number) => any) | undefined;
54
+ "onTime-update"?: ((currentTime: number, duration: number) => any) | undefined;
55
+ "onVolume-change"?: ((volume: number, muted: boolean) => any) | undefined;
56
+ onMilestone?: ((percent: 100 | 25 | 50 | 75) => any) | undefined;
57
+ "onPlaylist-change"?: ((index: number, item: PlaylistItem) => any) | undefined;
40
58
  }>, {
41
59
  muted: boolean;
42
60
  loop: boolean;
43
61
  controls: boolean | "custom" | "native";
44
62
  autoPlay: boolean;
45
63
  class: string;
64
+ defaultIndex: number;
65
+ autoAdvance: boolean;
46
66
  showDeviceToggle: boolean;
47
67
  defaultDevice: DeviceMode;
48
68
  hoverPlay: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"VideoPlayer.vue.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.vue"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAmPlE,iBAAS,cAAc;qBAqbO,GAAG;EAGhC;AA8CD,QAAA,MAAM,eAAe;YAKsE,MAAM;eAAa,OAAO;;;;;;;;;;;;;;;;YAA1B,MAAM;eAAa,OAAO;;;;;;;;;;;;;;;;;;;;WAA1B,MAAM;;;;cAAa,OAAO;4EAEnH,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAAvG,wBAAwG;AACxG,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC;AAC9M,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI;KAE1B,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QACxE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;KACb,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACT,CAAC;AACN,KAAK,cAAc,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC;AACxD,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAAE,QAAO;QAClD,MAAM,EAAE,CAAC,CAAC;KACT,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"VideoPlayer.vue.d.ts","sourceRoot":"","sources":["../src/VideoPlayer.vue"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAyVhF,iBAAS,cAAc;qBAudO,GAAG;EAGhC;AA2DD,QAAA,MAAM,eAAe;YAKsE,MAAM;eAAa,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;YAA1B,MAAM;eAAa,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAA1B,MAAM;;;;;;cAAa,OAAO;4EAEnH,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAAvG,wBAAwG;AACxG,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC;AAC9M,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI;KAE1B,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QACxE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;KACb,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACT,CAAC;AACN,KAAK,cAAc,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC;AACxD,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAAE,QAAO;QAClD,MAAM,EAAE,CAAC,CAAC;KACT,CAAA;CAAE,CAAC"}
@@ -1,14 +1,78 @@
1
- declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
1
+ import { QualityLevelInfo } from '../utils/quality-levels';
2
+
3
+ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
2
4
  video: HTMLVideoElement | null;
3
5
  isPlaying: boolean;
4
6
  container: HTMLElement | null;
5
7
  onTogglePlay: () => void;
6
- }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
8
+ /** HLS quality levels (empty for non-HLS sources). */
9
+ qualityLevels?: QualityLevelInfo[];
10
+ /** The level hls.js is actually playing (real index, even in Auto). */
11
+ currentLevel?: number;
12
+ /** Selected level: -1 = Auto, >=0 pins a level. */
13
+ selectedLevel?: number;
14
+ /** URL of a WebVTT storyboard for seek-bar thumbnail previews. */
15
+ thumbnails?: string;
16
+ /** Timeline chapters: a WebVTT chapters URL or an inline array. */
17
+ chapters?: string | Array<{
18
+ start: number;
19
+ end?: number;
20
+ title: string;
21
+ }>;
22
+ /** Whether a previous playlist item exists. Shows the prev button. */
23
+ hasPrev?: boolean;
24
+ /** Whether a next playlist item exists. Shows the next button. */
25
+ hasNext?: boolean;
26
+ }>, {
27
+ qualityLevels: () => never[];
28
+ currentLevel: number;
29
+ selectedLevel: number;
30
+ hasPrev: boolean;
31
+ hasNext: boolean;
32
+ }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
33
+ "select-level": (index: number) => void;
34
+ prev: () => void;
35
+ next: () => void;
36
+ }, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
7
37
  video: HTMLVideoElement | null;
8
38
  isPlaying: boolean;
9
39
  container: HTMLElement | null;
10
40
  onTogglePlay: () => void;
11
- }>>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
41
+ /** HLS quality levels (empty for non-HLS sources). */
42
+ qualityLevels?: QualityLevelInfo[];
43
+ /** The level hls.js is actually playing (real index, even in Auto). */
44
+ currentLevel?: number;
45
+ /** Selected level: -1 = Auto, >=0 pins a level. */
46
+ selectedLevel?: number;
47
+ /** URL of a WebVTT storyboard for seek-bar thumbnail previews. */
48
+ thumbnails?: string;
49
+ /** Timeline chapters: a WebVTT chapters URL or an inline array. */
50
+ chapters?: string | Array<{
51
+ start: number;
52
+ end?: number;
53
+ title: string;
54
+ }>;
55
+ /** Whether a previous playlist item exists. Shows the prev button. */
56
+ hasPrev?: boolean;
57
+ /** Whether a next playlist item exists. Shows the next button. */
58
+ hasNext?: boolean;
59
+ }>, {
60
+ qualityLevels: () => never[];
61
+ currentLevel: number;
62
+ selectedLevel: number;
63
+ hasPrev: boolean;
64
+ hasNext: boolean;
65
+ }>>> & Readonly<{
66
+ "onSelect-level"?: ((index: number) => any) | undefined;
67
+ onPrev?: (() => any) | undefined;
68
+ onNext?: (() => any) | undefined;
69
+ }>, {
70
+ currentLevel: number;
71
+ qualityLevels: QualityLevelInfo[];
72
+ selectedLevel: number;
73
+ hasPrev: boolean;
74
+ hasNext: boolean;
75
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
12
76
  export default _default;
13
77
  type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
14
78
  type __VLS_TypePropsToRuntimeProps<T> = {
@@ -19,4 +83,12 @@ type __VLS_TypePropsToRuntimeProps<T> = {
19
83
  required: true;
20
84
  };
21
85
  };
86
+ type __VLS_WithDefaults<P, D> = {
87
+ [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
88
+ default: D[K];
89
+ }> : P[K];
90
+ };
91
+ type __VLS_Prettify<T> = {
92
+ [K in keyof T]: T[K];
93
+ } & {};
22
94
  //# sourceMappingURL=ControlBar.vue.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ControlBar.vue.d.ts","sourceRoot":"","sources":["../../src/components/ControlBar.vue"],"names":[],"mappings":";WA23BS,gBAAgB,GAAG,IAAI;eACnB,OAAO;eACP,WAAW,GAAG,IAAI;kBACf,MAAM,IAAI;;WAHjB,gBAAgB,GAAG,IAAI;eACnB,OAAO;eACP,WAAW,GAAG,IAAI;kBACf,MAAM,IAAI;;AAT1B,wBAWG;AACH,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC"}
1
+ {"version":3,"file":"ControlBar.vue.d.ts","sourceRoot":"","sources":["../../src/components/ControlBar.vue"],"names":[],"mappings":"AAiBA,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;;WA8zCnE,gBAAgB,GAAG,IAAI;eACnB,OAAO;eACP,WAAW,GAAG,IAAI;kBACf,MAAM,IAAI;IACxB,sDAAsD;oBACtC,gBAAgB,EAAE;IAClC,uEAAuE;mBACxD,MAAM;IACrB,mDAAmD;oBACnC,MAAM;IACtB,kEAAkE;iBACrD,MAAM;IACnB,mEAAmE;eACxD,MAAM,GAAG,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,sEAAsE;cAC5D,OAAO;IACjB,kEAAkE;cACxD,OAAO;;;;;;;;;;;;WAjBV,gBAAgB,GAAG,IAAI;eACnB,OAAO;eACP,WAAW,GAAG,IAAI;kBACf,MAAM,IAAI;IACxB,sDAAsD;oBACtC,gBAAgB,EAAE;IAClC,uEAAuE;mBACxD,MAAM;IACrB,mDAAmD;oBACnC,MAAM;IACtB,kEAAkE;iBACrD,MAAM;IACnB,mEAAmE;eACxD,MAAM,GAAG,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,sEAAsE;cAC5D,OAAO;IACjB,kEAAkE;cACxD,OAAO;;;;;;;;;;;;kBAVF,MAAM;mBAFL,gBAAgB,EAAE;mBAIlB,MAAM;aAMZ,OAAO;aAEP,OAAO;;AAvBrB,wBA0BG;AACH,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACjE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC;AAC9M,KAAK,kBAAkB,CAAC,CAAC,EAAE,CAAC,IAAI;KAE1B,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;QACxE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;KACb,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACT,CAAC;AACN,KAAK,cAAc,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAG,GAAG,EAAE,CAAC"}
@@ -0,0 +1,16 @@
1
+ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
2
+ class?: string;
3
+ }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
4
+ class?: string;
5
+ }>>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
6
+ export default _default;
7
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
8
+ type __VLS_TypePropsToRuntimeProps<T> = {
9
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
10
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
11
+ } : {
12
+ type: import('vue').PropType<T[K]>;
13
+ required: true;
14
+ };
15
+ };
16
+ //# sourceMappingURL=IconNext.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconNext.vue.d.ts","sourceRoot":"","sources":["../../src/components/IconNext.vue"],"names":[],"mappings":";YAuEqD,MAAM;;YAAN,MAAM;;AAnE3D,wBAqEI;AAAA,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACrE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC"}
@@ -0,0 +1,16 @@
1
+ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
2
+ class?: string;
3
+ }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
4
+ class?: string;
5
+ }>>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
6
+ export default _default;
7
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
8
+ type __VLS_TypePropsToRuntimeProps<T> = {
9
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
10
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
11
+ } : {
12
+ type: import('vue').PropType<T[K]>;
13
+ required: true;
14
+ };
15
+ };
16
+ //# sourceMappingURL=IconPrev.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconPrev.vue.d.ts","sourceRoot":"","sources":["../../src/components/IconPrev.vue"],"names":[],"mappings":";YAuEqD,MAAM;;YAAN,MAAM;;AAnE3D,wBAqEI;AAAA,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACrE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC"}
@@ -0,0 +1,16 @@
1
+ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
2
+ class?: string;
3
+ }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_TypePropsToRuntimeProps<{
4
+ class?: string;
5
+ }>>> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
6
+ export default _default;
7
+ type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
8
+ type __VLS_TypePropsToRuntimeProps<T> = {
9
+ [K in keyof T]-?: {} extends Pick<T, K> ? {
10
+ type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
11
+ } : {
12
+ type: import('vue').PropType<T[K]>;
13
+ required: true;
14
+ };
15
+ };
16
+ //# sourceMappingURL=IconQuality.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IconQuality.vue.d.ts","sourceRoot":"","sources":["../../src/components/IconQuality.vue"],"names":[],"mappings":";YAuEqD,MAAM;;YAAN,MAAM;;AAnE3D,wBAqEI;AAAA,KAAK,sBAAsB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC;AACrE,KAAK,6BAA6B,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE;CAAE,CAAC"}