@scarlett-player/vue 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +502 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +511 -0
- package/dist/index.js.map +1 -0
- package/dist/style.css +1 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
# @scarlett-player/vue
|
|
2
|
+
|
|
3
|
+
Vue 3 component wrapper for Scarlett Player.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @scarlett-player/vue @scarlett-player/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Basic Component Usage
|
|
14
|
+
|
|
15
|
+
```vue
|
|
16
|
+
<template>
|
|
17
|
+
<div class="video-container">
|
|
18
|
+
<ScarlettPlayer
|
|
19
|
+
ref="playerRef"
|
|
20
|
+
:src="videoUrl"
|
|
21
|
+
:autoplay="false"
|
|
22
|
+
:plugins="plugins"
|
|
23
|
+
@ready="onPlayerReady"
|
|
24
|
+
@play="onPlay"
|
|
25
|
+
@pause="onPause"
|
|
26
|
+
@timeupdate="onTimeUpdate"
|
|
27
|
+
/>
|
|
28
|
+
</div>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script setup lang="ts">
|
|
32
|
+
import { ref } from 'vue';
|
|
33
|
+
import { ScarlettPlayerComponent } from '@scarlett-player/vue';
|
|
34
|
+
import { createHLSPlugin } from '@scarlett-player/hls';
|
|
35
|
+
import { createNativePlugin } from '@scarlett-player/native';
|
|
36
|
+
import { uiPlugin } from '@scarlett-player/ui';
|
|
37
|
+
|
|
38
|
+
const playerRef = ref();
|
|
39
|
+
const videoUrl = ref('https://example.com/video.m3u8');
|
|
40
|
+
|
|
41
|
+
const plugins = [
|
|
42
|
+
createHLSPlugin(),
|
|
43
|
+
createNativePlugin(),
|
|
44
|
+
uiPlugin({
|
|
45
|
+
theme: {
|
|
46
|
+
accentColor: '#e50914',
|
|
47
|
+
},
|
|
48
|
+
}),
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
function onPlayerReady(player) {
|
|
52
|
+
console.log('Player ready!', player);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function onPlay() {
|
|
56
|
+
console.log('Playing');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function onPause() {
|
|
60
|
+
console.log('Paused');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function onTimeUpdate({ currentTime, duration }) {
|
|
64
|
+
console.log(`Time: ${currentTime}s / ${duration}s`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Control player programmatically
|
|
68
|
+
async function playVideo() {
|
|
69
|
+
await playerRef.value?.play();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function pauseVideo() {
|
|
73
|
+
playerRef.value?.pause();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function seekTo(time: number) {
|
|
77
|
+
playerRef.value?.seek(time);
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
|
|
81
|
+
<style scoped>
|
|
82
|
+
.video-container {
|
|
83
|
+
width: 100%;
|
|
84
|
+
max-width: 1280px;
|
|
85
|
+
aspect-ratio: 16 / 9;
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Using the Composable API
|
|
91
|
+
|
|
92
|
+
For more control and reactive state management:
|
|
93
|
+
|
|
94
|
+
```vue
|
|
95
|
+
<template>
|
|
96
|
+
<div>
|
|
97
|
+
<div ref="containerRef" class="video-container"></div>
|
|
98
|
+
|
|
99
|
+
<div class="controls">
|
|
100
|
+
<button @click="play" :disabled="playing">Play</button>
|
|
101
|
+
<button @click="pause" :disabled="!playing">Pause</button>
|
|
102
|
+
<button @click="toggleFullscreen">Fullscreen</button>
|
|
103
|
+
|
|
104
|
+
<div class="time">
|
|
105
|
+
{{ formatTime(currentTime) }} / {{ formatTime(duration) }}
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<input
|
|
109
|
+
type="range"
|
|
110
|
+
:value="currentTime"
|
|
111
|
+
:max="duration"
|
|
112
|
+
@input="seek($event.target.value)"
|
|
113
|
+
/>
|
|
114
|
+
|
|
115
|
+
<div class="volume">
|
|
116
|
+
<button @click="setMuted(!muted)">
|
|
117
|
+
{{ muted ? 'Unmute' : 'Mute' }}
|
|
118
|
+
</button>
|
|
119
|
+
<input
|
|
120
|
+
type="range"
|
|
121
|
+
:value="volume"
|
|
122
|
+
min="0"
|
|
123
|
+
max="1"
|
|
124
|
+
step="0.1"
|
|
125
|
+
@input="setVolume($event.target.value)"
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
</template>
|
|
131
|
+
|
|
132
|
+
<script setup lang="ts">
|
|
133
|
+
import { ref } from 'vue';
|
|
134
|
+
import { useScarlettPlayer } from '@scarlett-player/vue';
|
|
135
|
+
import { createHLSPlugin } from '@scarlett-player/hls';
|
|
136
|
+
import { createNativePlugin } from '@scarlett-player/native';
|
|
137
|
+
import { uiPlugin } from '@scarlett-player/ui';
|
|
138
|
+
|
|
139
|
+
const containerRef = ref<HTMLElement | null>(null);
|
|
140
|
+
|
|
141
|
+
const {
|
|
142
|
+
player,
|
|
143
|
+
isReady,
|
|
144
|
+
playing,
|
|
145
|
+
paused,
|
|
146
|
+
currentTime,
|
|
147
|
+
duration,
|
|
148
|
+
volume,
|
|
149
|
+
muted,
|
|
150
|
+
fullscreen,
|
|
151
|
+
play,
|
|
152
|
+
pause,
|
|
153
|
+
seek,
|
|
154
|
+
setVolume,
|
|
155
|
+
setMuted,
|
|
156
|
+
toggleFullscreen,
|
|
157
|
+
} = useScarlettPlayer({
|
|
158
|
+
container: containerRef,
|
|
159
|
+
src: 'https://example.com/video.m3u8',
|
|
160
|
+
plugins: [
|
|
161
|
+
createHLSPlugin(),
|
|
162
|
+
createNativePlugin(),
|
|
163
|
+
uiPlugin(),
|
|
164
|
+
],
|
|
165
|
+
autoInit: true,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
function formatTime(seconds: number): string {
|
|
169
|
+
const mins = Math.floor(seconds / 60);
|
|
170
|
+
const secs = Math.floor(seconds % 60);
|
|
171
|
+
return `${mins}:${secs.toString().padStart(2, '0')}`;
|
|
172
|
+
}
|
|
173
|
+
</script>
|
|
174
|
+
|
|
175
|
+
<style scoped>
|
|
176
|
+
.video-container {
|
|
177
|
+
width: 100%;
|
|
178
|
+
max-width: 1280px;
|
|
179
|
+
aspect-ratio: 16 / 9;
|
|
180
|
+
background: #000;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.controls {
|
|
184
|
+
margin-top: 1rem;
|
|
185
|
+
display: flex;
|
|
186
|
+
gap: 1rem;
|
|
187
|
+
align-items: center;
|
|
188
|
+
}
|
|
189
|
+
</style>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Component Props
|
|
193
|
+
|
|
194
|
+
| Prop | Type | Default | Description |
|
|
195
|
+
|------|------|---------|-------------|
|
|
196
|
+
| `src` | `string` | - | Video source URL |
|
|
197
|
+
| `poster` | `string` | - | Poster image URL |
|
|
198
|
+
| `autoplay` | `boolean` | `false` | Auto-play video on load |
|
|
199
|
+
| `loop` | `boolean` | `false` | Loop playback |
|
|
200
|
+
| `volume` | `number` | `1.0` | Initial volume (0-1) |
|
|
201
|
+
| `muted` | `boolean` | `false` | Start muted |
|
|
202
|
+
| `logLevel` | `'debug' \| 'info' \| 'warn' \| 'error'` | `'warn'` | Console log level |
|
|
203
|
+
| `plugins` | `Plugin[]` | `[]` | Scarlett Player plugins |
|
|
204
|
+
| `options` | `PlayerOptions` | `{}` | Additional player options |
|
|
205
|
+
|
|
206
|
+
## Component Events
|
|
207
|
+
|
|
208
|
+
| Event | Payload | Description |
|
|
209
|
+
|-------|---------|-------------|
|
|
210
|
+
| `ready` | `ScarlettPlayer` | Player initialized and ready |
|
|
211
|
+
| `play` | - | Playback started |
|
|
212
|
+
| `pause` | - | Playback paused |
|
|
213
|
+
| `seeking` | `{ time: number }` | Seeking to new time |
|
|
214
|
+
| `seeked` | - | Seek completed |
|
|
215
|
+
| `timeupdate` | `{ currentTime: number, duration: number }` | Time updated |
|
|
216
|
+
| `volumechange` | `{ volume: number, muted: boolean }` | Volume/mute changed |
|
|
217
|
+
| `ratechange` | `{ rate: number }` | Playback rate changed |
|
|
218
|
+
| `ended` | - | Playback ended |
|
|
219
|
+
| `error` | `Error` | Error occurred |
|
|
220
|
+
| `loaded` | `any` | Media loaded |
|
|
221
|
+
| `loadedmetadata` | `any` | Metadata loaded |
|
|
222
|
+
| `qualitychange` | `{ quality: string, auto: boolean }` | Quality level changed |
|
|
223
|
+
| `qualitylevels` | `any` | Quality levels available |
|
|
224
|
+
| `fullscreenchange` | `{ fullscreen: boolean }` | Fullscreen state changed |
|
|
225
|
+
| `destroy` | - | Player destroyed |
|
|
226
|
+
|
|
227
|
+
## Component Methods (via ref)
|
|
228
|
+
|
|
229
|
+
Access player methods via template ref:
|
|
230
|
+
|
|
231
|
+
```vue
|
|
232
|
+
<template>
|
|
233
|
+
<ScarlettPlayer ref="playerRef" />
|
|
234
|
+
</template>
|
|
235
|
+
|
|
236
|
+
<script setup>
|
|
237
|
+
const playerRef = ref();
|
|
238
|
+
|
|
239
|
+
// Access methods
|
|
240
|
+
playerRef.value.play();
|
|
241
|
+
playerRef.value.pause();
|
|
242
|
+
playerRef.value.seek(30);
|
|
243
|
+
playerRef.value.setVolume(0.5);
|
|
244
|
+
playerRef.value.setMuted(true);
|
|
245
|
+
playerRef.value.setQuality(2);
|
|
246
|
+
playerRef.value.requestFullscreen();
|
|
247
|
+
</script>
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Available Methods
|
|
251
|
+
|
|
252
|
+
- `play()` - Start playback
|
|
253
|
+
- `pause()` - Pause playback
|
|
254
|
+
- `seek(time: number)` - Seek to time in seconds
|
|
255
|
+
- `load(src: string)` - Load new source
|
|
256
|
+
- `setVolume(volume: number)` - Set volume (0-1)
|
|
257
|
+
- `setMuted(muted: boolean)` - Set muted state
|
|
258
|
+
- `setPlaybackRate(rate: number)` - Set playback speed
|
|
259
|
+
- `getQualities()` - Get available quality levels
|
|
260
|
+
- `setQuality(index: number)` - Set quality level (-1 for auto)
|
|
261
|
+
- `getCurrentQuality()` - Get current quality index
|
|
262
|
+
- `requestFullscreen()` - Enter fullscreen
|
|
263
|
+
- `exitFullscreen()` - Exit fullscreen
|
|
264
|
+
- `toggleFullscreen()` - Toggle fullscreen
|
|
265
|
+
- `requestAirPlay()` - Show AirPlay picker
|
|
266
|
+
- `requestChromecast()` - Request Chromecast session
|
|
267
|
+
- `stopCasting()` - Stop casting
|
|
268
|
+
- `seekToLive()` - Seek to live edge (for live streams)
|
|
269
|
+
- `getState()` - Get current state snapshot
|
|
270
|
+
- `getPlugin(name: string)` - Get plugin instance
|
|
271
|
+
- `registerPlugin(plugin: Plugin)` - Register new plugin
|
|
272
|
+
- `destroy()` - Destroy player instance
|
|
273
|
+
|
|
274
|
+
## Composable API
|
|
275
|
+
|
|
276
|
+
The `useScarlettPlayer` composable provides reactive state and methods:
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
const {
|
|
280
|
+
// Instance
|
|
281
|
+
player,
|
|
282
|
+
isReady,
|
|
283
|
+
error,
|
|
284
|
+
|
|
285
|
+
// Reactive state
|
|
286
|
+
playing,
|
|
287
|
+
paused,
|
|
288
|
+
currentTime,
|
|
289
|
+
duration,
|
|
290
|
+
volume,
|
|
291
|
+
muted,
|
|
292
|
+
bufferedAmount,
|
|
293
|
+
fullscreen,
|
|
294
|
+
live,
|
|
295
|
+
progress,
|
|
296
|
+
isBuffering,
|
|
297
|
+
|
|
298
|
+
// Methods
|
|
299
|
+
init,
|
|
300
|
+
play,
|
|
301
|
+
pause,
|
|
302
|
+
seek,
|
|
303
|
+
load,
|
|
304
|
+
setVolume,
|
|
305
|
+
setMuted,
|
|
306
|
+
requestFullscreen,
|
|
307
|
+
exitFullscreen,
|
|
308
|
+
toggleFullscreen,
|
|
309
|
+
getQualities,
|
|
310
|
+
setQuality,
|
|
311
|
+
getCurrentQuality,
|
|
312
|
+
} = useScarlettPlayer(options);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
## Global Plugin Installation
|
|
316
|
+
|
|
317
|
+
You can register the component globally:
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { createApp } from 'vue';
|
|
321
|
+
import { ScarlettPlayerPlugin } from '@scarlett-player/vue';
|
|
322
|
+
import App from './App.vue';
|
|
323
|
+
|
|
324
|
+
const app = createApp(App);
|
|
325
|
+
app.use(ScarlettPlayerPlugin);
|
|
326
|
+
app.mount('#app');
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Then use it without importing:
|
|
330
|
+
|
|
331
|
+
```vue
|
|
332
|
+
<template>
|
|
333
|
+
<ScarlettPlayer :src="videoUrl" :plugins="plugins" />
|
|
334
|
+
</template>
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## TypeScript Support
|
|
338
|
+
|
|
339
|
+
Full TypeScript support with exported types:
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
import type {
|
|
343
|
+
ScarlettPlayer,
|
|
344
|
+
PlayerOptions,
|
|
345
|
+
QualityLevel,
|
|
346
|
+
ScarlettPlugin,
|
|
347
|
+
EventName,
|
|
348
|
+
StateStore,
|
|
349
|
+
} from '@scarlett-player/vue';
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
## Examples
|
|
353
|
+
|
|
354
|
+
### Custom Controls
|
|
355
|
+
|
|
356
|
+
```vue
|
|
357
|
+
<template>
|
|
358
|
+
<div class="player-wrapper">
|
|
359
|
+
<ScarlettPlayer
|
|
360
|
+
ref="playerRef"
|
|
361
|
+
:src="videoUrl"
|
|
362
|
+
:plugins="plugins"
|
|
363
|
+
@timeupdate="onTimeUpdate"
|
|
364
|
+
/>
|
|
365
|
+
|
|
366
|
+
<!-- Custom UI overlay -->
|
|
367
|
+
<div class="custom-controls">
|
|
368
|
+
<button @click="playPause">
|
|
369
|
+
{{ playing ? 'Pause' : 'Play' }}
|
|
370
|
+
</button>
|
|
371
|
+
|
|
372
|
+
<div class="progress-bar" @click="handleProgressClick">
|
|
373
|
+
<div class="progress-fill" :style="{ width: progressPercent + '%' }"></div>
|
|
374
|
+
</div>
|
|
375
|
+
|
|
376
|
+
<select @change="handleQualityChange">
|
|
377
|
+
<option value="-1">Auto</option>
|
|
378
|
+
<option
|
|
379
|
+
v-for="(quality, index) in qualities"
|
|
380
|
+
:key="index"
|
|
381
|
+
:value="index"
|
|
382
|
+
>
|
|
383
|
+
{{ quality.label }}
|
|
384
|
+
</option>
|
|
385
|
+
</select>
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
</template>
|
|
389
|
+
|
|
390
|
+
<script setup lang="ts">
|
|
391
|
+
import { ref, computed } from 'vue';
|
|
392
|
+
import { ScarlettPlayerComponent } from '@scarlett-player/vue';
|
|
393
|
+
import { createHLSPlugin } from '@scarlett-player/hls';
|
|
394
|
+
import { uiPlugin } from '@scarlett-player/ui';
|
|
395
|
+
|
|
396
|
+
const playerRef = ref();
|
|
397
|
+
const videoUrl = ref('https://example.com/video.m3u8');
|
|
398
|
+
const playing = ref(false);
|
|
399
|
+
const currentTime = ref(0);
|
|
400
|
+
const duration = ref(0);
|
|
401
|
+
const qualities = ref([]);
|
|
402
|
+
|
|
403
|
+
const plugins = [
|
|
404
|
+
createHLSPlugin(),
|
|
405
|
+
uiPlugin({ hideDelay: 3000 }),
|
|
406
|
+
];
|
|
407
|
+
|
|
408
|
+
const progressPercent = computed(() => {
|
|
409
|
+
if (duration.value === 0) return 0;
|
|
410
|
+
return (currentTime.value / duration.value) * 100;
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
function onTimeUpdate({ currentTime: ct, duration: d }) {
|
|
414
|
+
currentTime.value = ct;
|
|
415
|
+
duration.value = d;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
function playPause() {
|
|
419
|
+
if (playing.value) {
|
|
420
|
+
playerRef.value?.pause();
|
|
421
|
+
} else {
|
|
422
|
+
playerRef.value?.play();
|
|
423
|
+
}
|
|
424
|
+
playing.value = !playing.value;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
function handleProgressClick(e: MouseEvent) {
|
|
428
|
+
const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();
|
|
429
|
+
const percent = (e.clientX - rect.left) / rect.width;
|
|
430
|
+
const seekTime = percent * duration.value;
|
|
431
|
+
playerRef.value?.seek(seekTime);
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function handleQualityChange(e: Event) {
|
|
435
|
+
const index = parseInt((e.target as HTMLSelectElement).value);
|
|
436
|
+
playerRef.value?.setQuality(index);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function loadQualities() {
|
|
440
|
+
qualities.value = playerRef.value?.getQualities() ?? [];
|
|
441
|
+
}
|
|
442
|
+
</script>
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### Live Stream with DVR
|
|
446
|
+
|
|
447
|
+
```vue
|
|
448
|
+
<template>
|
|
449
|
+
<div>
|
|
450
|
+
<ScarlettPlayer
|
|
451
|
+
ref="playerRef"
|
|
452
|
+
:src="liveStreamUrl"
|
|
453
|
+
:autoplay="true"
|
|
454
|
+
:plugins="plugins"
|
|
455
|
+
@loadedmetadata="onMetadataLoaded"
|
|
456
|
+
/>
|
|
457
|
+
|
|
458
|
+
<button v-if="isLive" @click="goToLive">
|
|
459
|
+
Go to Live
|
|
460
|
+
</button>
|
|
461
|
+
</div>
|
|
462
|
+
</template>
|
|
463
|
+
|
|
464
|
+
<script setup lang="ts">
|
|
465
|
+
import { ref } from 'vue';
|
|
466
|
+
import { ScarlettPlayerComponent } from '@scarlett-player/vue';
|
|
467
|
+
import { createHLSPlugin } from '@scarlett-player/hls';
|
|
468
|
+
import { uiPlugin } from '@scarlett-player/ui';
|
|
469
|
+
|
|
470
|
+
const playerRef = ref();
|
|
471
|
+
const liveStreamUrl = ref('https://example.com/live.m3u8');
|
|
472
|
+
const isLive = ref(false);
|
|
473
|
+
|
|
474
|
+
const plugins = [
|
|
475
|
+
createHLSPlugin({ lowLatencyMode: true }),
|
|
476
|
+
uiPlugin(),
|
|
477
|
+
];
|
|
478
|
+
|
|
479
|
+
function onMetadataLoaded(payload) {
|
|
480
|
+
isLive.value = payload.live ?? false;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
function goToLive() {
|
|
484
|
+
playerRef.value?.seekToLive();
|
|
485
|
+
}
|
|
486
|
+
</script>
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
## Browser Support
|
|
490
|
+
|
|
491
|
+
- Chrome 80+
|
|
492
|
+
- Firefox 78+
|
|
493
|
+
- Safari 14+
|
|
494
|
+
- Edge 80+
|
|
495
|
+
|
|
496
|
+
## License
|
|
497
|
+
|
|
498
|
+
MIT
|
|
499
|
+
|
|
500
|
+
## Credits
|
|
501
|
+
|
|
502
|
+
Built with Scarlett Player - Modular. Extensible. Yours.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty;Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),a=((e,a)=>{const l=e.__vccOpts||e;for(const[t,u]of a)l[t]=u;return l})(e.defineComponent({__name:"ScarlettPlayer",props:{src:{type:String,required:!1},poster:{type:String,required:!1},autoplay:{type:Boolean,default:!1},loop:{type:Boolean,default:!1},volume:{type:Number,default:1,validator:e=>e>=0&&e<=1},muted:{type:Boolean,default:!1},logLevel:{type:String,default:"warn"},plugins:{type:Array,default:()=>[]},options:{type:Object,default:()=>({})}},emits:["ready","play","pause","seeking","seeked","timeupdate","volumechange","ratechange","ended","error","loaded","loadedmetadata","qualitychange","qualitylevels","fullscreenchange","destroy"],setup(a,{expose:l,emit:t}){const u=a,r=t,n=e.ref(null),o=e.ref(null);return e.onMounted(async()=>{var e;if(n.value)try{const{ScarlettPlayer:a}=await import("@scarlett-player/core"),l={container:n.value,src:u.src,poster:u.poster,autoplay:u.autoplay,loop:u.loop,volume:u.volume,muted:u.muted,logLevel:u.logLevel,plugins:u.plugins,...u.options};o.value=new a(l),await o.value.init(),(e=o.value).on("player:ready",()=>r("ready",e)),e.on("player:destroy",()=>r("destroy")),e.on("playback:play",()=>r("play")),e.on("playback:pause",()=>r("pause")),e.on("playback:seeking",e=>r("seeking",e)),e.on("playback:seeked",()=>r("seeked")),e.on("playback:timeupdate",e=>r("timeupdate",e)),e.on("playback:ended",()=>r("ended")),e.on("playback:ratechange",e=>r("ratechange",e)),e.on("media:loaded",e=>r("loaded",e)),e.on("media:loadedmetadata",e=>r("loadedmetadata",e)),e.on("volume:change",e=>r("volumechange",e)),e.on("quality:change",e=>r("qualitychange",e)),e.on("quality:levels",e=>r("qualitylevels",e)),e.on("fullscreen:change",e=>r("fullscreenchange",e)),e.on("error",e=>r("error",e)),r("ready",o.value)}catch(a){console.error("Failed to initialize ScarlettPlayer:",a),r("error",a)}else console.error("ScarlettPlayer: Container ref not found")}),e.onBeforeUnmount(()=>{o.value&&(o.value.destroy(),o.value=null)}),e.watch(()=>u.src,async e=>{e&&o.value&&await o.value.load(e)}),e.watch(()=>u.volume,e=>{o.value&&o.value.setVolume(e)}),e.watch(()=>u.muted,e=>{o.value&&o.value.setMuted(e)}),e.watch(()=>u.autoplay,e=>{o.value&&o.value.setAutoplay(e)}),l({player:o,async play(){var e;await(null==(e=o.value)?void 0:e.play())},pause(){var e;null==(e=o.value)||e.pause()},seek(e){var a;null==(a=o.value)||a.seek(e)},setVolume(e){var a;null==(a=o.value)||a.setVolume(e)},setMuted(e){var a;null==(a=o.value)||a.setMuted(e)},setPlaybackRate(e){var a;null==(a=o.value)||a.setPlaybackRate(e)},getQualities(){var e;return(null==(e=o.value)?void 0:e.getQualities())??[]},setQuality(e){var a;null==(a=o.value)||a.setQuality(e)},getCurrentQuality(){var e;return(null==(e=o.value)?void 0:e.getCurrentQuality())??-1},async requestFullscreen(){var e;await(null==(e=o.value)?void 0:e.requestFullscreen())},async exitFullscreen(){var e;await(null==(e=o.value)?void 0:e.exitFullscreen())},async toggleFullscreen(){var e;await(null==(e=o.value)?void 0:e.toggleFullscreen())},requestAirPlay(){var e;null==(e=o.value)||e.requestAirPlay()},async requestChromecast(){var e;await(null==(e=o.value)?void 0:e.requestChromecast())},stopCasting(){var e;null==(e=o.value)||e.stopCasting()},seekToLive(){var e;null==(e=o.value)||e.seekToLive()},getState(){var e;return null==(e=o.value)?void 0:e.getState()},getPlugin(e){var a;return(null==(a=o.value)?void 0:a.getPlugin(e))??null},registerPlugin(e){var a;null==(a=o.value)||a.registerPlugin(e)},async load(e){var a;await(null==(a=o.value)?void 0:a.load(e))},destroy(){var e;null==(e=o.value)||e.destroy()},get playing(){var e;return(null==(e=o.value)?void 0:e.playing)??!1},get paused(){var e;return(null==(e=o.value)?void 0:e.paused)??!0},get currentTime(){var e;return(null==(e=o.value)?void 0:e.currentTime)??0},get duration(){var e;return(null==(e=o.value)?void 0:e.duration)??0},get volume(){var e;return(null==(e=o.value)?void 0:e.volume)??1},get muted(){var e;return(null==(e=o.value)?void 0:e.muted)??!1},get playbackRate(){var e;return(null==(e=o.value)?void 0:e.playbackRate)??1},get bufferedAmount(){var e;return(null==(e=o.value)?void 0:e.bufferedAmount)??0},get fullscreen(){var e;return(null==(e=o.value)?void 0:e.fullscreen)??!1},get live(){var e;return(null==(e=o.value)?void 0:e.live)??!1},get autoplay(){var e;return(null==(e=o.value)?void 0:e.autoplay)??!1}}),(a,l)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"containerRef",ref:n,class:"scarlett-player-container"},null,512))}}),[["__scopeId","data-v-5f43baa1"]]);const l={install(e){e.component("ScarlettPlayer",a)}};exports.ScarlettPlayerComponent=a,exports.ScarlettPlayerPlugin=l,exports.default=a,exports.useScarlettPlayer=function(a){const l=e.ref(null),t=e.ref(!1),u=e.ref(null),r=e.ref(!1),n=e.ref(!0),o=e.ref(0),v=e.ref(0),i=e.ref(a.volume??1),s=e.ref(a.muted??!1),c=e.ref(0),d=e.ref(!1);async function y(){var e;if(a.container.value)try{const{ScarlettPlayer:y}=await import("@scarlett-player/core"),p=new y({container:a.container.value,src:a.src,poster:a.poster,autoplay:a.autoplay,loop:a.loop,volume:a.volume,muted:a.muted,logLevel:a.logLevel,plugins:a.plugins});await p.init(),l.value=p,(e=p).on("playback:play",()=>{r.value=!0,n.value=!1}),e.on("playback:pause",()=>{r.value=!1,n.value=!0}),e.on("playback:timeupdate",e=>{o.value=e.currentTime}),e.on("volume:change",e=>{i.value=e.volume,s.value=e.muted}),e.on("media:progress",e=>{c.value=e.buffered}),e.on("fullscreen:change",e=>{d.value=e.fullscreen}),e.on("media:loadedmetadata",e=>{v.value=e.duration??0}),e.on("error",e=>{u.value=e}),t.value=!0}catch(y){u.value=y,console.error("Failed to initialize Scarlett Player:",y)}else u.value=new Error("Container element not found")}const p=e.computed(()=>0===v.value?0:o.value/v.value*100),g=e.computed(()=>{if(!l.value)return!1;return l.value.getState().buffering??!1});return e.onMounted(()=>{!1!==a.autoInit&&y()}),e.onBeforeUnmount(()=>{l.value&&(l.value.destroy(),l.value=null)}),{player:l,isReady:t,error:u,playing:r,paused:n,currentTime:o,duration:v,volume:i,muted:s,bufferedAmount:c,fullscreen:d,progress:p,isBuffering:g,init:y,play:async function(){l.value&&await l.value.play()},pause:function(){l.value&&l.value.pause()},seek:function(e){l.value&&l.value.seek(e)},load:async function(e){l.value&&await l.value.load(e)},setVolume:function(e){l.value&&l.value.setVolume(e)},setMuted:function(e){l.value&&l.value.setMuted(e)},requestFullscreen:async function(){l.value&&await l.value.requestFullscreen()},exitFullscreen:async function(){l.value&&await l.value.exitFullscreen()},toggleFullscreen:async function(){l.value&&await l.value.toggleFullscreen()},getQualities:function(){var e;return(null==(e=l.value)?void 0:e.getQualities())??[]},setQuality:function(e){l.value&&l.value.setQuality(e)},getCurrentQuality:function(){var e;return(null==(e=l.value)?void 0:e.getCurrentQuality())??-1}}};
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/ScarlettPlayer.vue","../src/index.ts","../src/composables/useScarlettPlayer.ts"],"sourcesContent":["<template>\n <div ref=\"containerRef\" class=\"scarlett-player-container\"></div>\n</template>\n\n<script setup lang=\"ts\">\nimport {\n ref,\n onMounted,\n onBeforeUnmount,\n watch,\n type PropType,\n defineExpose,\n} from 'vue';\nimport type { ScarlettPlayer, PlayerOptions, Plugin } from '@scarlett-player/core';\n\n// Props\nconst props = defineProps({\n /**\n * Video source URL\n */\n src: {\n type: String,\n required: false,\n },\n /**\n * Poster image URL\n */\n poster: {\n type: String,\n required: false,\n },\n /**\n * Autoplay video\n */\n autoplay: {\n type: Boolean,\n default: false,\n },\n /**\n * Loop playback\n */\n loop: {\n type: Boolean,\n default: false,\n },\n /**\n * Initial volume (0-1)\n */\n volume: {\n type: Number,\n default: 1.0,\n validator: (value: number) => value >= 0 && value <= 1,\n },\n /**\n * Start muted\n */\n muted: {\n type: Boolean,\n default: false,\n },\n /**\n * Log level\n */\n logLevel: {\n type: String as PropType<'debug' | 'info' | 'warn' | 'error'>,\n default: 'warn',\n },\n /**\n * Plugins to register\n */\n plugins: {\n type: Array as PropType<Plugin[]>,\n default: () => [],\n },\n /**\n * Player options (overrides individual props)\n */\n options: {\n type: Object as PropType<Partial<PlayerOptions>>,\n default: () => ({}),\n },\n});\n\n// Emits\nconst emit = defineEmits<{\n ready: [player: ScarlettPlayer];\n play: [];\n pause: [];\n seeking: [payload: { time: number }];\n seeked: [];\n timeupdate: [payload: { currentTime: number; duration: number }];\n volumechange: [payload: { volume: number; muted: boolean }];\n ratechange: [payload: { rate: number }];\n ended: [];\n error: [error: any];\n loaded: [payload: any];\n loadedmetadata: [payload: any];\n qualitychange: [payload: { quality: string; auto: boolean }];\n qualitylevels: [payload: any];\n fullscreenchange: [payload: { fullscreen: boolean }];\n destroy: [];\n}>();\n\n// Refs\nconst containerRef = ref<HTMLElement | null>(null);\nconst playerInstance = ref<ScarlettPlayer | null>(null);\n\n// Lifecycle\nonMounted(async () => {\n if (!containerRef.value) {\n console.error('ScarlettPlayer: Container ref not found');\n return;\n }\n\n try {\n // Import ScarlettPlayer dynamically to avoid SSR issues\n const { ScarlettPlayer: PlayerClass } = await import('@scarlett-player/core');\n\n // Merge props into options\n const playerOptions: PlayerOptions = {\n container: containerRef.value,\n src: props.src,\n poster: props.poster,\n autoplay: props.autoplay,\n loop: props.loop,\n volume: props.volume,\n muted: props.muted,\n logLevel: props.logLevel,\n plugins: props.plugins,\n ...props.options, // Allow options prop to override\n };\n\n // Create player instance\n playerInstance.value = new PlayerClass(playerOptions);\n\n // Initialize player\n await playerInstance.value.init();\n\n // Set up event listeners\n setupEventListeners(playerInstance.value);\n\n // Emit ready event\n emit('ready', playerInstance.value);\n } catch (error) {\n console.error('Failed to initialize ScarlettPlayer:', error);\n emit('error', error);\n }\n});\n\nonBeforeUnmount(() => {\n if (playerInstance.value) {\n playerInstance.value.destroy();\n playerInstance.value = null;\n }\n});\n\n// Watch for src changes\nwatch(\n () => props.src,\n async (newSrc) => {\n if (newSrc && playerInstance.value) {\n await playerInstance.value.load(newSrc);\n }\n }\n);\n\n// Watch for volume changes\nwatch(\n () => props.volume,\n (newVolume) => {\n if (playerInstance.value) {\n playerInstance.value.setVolume(newVolume);\n }\n }\n);\n\n// Watch for muted changes\nwatch(\n () => props.muted,\n (newMuted) => {\n if (playerInstance.value) {\n playerInstance.value.setMuted(newMuted);\n }\n }\n);\n\n// Watch for autoplay changes\nwatch(\n () => props.autoplay,\n (newAutoplay) => {\n if (playerInstance.value) {\n playerInstance.value.setAutoplay(newAutoplay);\n }\n }\n);\n\n// Event listeners setup\nfunction setupEventListeners(player: ScarlettPlayer) {\n // Player events\n player.on('player:ready', () => emit('ready', player));\n player.on('player:destroy', () => emit('destroy'));\n\n // Playback events\n player.on('playback:play', () => emit('play'));\n player.on('playback:pause', () => emit('pause'));\n player.on('playback:seeking', (payload) => emit('seeking', payload));\n player.on('playback:seeked', () => emit('seeked'));\n player.on('playback:timeupdate', (payload) => emit('timeupdate', payload));\n player.on('playback:ended', () => emit('ended'));\n player.on('playback:ratechange', (payload) => emit('ratechange', payload));\n\n // Media events\n player.on('media:loaded', (payload) => emit('loaded', payload));\n player.on('media:loadedmetadata', (payload) => emit('loadedmetadata', payload));\n\n // Volume events\n player.on('volume:change', (payload) => emit('volumechange', payload));\n\n // Quality events\n player.on('quality:change', (payload) => emit('qualitychange', payload));\n player.on('quality:levels', (payload) => emit('qualitylevels', payload));\n\n // Fullscreen events\n player.on('fullscreen:change', (payload) => emit('fullscreenchange', payload));\n\n // Error events\n player.on('error', (error) => emit('error', error));\n}\n\n// Public API (exposed to parent component via ref)\ndefineExpose({\n player: playerInstance,\n\n // Playback methods\n async play() {\n await playerInstance.value?.play();\n },\n pause() {\n playerInstance.value?.pause();\n },\n seek(time: number) {\n playerInstance.value?.seek(time);\n },\n\n // Volume methods\n setVolume(volume: number) {\n playerInstance.value?.setVolume(volume);\n },\n setMuted(muted: boolean) {\n playerInstance.value?.setMuted(muted);\n },\n\n // Playback rate\n setPlaybackRate(rate: number) {\n playerInstance.value?.setPlaybackRate(rate);\n },\n\n // Quality methods\n getQualities() {\n return playerInstance.value?.getQualities() ?? [];\n },\n setQuality(index: number) {\n playerInstance.value?.setQuality(index);\n },\n getCurrentQuality() {\n return playerInstance.value?.getCurrentQuality() ?? -1;\n },\n\n // Fullscreen methods\n async requestFullscreen() {\n await playerInstance.value?.requestFullscreen();\n },\n async exitFullscreen() {\n await playerInstance.value?.exitFullscreen();\n },\n async toggleFullscreen() {\n await playerInstance.value?.toggleFullscreen();\n },\n\n // Casting methods\n requestAirPlay() {\n playerInstance.value?.requestAirPlay();\n },\n async requestChromecast() {\n await playerInstance.value?.requestChromecast();\n },\n stopCasting() {\n playerInstance.value?.stopCasting();\n },\n\n // Live stream methods\n seekToLive() {\n playerInstance.value?.seekToLive();\n },\n\n // State methods\n getState() {\n return playerInstance.value?.getState();\n },\n\n // Plugin methods\n getPlugin<T>(name: string) {\n return playerInstance.value?.getPlugin<T>(name) ?? null;\n },\n registerPlugin(plugin: Plugin) {\n playerInstance.value?.registerPlugin(plugin);\n },\n\n // Load source\n async load(src: string) {\n await playerInstance.value?.load(src);\n },\n\n // Destroy\n destroy() {\n playerInstance.value?.destroy();\n },\n\n // State getters\n get playing() {\n return playerInstance.value?.playing ?? false;\n },\n get paused() {\n return playerInstance.value?.paused ?? true;\n },\n get currentTime() {\n return playerInstance.value?.currentTime ?? 0;\n },\n get duration() {\n return playerInstance.value?.duration ?? 0;\n },\n get volume() {\n return playerInstance.value?.volume ?? 1;\n },\n get muted() {\n return playerInstance.value?.muted ?? false;\n },\n get playbackRate() {\n return playerInstance.value?.playbackRate ?? 1;\n },\n get bufferedAmount() {\n return playerInstance.value?.bufferedAmount ?? 0;\n },\n get fullscreen() {\n return playerInstance.value?.fullscreen ?? false;\n },\n get live() {\n return playerInstance.value?.live ?? false;\n },\n get autoplay() {\n return playerInstance.value?.autoplay ?? false;\n },\n});\n</script>\n\n<style scoped>\n.scarlett-player-container {\n width: 100%;\n height: 100%;\n position: relative;\n}\n</style>\n","/**\n * @scarlett-player/vue - Vue 3 component wrapper for Scarlett Player\n *\n * Provides a Vue 3 component that wraps the Scarlett Player core.\n * Supports Composition API, TypeScript, and reactive props.\n *\n * @packageDocumentation\n */\n\nimport ScarlettPlayerComponent from './ScarlettPlayer.vue';\nimport type { App, Plugin } from 'vue';\n\n// Export the component\nexport { ScarlettPlayerComponent };\nexport default ScarlettPlayerComponent;\n\n// Export composables\nexport { useScarlettPlayer } from './composables/useScarlettPlayer';\n\n// Re-export core types for convenience\nexport type {\n ScarlettPlayer,\n PlayerOptions,\n QualityLevel,\n Plugin as ScarlettPlugin,\n PluginType,\n EventName,\n EventPayload,\n StateStore,\n PlaybackState,\n MediaType,\n} from '@scarlett-player/core';\n\n// Vue plugin installation (optional)\nexport const ScarlettPlayerPlugin: Plugin = {\n install(app: App) {\n app.component('ScarlettPlayer', ScarlettPlayerComponent);\n },\n};\n","/**\n * Composable for using Scarlett Player in Vue 3\n *\n * Provides a reactive API for controlling the player programmatically.\n */\n\nimport { ref, onMounted, onBeforeUnmount, computed, type Ref } from 'vue';\nimport type { ScarlettPlayer, PlayerOptions } from '@scarlett-player/core';\n\nexport interface UseScarlettPlayerOptions extends Omit<PlayerOptions, 'container'> {\n /**\n * Container element ref\n */\n container: Ref<HTMLElement | null>;\n\n /**\n * Auto-initialize player on mount\n */\n autoInit?: boolean;\n}\n\nexport function useScarlettPlayer(options: UseScarlettPlayerOptions) {\n const player = ref<ScarlettPlayer | null>(null);\n const isReady = ref(false);\n const error = ref<Error | null>(null);\n\n // Reactive state\n const playing = ref(false);\n const paused = ref(true);\n const currentTime = ref(0);\n const duration = ref(0);\n const volume = ref(options.volume ?? 1);\n const muted = ref(options.muted ?? false);\n const bufferedAmount = ref(0);\n const fullscreen = ref(false);\n\n // Initialize player\n async function init() {\n if (!options.container.value) {\n error.value = new Error('Container element not found');\n return;\n }\n\n try {\n const { ScarlettPlayer: PlayerClass } = await import('@scarlett-player/core');\n\n const playerOptions: PlayerOptions = {\n container: options.container.value,\n src: options.src,\n poster: options.poster,\n autoplay: options.autoplay,\n loop: options.loop,\n volume: options.volume,\n muted: options.muted,\n logLevel: options.logLevel,\n plugins: options.plugins,\n };\n\n const instance = new PlayerClass(playerOptions);\n await instance.init();\n player.value = instance;\n\n // Setup state sync\n setupStateSync(instance);\n\n isReady.value = true;\n } catch (err) {\n error.value = err as Error;\n console.error('Failed to initialize Scarlett Player:', err);\n }\n }\n\n // Setup state synchronization\n function setupStateSync(playerInstance: ScarlettPlayer) {\n // Sync playback state\n playerInstance.on('playback:play', () => {\n playing.value = true;\n paused.value = false;\n });\n\n playerInstance.on('playback:pause', () => {\n playing.value = false;\n paused.value = true;\n });\n\n playerInstance.on('playback:timeupdate', (payload) => {\n currentTime.value = payload.currentTime;\n });\n\n // Sync volume state\n playerInstance.on('volume:change', (payload) => {\n volume.value = payload.volume;\n muted.value = payload.muted;\n });\n\n // Sync buffering state\n playerInstance.on('media:progress', (payload) => {\n bufferedAmount.value = payload.buffered;\n });\n\n // Sync fullscreen state\n playerInstance.on('fullscreen:change', (payload) => {\n fullscreen.value = payload.fullscreen;\n });\n\n // Sync media metadata\n playerInstance.on('media:loadedmetadata', (payload) => {\n duration.value = payload.duration ?? 0;\n });\n\n // Handle errors\n playerInstance.on('error', (err) => {\n error.value = err as unknown as Error;\n });\n }\n\n // Playback methods\n async function play() {\n if (player.value) {\n await player.value.play();\n }\n }\n\n function pause() {\n if (player.value) {\n player.value.pause();\n }\n }\n\n function seek(time: number) {\n if (player.value) {\n player.value.seek(time);\n }\n }\n\n async function load(src: string) {\n if (player.value) {\n await player.value.load(src);\n }\n }\n\n // Volume methods\n function setVolume(vol: number) {\n if (player.value) {\n player.value.setVolume(vol);\n }\n }\n\n function setMuted(mute: boolean) {\n if (player.value) {\n player.value.setMuted(mute);\n }\n }\n\n // Fullscreen methods\n async function requestFullscreen() {\n if (player.value) {\n await player.value.requestFullscreen();\n }\n }\n\n async function exitFullscreen() {\n if (player.value) {\n await player.value.exitFullscreen();\n }\n }\n\n async function toggleFullscreen() {\n if (player.value) {\n await player.value.toggleFullscreen();\n }\n }\n\n // Quality methods\n function getQualities() {\n return player.value?.getQualities() ?? [];\n }\n\n function setQuality(index: number) {\n if (player.value) {\n player.value.setQuality(index);\n }\n }\n\n function getCurrentQuality() {\n return player.value?.getCurrentQuality() ?? -1;\n }\n\n // Computed properties\n const progress = computed(() => {\n if (duration.value === 0) return 0;\n return (currentTime.value / duration.value) * 100;\n });\n\n const isBuffering = computed(() => {\n if (!player.value) return false;\n const state = player.value.getState();\n return state.buffering ?? false;\n });\n\n // Lifecycle\n onMounted(() => {\n if (options.autoInit !== false) {\n init();\n }\n });\n\n onBeforeUnmount(() => {\n if (player.value) {\n player.value.destroy();\n player.value = null;\n }\n });\n\n return {\n // Instance\n player,\n isReady,\n error,\n\n // State\n playing,\n paused,\n currentTime,\n duration,\n volume,\n muted,\n bufferedAmount,\n fullscreen,\n progress,\n isBuffering,\n\n // Methods\n init,\n play,\n pause,\n seek,\n load,\n setVolume,\n setMuted,\n requestFullscreen,\n exitFullscreen,\n toggleFullscreen,\n getQualities,\n setQuality,\n getCurrentQuality,\n };\n}\n"],"names":["props","__props","emit","__emit","containerRef","ref","playerInstance","onMounted","async","player","value","ScarlettPlayer","PlayerClass","import","playerOptions","container","src","poster","autoplay","loop","volume","muted","logLevel","plugins","options","init","on","payload","error","console","onBeforeUnmount","destroy","watch","newSrc","load","newVolume","setVolume","newMuted","setMuted","newAutoplay","setAutoplay","__expose","play","_a","pause","seek","time","setPlaybackRate","rate","getQualities","setQuality","index","getCurrentQuality","requestFullscreen","exitFullscreen","toggleFullscreen","requestAirPlay","requestChromecast","stopCasting","seekToLive","getState","getPlugin","name","registerPlugin","plugin","playing","paused","currentTime","duration","playbackRate","bufferedAmount","fullscreen","live","_createElementBlock","class","ScarlettPlayerPlugin","install","app","component","ScarlettPlayerComponent","isReady","instance","buffered","err","Error","progress","computed","isBuffering","buffering","autoInit","vol","mute"],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import { defineComponent, ref, onMounted, onBeforeUnmount, watch, createElementBlock, openBlock, computed } from "vue";
|
|
2
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
3
|
+
__name: "ScarlettPlayer",
|
|
4
|
+
props: {
|
|
5
|
+
/**
|
|
6
|
+
* Video source URL
|
|
7
|
+
*/
|
|
8
|
+
src: {
|
|
9
|
+
type: String,
|
|
10
|
+
required: false
|
|
11
|
+
},
|
|
12
|
+
/**
|
|
13
|
+
* Poster image URL
|
|
14
|
+
*/
|
|
15
|
+
poster: {
|
|
16
|
+
type: String,
|
|
17
|
+
required: false
|
|
18
|
+
},
|
|
19
|
+
/**
|
|
20
|
+
* Autoplay video
|
|
21
|
+
*/
|
|
22
|
+
autoplay: {
|
|
23
|
+
type: Boolean,
|
|
24
|
+
default: false
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Loop playback
|
|
28
|
+
*/
|
|
29
|
+
loop: {
|
|
30
|
+
type: Boolean,
|
|
31
|
+
default: false
|
|
32
|
+
},
|
|
33
|
+
/**
|
|
34
|
+
* Initial volume (0-1)
|
|
35
|
+
*/
|
|
36
|
+
volume: {
|
|
37
|
+
type: Number,
|
|
38
|
+
default: 1,
|
|
39
|
+
validator: (value) => value >= 0 && value <= 1
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* Start muted
|
|
43
|
+
*/
|
|
44
|
+
muted: {
|
|
45
|
+
type: Boolean,
|
|
46
|
+
default: false
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* Log level
|
|
50
|
+
*/
|
|
51
|
+
logLevel: {
|
|
52
|
+
type: String,
|
|
53
|
+
default: "warn"
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* Plugins to register
|
|
57
|
+
*/
|
|
58
|
+
plugins: {
|
|
59
|
+
type: Array,
|
|
60
|
+
default: () => []
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* Player options (overrides individual props)
|
|
64
|
+
*/
|
|
65
|
+
options: {
|
|
66
|
+
type: Object,
|
|
67
|
+
default: () => ({})
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
emits: ["ready", "play", "pause", "seeking", "seeked", "timeupdate", "volumechange", "ratechange", "ended", "error", "loaded", "loadedmetadata", "qualitychange", "qualitylevels", "fullscreenchange", "destroy"],
|
|
71
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
72
|
+
const props = __props;
|
|
73
|
+
const emit = __emit;
|
|
74
|
+
const containerRef = ref(null);
|
|
75
|
+
const playerInstance = ref(null);
|
|
76
|
+
onMounted(async () => {
|
|
77
|
+
if (!containerRef.value) {
|
|
78
|
+
console.error("ScarlettPlayer: Container ref not found");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const { ScarlettPlayer: PlayerClass } = await import("@scarlett-player/core");
|
|
83
|
+
const playerOptions = {
|
|
84
|
+
container: containerRef.value,
|
|
85
|
+
src: props.src,
|
|
86
|
+
poster: props.poster,
|
|
87
|
+
autoplay: props.autoplay,
|
|
88
|
+
loop: props.loop,
|
|
89
|
+
volume: props.volume,
|
|
90
|
+
muted: props.muted,
|
|
91
|
+
logLevel: props.logLevel,
|
|
92
|
+
plugins: props.plugins,
|
|
93
|
+
...props.options
|
|
94
|
+
// Allow options prop to override
|
|
95
|
+
};
|
|
96
|
+
playerInstance.value = new PlayerClass(playerOptions);
|
|
97
|
+
await playerInstance.value.init();
|
|
98
|
+
setupEventListeners(playerInstance.value);
|
|
99
|
+
emit("ready", playerInstance.value);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error("Failed to initialize ScarlettPlayer:", error);
|
|
102
|
+
emit("error", error);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
onBeforeUnmount(() => {
|
|
106
|
+
if (playerInstance.value) {
|
|
107
|
+
playerInstance.value.destroy();
|
|
108
|
+
playerInstance.value = null;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
watch(
|
|
112
|
+
() => props.src,
|
|
113
|
+
async (newSrc) => {
|
|
114
|
+
if (newSrc && playerInstance.value) {
|
|
115
|
+
await playerInstance.value.load(newSrc);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
watch(
|
|
120
|
+
() => props.volume,
|
|
121
|
+
(newVolume) => {
|
|
122
|
+
if (playerInstance.value) {
|
|
123
|
+
playerInstance.value.setVolume(newVolume);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
);
|
|
127
|
+
watch(
|
|
128
|
+
() => props.muted,
|
|
129
|
+
(newMuted) => {
|
|
130
|
+
if (playerInstance.value) {
|
|
131
|
+
playerInstance.value.setMuted(newMuted);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
watch(
|
|
136
|
+
() => props.autoplay,
|
|
137
|
+
(newAutoplay) => {
|
|
138
|
+
if (playerInstance.value) {
|
|
139
|
+
playerInstance.value.setAutoplay(newAutoplay);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
);
|
|
143
|
+
function setupEventListeners(player) {
|
|
144
|
+
player.on("player:ready", () => emit("ready", player));
|
|
145
|
+
player.on("player:destroy", () => emit("destroy"));
|
|
146
|
+
player.on("playback:play", () => emit("play"));
|
|
147
|
+
player.on("playback:pause", () => emit("pause"));
|
|
148
|
+
player.on("playback:seeking", (payload) => emit("seeking", payload));
|
|
149
|
+
player.on("playback:seeked", () => emit("seeked"));
|
|
150
|
+
player.on("playback:timeupdate", (payload) => emit("timeupdate", payload));
|
|
151
|
+
player.on("playback:ended", () => emit("ended"));
|
|
152
|
+
player.on("playback:ratechange", (payload) => emit("ratechange", payload));
|
|
153
|
+
player.on("media:loaded", (payload) => emit("loaded", payload));
|
|
154
|
+
player.on("media:loadedmetadata", (payload) => emit("loadedmetadata", payload));
|
|
155
|
+
player.on("volume:change", (payload) => emit("volumechange", payload));
|
|
156
|
+
player.on("quality:change", (payload) => emit("qualitychange", payload));
|
|
157
|
+
player.on("quality:levels", (payload) => emit("qualitylevels", payload));
|
|
158
|
+
player.on("fullscreen:change", (payload) => emit("fullscreenchange", payload));
|
|
159
|
+
player.on("error", (error) => emit("error", error));
|
|
160
|
+
}
|
|
161
|
+
__expose({
|
|
162
|
+
player: playerInstance,
|
|
163
|
+
// Playback methods
|
|
164
|
+
async play() {
|
|
165
|
+
var _a;
|
|
166
|
+
await ((_a = playerInstance.value) == null ? void 0 : _a.play());
|
|
167
|
+
},
|
|
168
|
+
pause() {
|
|
169
|
+
var _a;
|
|
170
|
+
(_a = playerInstance.value) == null ? void 0 : _a.pause();
|
|
171
|
+
},
|
|
172
|
+
seek(time) {
|
|
173
|
+
var _a;
|
|
174
|
+
(_a = playerInstance.value) == null ? void 0 : _a.seek(time);
|
|
175
|
+
},
|
|
176
|
+
// Volume methods
|
|
177
|
+
setVolume(volume) {
|
|
178
|
+
var _a;
|
|
179
|
+
(_a = playerInstance.value) == null ? void 0 : _a.setVolume(volume);
|
|
180
|
+
},
|
|
181
|
+
setMuted(muted) {
|
|
182
|
+
var _a;
|
|
183
|
+
(_a = playerInstance.value) == null ? void 0 : _a.setMuted(muted);
|
|
184
|
+
},
|
|
185
|
+
// Playback rate
|
|
186
|
+
setPlaybackRate(rate) {
|
|
187
|
+
var _a;
|
|
188
|
+
(_a = playerInstance.value) == null ? void 0 : _a.setPlaybackRate(rate);
|
|
189
|
+
},
|
|
190
|
+
// Quality methods
|
|
191
|
+
getQualities() {
|
|
192
|
+
var _a;
|
|
193
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.getQualities()) ?? [];
|
|
194
|
+
},
|
|
195
|
+
setQuality(index) {
|
|
196
|
+
var _a;
|
|
197
|
+
(_a = playerInstance.value) == null ? void 0 : _a.setQuality(index);
|
|
198
|
+
},
|
|
199
|
+
getCurrentQuality() {
|
|
200
|
+
var _a;
|
|
201
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.getCurrentQuality()) ?? -1;
|
|
202
|
+
},
|
|
203
|
+
// Fullscreen methods
|
|
204
|
+
async requestFullscreen() {
|
|
205
|
+
var _a;
|
|
206
|
+
await ((_a = playerInstance.value) == null ? void 0 : _a.requestFullscreen());
|
|
207
|
+
},
|
|
208
|
+
async exitFullscreen() {
|
|
209
|
+
var _a;
|
|
210
|
+
await ((_a = playerInstance.value) == null ? void 0 : _a.exitFullscreen());
|
|
211
|
+
},
|
|
212
|
+
async toggleFullscreen() {
|
|
213
|
+
var _a;
|
|
214
|
+
await ((_a = playerInstance.value) == null ? void 0 : _a.toggleFullscreen());
|
|
215
|
+
},
|
|
216
|
+
// Casting methods
|
|
217
|
+
requestAirPlay() {
|
|
218
|
+
var _a;
|
|
219
|
+
(_a = playerInstance.value) == null ? void 0 : _a.requestAirPlay();
|
|
220
|
+
},
|
|
221
|
+
async requestChromecast() {
|
|
222
|
+
var _a;
|
|
223
|
+
await ((_a = playerInstance.value) == null ? void 0 : _a.requestChromecast());
|
|
224
|
+
},
|
|
225
|
+
stopCasting() {
|
|
226
|
+
var _a;
|
|
227
|
+
(_a = playerInstance.value) == null ? void 0 : _a.stopCasting();
|
|
228
|
+
},
|
|
229
|
+
// Live stream methods
|
|
230
|
+
seekToLive() {
|
|
231
|
+
var _a;
|
|
232
|
+
(_a = playerInstance.value) == null ? void 0 : _a.seekToLive();
|
|
233
|
+
},
|
|
234
|
+
// State methods
|
|
235
|
+
getState() {
|
|
236
|
+
var _a;
|
|
237
|
+
return (_a = playerInstance.value) == null ? void 0 : _a.getState();
|
|
238
|
+
},
|
|
239
|
+
// Plugin methods
|
|
240
|
+
getPlugin(name) {
|
|
241
|
+
var _a;
|
|
242
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.getPlugin(name)) ?? null;
|
|
243
|
+
},
|
|
244
|
+
registerPlugin(plugin) {
|
|
245
|
+
var _a;
|
|
246
|
+
(_a = playerInstance.value) == null ? void 0 : _a.registerPlugin(plugin);
|
|
247
|
+
},
|
|
248
|
+
// Load source
|
|
249
|
+
async load(src) {
|
|
250
|
+
var _a;
|
|
251
|
+
await ((_a = playerInstance.value) == null ? void 0 : _a.load(src));
|
|
252
|
+
},
|
|
253
|
+
// Destroy
|
|
254
|
+
destroy() {
|
|
255
|
+
var _a;
|
|
256
|
+
(_a = playerInstance.value) == null ? void 0 : _a.destroy();
|
|
257
|
+
},
|
|
258
|
+
// State getters
|
|
259
|
+
get playing() {
|
|
260
|
+
var _a;
|
|
261
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.playing) ?? false;
|
|
262
|
+
},
|
|
263
|
+
get paused() {
|
|
264
|
+
var _a;
|
|
265
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.paused) ?? true;
|
|
266
|
+
},
|
|
267
|
+
get currentTime() {
|
|
268
|
+
var _a;
|
|
269
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.currentTime) ?? 0;
|
|
270
|
+
},
|
|
271
|
+
get duration() {
|
|
272
|
+
var _a;
|
|
273
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.duration) ?? 0;
|
|
274
|
+
},
|
|
275
|
+
get volume() {
|
|
276
|
+
var _a;
|
|
277
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.volume) ?? 1;
|
|
278
|
+
},
|
|
279
|
+
get muted() {
|
|
280
|
+
var _a;
|
|
281
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.muted) ?? false;
|
|
282
|
+
},
|
|
283
|
+
get playbackRate() {
|
|
284
|
+
var _a;
|
|
285
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.playbackRate) ?? 1;
|
|
286
|
+
},
|
|
287
|
+
get bufferedAmount() {
|
|
288
|
+
var _a;
|
|
289
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.bufferedAmount) ?? 0;
|
|
290
|
+
},
|
|
291
|
+
get fullscreen() {
|
|
292
|
+
var _a;
|
|
293
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.fullscreen) ?? false;
|
|
294
|
+
},
|
|
295
|
+
get live() {
|
|
296
|
+
var _a;
|
|
297
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.live) ?? false;
|
|
298
|
+
},
|
|
299
|
+
get autoplay() {
|
|
300
|
+
var _a;
|
|
301
|
+
return ((_a = playerInstance.value) == null ? void 0 : _a.autoplay) ?? false;
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
return (_ctx, _cache) => {
|
|
305
|
+
return openBlock(), createElementBlock("div", {
|
|
306
|
+
ref_key: "containerRef",
|
|
307
|
+
ref: containerRef,
|
|
308
|
+
class: "scarlett-player-container"
|
|
309
|
+
}, null, 512);
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
const _export_sfc = (sfc, props) => {
|
|
314
|
+
const target = sfc.__vccOpts || sfc;
|
|
315
|
+
for (const [key, val] of props) {
|
|
316
|
+
target[key] = val;
|
|
317
|
+
}
|
|
318
|
+
return target;
|
|
319
|
+
};
|
|
320
|
+
const ScarlettPlayerComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-5f43baa1"]]);
|
|
321
|
+
function useScarlettPlayer(options) {
|
|
322
|
+
const player = ref(null);
|
|
323
|
+
const isReady = ref(false);
|
|
324
|
+
const error = ref(null);
|
|
325
|
+
const playing = ref(false);
|
|
326
|
+
const paused = ref(true);
|
|
327
|
+
const currentTime = ref(0);
|
|
328
|
+
const duration = ref(0);
|
|
329
|
+
const volume = ref(options.volume ?? 1);
|
|
330
|
+
const muted = ref(options.muted ?? false);
|
|
331
|
+
const bufferedAmount = ref(0);
|
|
332
|
+
const fullscreen = ref(false);
|
|
333
|
+
async function init() {
|
|
334
|
+
if (!options.container.value) {
|
|
335
|
+
error.value = new Error("Container element not found");
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
try {
|
|
339
|
+
const { ScarlettPlayer: PlayerClass } = await import("@scarlett-player/core");
|
|
340
|
+
const playerOptions = {
|
|
341
|
+
container: options.container.value,
|
|
342
|
+
src: options.src,
|
|
343
|
+
poster: options.poster,
|
|
344
|
+
autoplay: options.autoplay,
|
|
345
|
+
loop: options.loop,
|
|
346
|
+
volume: options.volume,
|
|
347
|
+
muted: options.muted,
|
|
348
|
+
logLevel: options.logLevel,
|
|
349
|
+
plugins: options.plugins
|
|
350
|
+
};
|
|
351
|
+
const instance = new PlayerClass(playerOptions);
|
|
352
|
+
await instance.init();
|
|
353
|
+
player.value = instance;
|
|
354
|
+
setupStateSync(instance);
|
|
355
|
+
isReady.value = true;
|
|
356
|
+
} catch (err) {
|
|
357
|
+
error.value = err;
|
|
358
|
+
console.error("Failed to initialize Scarlett Player:", err);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
function setupStateSync(playerInstance) {
|
|
362
|
+
playerInstance.on("playback:play", () => {
|
|
363
|
+
playing.value = true;
|
|
364
|
+
paused.value = false;
|
|
365
|
+
});
|
|
366
|
+
playerInstance.on("playback:pause", () => {
|
|
367
|
+
playing.value = false;
|
|
368
|
+
paused.value = true;
|
|
369
|
+
});
|
|
370
|
+
playerInstance.on("playback:timeupdate", (payload) => {
|
|
371
|
+
currentTime.value = payload.currentTime;
|
|
372
|
+
});
|
|
373
|
+
playerInstance.on("volume:change", (payload) => {
|
|
374
|
+
volume.value = payload.volume;
|
|
375
|
+
muted.value = payload.muted;
|
|
376
|
+
});
|
|
377
|
+
playerInstance.on("media:progress", (payload) => {
|
|
378
|
+
bufferedAmount.value = payload.buffered;
|
|
379
|
+
});
|
|
380
|
+
playerInstance.on("fullscreen:change", (payload) => {
|
|
381
|
+
fullscreen.value = payload.fullscreen;
|
|
382
|
+
});
|
|
383
|
+
playerInstance.on("media:loadedmetadata", (payload) => {
|
|
384
|
+
duration.value = payload.duration ?? 0;
|
|
385
|
+
});
|
|
386
|
+
playerInstance.on("error", (err) => {
|
|
387
|
+
error.value = err;
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
async function play() {
|
|
391
|
+
if (player.value) {
|
|
392
|
+
await player.value.play();
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
function pause() {
|
|
396
|
+
if (player.value) {
|
|
397
|
+
player.value.pause();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
function seek(time) {
|
|
401
|
+
if (player.value) {
|
|
402
|
+
player.value.seek(time);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
async function load(src) {
|
|
406
|
+
if (player.value) {
|
|
407
|
+
await player.value.load(src);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function setVolume(vol) {
|
|
411
|
+
if (player.value) {
|
|
412
|
+
player.value.setVolume(vol);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
function setMuted(mute) {
|
|
416
|
+
if (player.value) {
|
|
417
|
+
player.value.setMuted(mute);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
async function requestFullscreen() {
|
|
421
|
+
if (player.value) {
|
|
422
|
+
await player.value.requestFullscreen();
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
async function exitFullscreen() {
|
|
426
|
+
if (player.value) {
|
|
427
|
+
await player.value.exitFullscreen();
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
async function toggleFullscreen() {
|
|
431
|
+
if (player.value) {
|
|
432
|
+
await player.value.toggleFullscreen();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
function getQualities() {
|
|
436
|
+
var _a;
|
|
437
|
+
return ((_a = player.value) == null ? void 0 : _a.getQualities()) ?? [];
|
|
438
|
+
}
|
|
439
|
+
function setQuality(index) {
|
|
440
|
+
if (player.value) {
|
|
441
|
+
player.value.setQuality(index);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
function getCurrentQuality() {
|
|
445
|
+
var _a;
|
|
446
|
+
return ((_a = player.value) == null ? void 0 : _a.getCurrentQuality()) ?? -1;
|
|
447
|
+
}
|
|
448
|
+
const progress = computed(() => {
|
|
449
|
+
if (duration.value === 0) return 0;
|
|
450
|
+
return currentTime.value / duration.value * 100;
|
|
451
|
+
});
|
|
452
|
+
const isBuffering = computed(() => {
|
|
453
|
+
if (!player.value) return false;
|
|
454
|
+
const state = player.value.getState();
|
|
455
|
+
return state.buffering ?? false;
|
|
456
|
+
});
|
|
457
|
+
onMounted(() => {
|
|
458
|
+
if (options.autoInit !== false) {
|
|
459
|
+
init();
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
onBeforeUnmount(() => {
|
|
463
|
+
if (player.value) {
|
|
464
|
+
player.value.destroy();
|
|
465
|
+
player.value = null;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
return {
|
|
469
|
+
// Instance
|
|
470
|
+
player,
|
|
471
|
+
isReady,
|
|
472
|
+
error,
|
|
473
|
+
// State
|
|
474
|
+
playing,
|
|
475
|
+
paused,
|
|
476
|
+
currentTime,
|
|
477
|
+
duration,
|
|
478
|
+
volume,
|
|
479
|
+
muted,
|
|
480
|
+
bufferedAmount,
|
|
481
|
+
fullscreen,
|
|
482
|
+
progress,
|
|
483
|
+
isBuffering,
|
|
484
|
+
// Methods
|
|
485
|
+
init,
|
|
486
|
+
play,
|
|
487
|
+
pause,
|
|
488
|
+
seek,
|
|
489
|
+
load,
|
|
490
|
+
setVolume,
|
|
491
|
+
setMuted,
|
|
492
|
+
requestFullscreen,
|
|
493
|
+
exitFullscreen,
|
|
494
|
+
toggleFullscreen,
|
|
495
|
+
getQualities,
|
|
496
|
+
setQuality,
|
|
497
|
+
getCurrentQuality
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
const ScarlettPlayerPlugin = {
|
|
501
|
+
install(app) {
|
|
502
|
+
app.component("ScarlettPlayer", ScarlettPlayerComponent);
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
export {
|
|
506
|
+
ScarlettPlayerComponent,
|
|
507
|
+
ScarlettPlayerPlugin,
|
|
508
|
+
ScarlettPlayerComponent as default,
|
|
509
|
+
useScarlettPlayer
|
|
510
|
+
};
|
|
511
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/ScarlettPlayer.vue","../src/composables/useScarlettPlayer.ts","../src/index.ts"],"sourcesContent":["<template>\n <div ref=\"containerRef\" class=\"scarlett-player-container\"></div>\n</template>\n\n<script setup lang=\"ts\">\nimport {\n ref,\n onMounted,\n onBeforeUnmount,\n watch,\n type PropType,\n defineExpose,\n} from 'vue';\nimport type { ScarlettPlayer, PlayerOptions, Plugin } from '@scarlett-player/core';\n\n// Props\nconst props = defineProps({\n /**\n * Video source URL\n */\n src: {\n type: String,\n required: false,\n },\n /**\n * Poster image URL\n */\n poster: {\n type: String,\n required: false,\n },\n /**\n * Autoplay video\n */\n autoplay: {\n type: Boolean,\n default: false,\n },\n /**\n * Loop playback\n */\n loop: {\n type: Boolean,\n default: false,\n },\n /**\n * Initial volume (0-1)\n */\n volume: {\n type: Number,\n default: 1.0,\n validator: (value: number) => value >= 0 && value <= 1,\n },\n /**\n * Start muted\n */\n muted: {\n type: Boolean,\n default: false,\n },\n /**\n * Log level\n */\n logLevel: {\n type: String as PropType<'debug' | 'info' | 'warn' | 'error'>,\n default: 'warn',\n },\n /**\n * Plugins to register\n */\n plugins: {\n type: Array as PropType<Plugin[]>,\n default: () => [],\n },\n /**\n * Player options (overrides individual props)\n */\n options: {\n type: Object as PropType<Partial<PlayerOptions>>,\n default: () => ({}),\n },\n});\n\n// Emits\nconst emit = defineEmits<{\n ready: [player: ScarlettPlayer];\n play: [];\n pause: [];\n seeking: [payload: { time: number }];\n seeked: [];\n timeupdate: [payload: { currentTime: number; duration: number }];\n volumechange: [payload: { volume: number; muted: boolean }];\n ratechange: [payload: { rate: number }];\n ended: [];\n error: [error: any];\n loaded: [payload: any];\n loadedmetadata: [payload: any];\n qualitychange: [payload: { quality: string; auto: boolean }];\n qualitylevels: [payload: any];\n fullscreenchange: [payload: { fullscreen: boolean }];\n destroy: [];\n}>();\n\n// Refs\nconst containerRef = ref<HTMLElement | null>(null);\nconst playerInstance = ref<ScarlettPlayer | null>(null);\n\n// Lifecycle\nonMounted(async () => {\n if (!containerRef.value) {\n console.error('ScarlettPlayer: Container ref not found');\n return;\n }\n\n try {\n // Import ScarlettPlayer dynamically to avoid SSR issues\n const { ScarlettPlayer: PlayerClass } = await import('@scarlett-player/core');\n\n // Merge props into options\n const playerOptions: PlayerOptions = {\n container: containerRef.value,\n src: props.src,\n poster: props.poster,\n autoplay: props.autoplay,\n loop: props.loop,\n volume: props.volume,\n muted: props.muted,\n logLevel: props.logLevel,\n plugins: props.plugins,\n ...props.options, // Allow options prop to override\n };\n\n // Create player instance\n playerInstance.value = new PlayerClass(playerOptions);\n\n // Initialize player\n await playerInstance.value.init();\n\n // Set up event listeners\n setupEventListeners(playerInstance.value);\n\n // Emit ready event\n emit('ready', playerInstance.value);\n } catch (error) {\n console.error('Failed to initialize ScarlettPlayer:', error);\n emit('error', error);\n }\n});\n\nonBeforeUnmount(() => {\n if (playerInstance.value) {\n playerInstance.value.destroy();\n playerInstance.value = null;\n }\n});\n\n// Watch for src changes\nwatch(\n () => props.src,\n async (newSrc) => {\n if (newSrc && playerInstance.value) {\n await playerInstance.value.load(newSrc);\n }\n }\n);\n\n// Watch for volume changes\nwatch(\n () => props.volume,\n (newVolume) => {\n if (playerInstance.value) {\n playerInstance.value.setVolume(newVolume);\n }\n }\n);\n\n// Watch for muted changes\nwatch(\n () => props.muted,\n (newMuted) => {\n if (playerInstance.value) {\n playerInstance.value.setMuted(newMuted);\n }\n }\n);\n\n// Watch for autoplay changes\nwatch(\n () => props.autoplay,\n (newAutoplay) => {\n if (playerInstance.value) {\n playerInstance.value.setAutoplay(newAutoplay);\n }\n }\n);\n\n// Event listeners setup\nfunction setupEventListeners(player: ScarlettPlayer) {\n // Player events\n player.on('player:ready', () => emit('ready', player));\n player.on('player:destroy', () => emit('destroy'));\n\n // Playback events\n player.on('playback:play', () => emit('play'));\n player.on('playback:pause', () => emit('pause'));\n player.on('playback:seeking', (payload) => emit('seeking', payload));\n player.on('playback:seeked', () => emit('seeked'));\n player.on('playback:timeupdate', (payload) => emit('timeupdate', payload));\n player.on('playback:ended', () => emit('ended'));\n player.on('playback:ratechange', (payload) => emit('ratechange', payload));\n\n // Media events\n player.on('media:loaded', (payload) => emit('loaded', payload));\n player.on('media:loadedmetadata', (payload) => emit('loadedmetadata', payload));\n\n // Volume events\n player.on('volume:change', (payload) => emit('volumechange', payload));\n\n // Quality events\n player.on('quality:change', (payload) => emit('qualitychange', payload));\n player.on('quality:levels', (payload) => emit('qualitylevels', payload));\n\n // Fullscreen events\n player.on('fullscreen:change', (payload) => emit('fullscreenchange', payload));\n\n // Error events\n player.on('error', (error) => emit('error', error));\n}\n\n// Public API (exposed to parent component via ref)\ndefineExpose({\n player: playerInstance,\n\n // Playback methods\n async play() {\n await playerInstance.value?.play();\n },\n pause() {\n playerInstance.value?.pause();\n },\n seek(time: number) {\n playerInstance.value?.seek(time);\n },\n\n // Volume methods\n setVolume(volume: number) {\n playerInstance.value?.setVolume(volume);\n },\n setMuted(muted: boolean) {\n playerInstance.value?.setMuted(muted);\n },\n\n // Playback rate\n setPlaybackRate(rate: number) {\n playerInstance.value?.setPlaybackRate(rate);\n },\n\n // Quality methods\n getQualities() {\n return playerInstance.value?.getQualities() ?? [];\n },\n setQuality(index: number) {\n playerInstance.value?.setQuality(index);\n },\n getCurrentQuality() {\n return playerInstance.value?.getCurrentQuality() ?? -1;\n },\n\n // Fullscreen methods\n async requestFullscreen() {\n await playerInstance.value?.requestFullscreen();\n },\n async exitFullscreen() {\n await playerInstance.value?.exitFullscreen();\n },\n async toggleFullscreen() {\n await playerInstance.value?.toggleFullscreen();\n },\n\n // Casting methods\n requestAirPlay() {\n playerInstance.value?.requestAirPlay();\n },\n async requestChromecast() {\n await playerInstance.value?.requestChromecast();\n },\n stopCasting() {\n playerInstance.value?.stopCasting();\n },\n\n // Live stream methods\n seekToLive() {\n playerInstance.value?.seekToLive();\n },\n\n // State methods\n getState() {\n return playerInstance.value?.getState();\n },\n\n // Plugin methods\n getPlugin<T>(name: string) {\n return playerInstance.value?.getPlugin<T>(name) ?? null;\n },\n registerPlugin(plugin: Plugin) {\n playerInstance.value?.registerPlugin(plugin);\n },\n\n // Load source\n async load(src: string) {\n await playerInstance.value?.load(src);\n },\n\n // Destroy\n destroy() {\n playerInstance.value?.destroy();\n },\n\n // State getters\n get playing() {\n return playerInstance.value?.playing ?? false;\n },\n get paused() {\n return playerInstance.value?.paused ?? true;\n },\n get currentTime() {\n return playerInstance.value?.currentTime ?? 0;\n },\n get duration() {\n return playerInstance.value?.duration ?? 0;\n },\n get volume() {\n return playerInstance.value?.volume ?? 1;\n },\n get muted() {\n return playerInstance.value?.muted ?? false;\n },\n get playbackRate() {\n return playerInstance.value?.playbackRate ?? 1;\n },\n get bufferedAmount() {\n return playerInstance.value?.bufferedAmount ?? 0;\n },\n get fullscreen() {\n return playerInstance.value?.fullscreen ?? false;\n },\n get live() {\n return playerInstance.value?.live ?? false;\n },\n get autoplay() {\n return playerInstance.value?.autoplay ?? false;\n },\n});\n</script>\n\n<style scoped>\n.scarlett-player-container {\n width: 100%;\n height: 100%;\n position: relative;\n}\n</style>\n","/**\n * Composable for using Scarlett Player in Vue 3\n *\n * Provides a reactive API for controlling the player programmatically.\n */\n\nimport { ref, onMounted, onBeforeUnmount, computed, type Ref } from 'vue';\nimport type { ScarlettPlayer, PlayerOptions } from '@scarlett-player/core';\n\nexport interface UseScarlettPlayerOptions extends Omit<PlayerOptions, 'container'> {\n /**\n * Container element ref\n */\n container: Ref<HTMLElement | null>;\n\n /**\n * Auto-initialize player on mount\n */\n autoInit?: boolean;\n}\n\nexport function useScarlettPlayer(options: UseScarlettPlayerOptions) {\n const player = ref<ScarlettPlayer | null>(null);\n const isReady = ref(false);\n const error = ref<Error | null>(null);\n\n // Reactive state\n const playing = ref(false);\n const paused = ref(true);\n const currentTime = ref(0);\n const duration = ref(0);\n const volume = ref(options.volume ?? 1);\n const muted = ref(options.muted ?? false);\n const bufferedAmount = ref(0);\n const fullscreen = ref(false);\n\n // Initialize player\n async function init() {\n if (!options.container.value) {\n error.value = new Error('Container element not found');\n return;\n }\n\n try {\n const { ScarlettPlayer: PlayerClass } = await import('@scarlett-player/core');\n\n const playerOptions: PlayerOptions = {\n container: options.container.value,\n src: options.src,\n poster: options.poster,\n autoplay: options.autoplay,\n loop: options.loop,\n volume: options.volume,\n muted: options.muted,\n logLevel: options.logLevel,\n plugins: options.plugins,\n };\n\n const instance = new PlayerClass(playerOptions);\n await instance.init();\n player.value = instance;\n\n // Setup state sync\n setupStateSync(instance);\n\n isReady.value = true;\n } catch (err) {\n error.value = err as Error;\n console.error('Failed to initialize Scarlett Player:', err);\n }\n }\n\n // Setup state synchronization\n function setupStateSync(playerInstance: ScarlettPlayer) {\n // Sync playback state\n playerInstance.on('playback:play', () => {\n playing.value = true;\n paused.value = false;\n });\n\n playerInstance.on('playback:pause', () => {\n playing.value = false;\n paused.value = true;\n });\n\n playerInstance.on('playback:timeupdate', (payload) => {\n currentTime.value = payload.currentTime;\n });\n\n // Sync volume state\n playerInstance.on('volume:change', (payload) => {\n volume.value = payload.volume;\n muted.value = payload.muted;\n });\n\n // Sync buffering state\n playerInstance.on('media:progress', (payload) => {\n bufferedAmount.value = payload.buffered;\n });\n\n // Sync fullscreen state\n playerInstance.on('fullscreen:change', (payload) => {\n fullscreen.value = payload.fullscreen;\n });\n\n // Sync media metadata\n playerInstance.on('media:loadedmetadata', (payload) => {\n duration.value = payload.duration ?? 0;\n });\n\n // Handle errors\n playerInstance.on('error', (err) => {\n error.value = err as unknown as Error;\n });\n }\n\n // Playback methods\n async function play() {\n if (player.value) {\n await player.value.play();\n }\n }\n\n function pause() {\n if (player.value) {\n player.value.pause();\n }\n }\n\n function seek(time: number) {\n if (player.value) {\n player.value.seek(time);\n }\n }\n\n async function load(src: string) {\n if (player.value) {\n await player.value.load(src);\n }\n }\n\n // Volume methods\n function setVolume(vol: number) {\n if (player.value) {\n player.value.setVolume(vol);\n }\n }\n\n function setMuted(mute: boolean) {\n if (player.value) {\n player.value.setMuted(mute);\n }\n }\n\n // Fullscreen methods\n async function requestFullscreen() {\n if (player.value) {\n await player.value.requestFullscreen();\n }\n }\n\n async function exitFullscreen() {\n if (player.value) {\n await player.value.exitFullscreen();\n }\n }\n\n async function toggleFullscreen() {\n if (player.value) {\n await player.value.toggleFullscreen();\n }\n }\n\n // Quality methods\n function getQualities() {\n return player.value?.getQualities() ?? [];\n }\n\n function setQuality(index: number) {\n if (player.value) {\n player.value.setQuality(index);\n }\n }\n\n function getCurrentQuality() {\n return player.value?.getCurrentQuality() ?? -1;\n }\n\n // Computed properties\n const progress = computed(() => {\n if (duration.value === 0) return 0;\n return (currentTime.value / duration.value) * 100;\n });\n\n const isBuffering = computed(() => {\n if (!player.value) return false;\n const state = player.value.getState();\n return state.buffering ?? false;\n });\n\n // Lifecycle\n onMounted(() => {\n if (options.autoInit !== false) {\n init();\n }\n });\n\n onBeforeUnmount(() => {\n if (player.value) {\n player.value.destroy();\n player.value = null;\n }\n });\n\n return {\n // Instance\n player,\n isReady,\n error,\n\n // State\n playing,\n paused,\n currentTime,\n duration,\n volume,\n muted,\n bufferedAmount,\n fullscreen,\n progress,\n isBuffering,\n\n // Methods\n init,\n play,\n pause,\n seek,\n load,\n setVolume,\n setMuted,\n requestFullscreen,\n exitFullscreen,\n toggleFullscreen,\n getQualities,\n setQuality,\n getCurrentQuality,\n };\n}\n","/**\n * @scarlett-player/vue - Vue 3 component wrapper for Scarlett Player\n *\n * Provides a Vue 3 component that wraps the Scarlett Player core.\n * Supports Composition API, TypeScript, and reactive props.\n *\n * @packageDocumentation\n */\n\nimport ScarlettPlayerComponent from './ScarlettPlayer.vue';\nimport type { App, Plugin } from 'vue';\n\n// Export the component\nexport { ScarlettPlayerComponent };\nexport default ScarlettPlayerComponent;\n\n// Export composables\nexport { useScarlettPlayer } from './composables/useScarlettPlayer';\n\n// Re-export core types for convenience\nexport type {\n ScarlettPlayer,\n PlayerOptions,\n QualityLevel,\n Plugin as ScarlettPlugin,\n PluginType,\n EventName,\n EventPayload,\n StateStore,\n PlaybackState,\n MediaType,\n} from '@scarlett-player/core';\n\n// Vue plugin installation (optional)\nexport const ScarlettPlayerPlugin: Plugin = {\n install(app: App) {\n app.component('ScarlettPlayer', ScarlettPlayerComponent);\n },\n};\n"],"names":["_createElementBlock"],"mappings":"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"}
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.scarlett-player-container[data-v-5f43baa1]{width:100%;height:100%;position:relative}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@scarlett-player/vue",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vue 3 component wrapper for Scarlett Player",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc && vite build",
|
|
21
|
+
"test": "vitest --run",
|
|
22
|
+
"test:watch": "vitest",
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"clean": "rimraf dist"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"video",
|
|
28
|
+
"player",
|
|
29
|
+
"vue",
|
|
30
|
+
"vue3",
|
|
31
|
+
"composition-api",
|
|
32
|
+
"scarlett",
|
|
33
|
+
"hls",
|
|
34
|
+
"streaming"
|
|
35
|
+
],
|
|
36
|
+
"author": "The Stream Platform",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/Hackney-Enterprises-Inc/scarlett-player.git",
|
|
41
|
+
"directory": "packages/vue"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/Hackney-Enterprises-Inc/scarlett-player/issues"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/Hackney-Enterprises-Inc/scarlett-player#readme",
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@scarlett-player/core": "^0.1.0",
|
|
49
|
+
"vue": "^3.3.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^20.0.0",
|
|
53
|
+
"@vitejs/plugin-vue": "^4.5.0",
|
|
54
|
+
"rimraf": "^5.0.5",
|
|
55
|
+
"typescript": "^5.3.3",
|
|
56
|
+
"vite": "^5.0.11",
|
|
57
|
+
"vitest": "^1.1.0",
|
|
58
|
+
"vue": "^3.3.0"
|
|
59
|
+
}
|
|
60
|
+
}
|