@viostream/viostream-player-svelte 0.1.2 → 0.2.1
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 +414 -456
- package/dist/ViostreamPlayer.svelte +232 -222
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,456 +1,414 @@
|
|
|
1
|
-
# viostream-player-svelte
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
|
75
|
-
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
| `
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
|
87
|
-
|
|
88
|
-
| `
|
|
89
|
-
| `
|
|
90
|
-
| `
|
|
91
|
-
| `
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
|
96
|
-
|
|
97
|
-
| `
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
|
102
|
-
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
player.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const
|
|
226
|
-
player.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
player.
|
|
236
|
-
{
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
<div>
|
|
417
|
-
<button onclick={async () => {
|
|
418
|
-
const vol = await player?.getVolume();
|
|
419
|
-
log = [`volume: ${vol}`, ...log];
|
|
420
|
-
}}>Get Volume</button>
|
|
421
|
-
<button onclick={async () => {
|
|
422
|
-
const tracks = await player?.getTracks();
|
|
423
|
-
log = [`tracks: ${JSON.stringify(tracks)}`, ...log];
|
|
424
|
-
}}>Get Tracks</button>
|
|
425
|
-
</div>
|
|
426
|
-
|
|
427
|
-
<pre>{log.join('\n')}</pre>
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
---
|
|
431
|
-
|
|
432
|
-
## Development
|
|
433
|
-
|
|
434
|
-
```bash
|
|
435
|
-
# Install dependencies
|
|
436
|
-
npm install
|
|
437
|
-
|
|
438
|
-
# Start the dev server (serves the demo page)
|
|
439
|
-
npm run dev
|
|
440
|
-
|
|
441
|
-
# Type-check
|
|
442
|
-
npm run check
|
|
443
|
-
|
|
444
|
-
# Run tests
|
|
445
|
-
npm run test
|
|
446
|
-
|
|
447
|
-
# Run tests in watch mode
|
|
448
|
-
npm run test:watch
|
|
449
|
-
|
|
450
|
-
# Build the library for publishing
|
|
451
|
-
npm run package
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
## License
|
|
455
|
-
|
|
456
|
-
MIT
|
|
1
|
+
# viostream-player-svelte
|
|
2
|
+
|
|
3
|
+
<a href="https://www.npmjs.com/package/@viostream/viostream-player-svelte"><img src="https://img.shields.io/npm/v/@viostream/viostream-player-svelte.svg?sanitize=true" alt="npm version"></a>
|
|
4
|
+
<a href="https://www.npmjs.com/package/@viostream/viostream-player-svelte"><img src="https://img.shields.io/npm/l/@viostream/viostream-player-svelte.svg?sanitize=true" alt="License"></a>
|
|
5
|
+
<a href="https://npmcharts.com/compare/@viostream/viostream-player-svelte?interval=30"><img src="https://img.shields.io/npm/dm/@viostream/viostream-player-svelte.svg?sanitize=true" alt="Downloads"></a>
|
|
6
|
+
|
|
7
|
+
Svelte 5 SDK for the [Viostream](https://www.viostream.com) video player. Embed, control, and listen to player events with full TypeScript support.
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- Svelte 5
|
|
12
|
+
- A Viostream account key (found on the **Settings > General** page in Viostream)
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install viostream-player-svelte
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Component
|
|
23
|
+
|
|
24
|
+
Drop a `<ViostreamPlayer>` into any Svelte component. The SDK loads the Viostream script automatically.
|
|
25
|
+
|
|
26
|
+
```svelte
|
|
27
|
+
<script lang="ts">
|
|
28
|
+
import { ViostreamPlayer } from 'viostream-player-svelte';
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<ViostreamPlayer
|
|
32
|
+
accountKey="vc-100100100"
|
|
33
|
+
publicKey="nhedxonrxsyfee"
|
|
34
|
+
displayTitle={true}
|
|
35
|
+
sharing={true}
|
|
36
|
+
onplay={() => console.log('playing')}
|
|
37
|
+
/>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Headless / Programmatic
|
|
41
|
+
|
|
42
|
+
Use `createViostreamPlayer` when you need full control without a component:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import { createViostreamPlayer } from 'viostream-player-svelte';
|
|
46
|
+
|
|
47
|
+
const player = await createViostreamPlayer({
|
|
48
|
+
accountKey: 'vc-100100100',
|
|
49
|
+
publicKey: 'nhedxonrxsyfee',
|
|
50
|
+
target: 'my-video-div', // element id or HTMLElement
|
|
51
|
+
options: { displayTitle: true }
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
player.play();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## `<ViostreamPlayer>` Component
|
|
60
|
+
|
|
61
|
+
### Props
|
|
62
|
+
|
|
63
|
+
#### Required
|
|
64
|
+
|
|
65
|
+
| Prop | Type | Description |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| `accountKey` | `string` | Your Viostream account key (e.g. `'vc-100100100'`). |
|
|
68
|
+
| `publicKey` | `string` | The public key of the media asset to embed. |
|
|
69
|
+
|
|
70
|
+
#### Embed Options
|
|
71
|
+
|
|
72
|
+
All embed options are optional and passed directly to the Viostream embed API.
|
|
73
|
+
|
|
74
|
+
| Prop | Type | Description |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `chapters` | `boolean` | Display chapter markers. |
|
|
77
|
+
| `chapterSlug` | `string` | Seek to a named chapter before playback. |
|
|
78
|
+
| `displayTitle` | `boolean` | Show the video title overlay. Default: `false`. |
|
|
79
|
+
| `hlsQualitySelector` | `boolean` | Show the HLS quality selector. Default: `true`. |
|
|
80
|
+
| `playerKey` | `string` | Override the player theme to use. |
|
|
81
|
+
| `playerStyle` | `'video' \| 'audio' \| 'audio-poster'` | The player rendering style. Default: `'video'`. |
|
|
82
|
+
| `sharing` | `boolean` | Show sharing controls. Default: `false`. |
|
|
83
|
+
| `skinActive` | `string` | Custom skin active colour (e.g. `'#ff0000'`). Requires `skinCustom: true`. |
|
|
84
|
+
| `skinBackground` | `string` | Custom skin background colour (e.g. `'#000000'`). Requires `skinCustom: true`. |
|
|
85
|
+
| `skinCustom` | `boolean` | Enable a custom skin via the API. Default: `false`. |
|
|
86
|
+
| `skinInactive` | `string` | Custom skin inactive colour (e.g. `'#cccccc'`). Requires `skinCustom: true`. |
|
|
87
|
+
| `speedSelector` | `boolean` | Show playback speed selector. Default: `true`. |
|
|
88
|
+
| `startEndTimespan` | `string` | Play a specific section (e.g. `'10,30'`). |
|
|
89
|
+
| `startTime` | `string` | Seek to a time (seconds) before playback. |
|
|
90
|
+
| `transcriptDownload` | `boolean` | Allow transcript download. Default: `false`. |
|
|
91
|
+
| `useSettingsMenu` | `boolean` | Enable the settings menu on the control bar. Default: `false`. |
|
|
92
|
+
|
|
93
|
+
#### Event Callbacks
|
|
94
|
+
|
|
95
|
+
| Prop | Signature | Fires when |
|
|
96
|
+
|---|---|---|
|
|
97
|
+
| `onplay` | `() => void` | Playback starts or resumes. |
|
|
98
|
+
| `onpause` | `() => void` | Playback is paused. |
|
|
99
|
+
| `onended` | `() => void` | Media finishes playing. |
|
|
100
|
+
| `ontimeupdate` | `(data: ViostreamTimeUpdateData) => void` | Current time changes. `data.seconds`, `data.duration`. |
|
|
101
|
+
| `onvolumechange` | `(data: ViostreamVolumeChangeData) => void` | Volume changes. `data.volume`. |
|
|
102
|
+
| `onerror` | `(data: ViostreamErrorData) => void` | An error occurs. `data.code`, `data.message`. |
|
|
103
|
+
| `onprogress` | `(data: ViostreamProgressData) => void` | Buffering progress. `data.percent`. |
|
|
104
|
+
| `onready` | `() => void` | Player is ready. |
|
|
105
|
+
| `onseeked` | `() => void` | Seek operation completes. |
|
|
106
|
+
| `onloaded` | `() => void` | Metadata has loaded. |
|
|
107
|
+
|
|
108
|
+
#### Other Props
|
|
109
|
+
|
|
110
|
+
| Prop | Type | Description |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| `class` | `string` | CSS class applied to the outer wrapper `<div>`. |
|
|
113
|
+
| `onplayerready` | `(player: ViostreamPlayerInstance) => void` | Callback providing the player instance for programmatic control. |
|
|
114
|
+
| `loading` | `Snippet` | Optional Svelte 5 snippet rendered while the player is loading. |
|
|
115
|
+
| `error` | `Snippet<[string]>` | Optional snippet rendered on error. Receives the error message as an argument. |
|
|
116
|
+
|
|
117
|
+
### Getting the Player Instance
|
|
118
|
+
|
|
119
|
+
Use `onplayerready` to get a reference to the player for programmatic control:
|
|
120
|
+
|
|
121
|
+
```svelte
|
|
122
|
+
<script lang="ts">
|
|
123
|
+
import { ViostreamPlayer } from 'viostream-player-svelte';
|
|
124
|
+
import type { ViostreamPlayerInstance } from 'viostream-player-svelte';
|
|
125
|
+
|
|
126
|
+
let player: ViostreamPlayerInstance | undefined = $state();
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<ViostreamPlayer
|
|
130
|
+
accountKey="vc-100100100"
|
|
131
|
+
publicKey="nhedxonrxsyfee"
|
|
132
|
+
onplayerready={(p) => (player = p)}
|
|
133
|
+
/>
|
|
134
|
+
|
|
135
|
+
<button onclick={() => player?.play()}>Play</button>
|
|
136
|
+
<button onclick={() => player?.pause()}>Pause</button>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Custom Loading and Error States
|
|
140
|
+
|
|
141
|
+
Use Svelte 5 snippets to replace the default loading/error UI:
|
|
142
|
+
|
|
143
|
+
```svelte
|
|
144
|
+
<ViostreamPlayer
|
|
145
|
+
accountKey="vc-100100100"
|
|
146
|
+
publicKey="nhedxonrxsyfee"
|
|
147
|
+
>
|
|
148
|
+
{#snippet loading()}
|
|
149
|
+
<p>Loading video...</p>
|
|
150
|
+
{/snippet}
|
|
151
|
+
|
|
152
|
+
{#snippet error(message)}
|
|
153
|
+
<div class="my-error">Something went wrong: {message}</div>
|
|
154
|
+
{/snippet}
|
|
155
|
+
</ViostreamPlayer>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Cleanup
|
|
159
|
+
|
|
160
|
+
The player is destroyed automatically when the component unmounts. All event listeners are cleaned up and the player iframe is removed from the DOM.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## `createViostreamPlayer()`
|
|
165
|
+
|
|
166
|
+
For use outside of Svelte components or when you need full lifecycle control.
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
import { createViostreamPlayer } from 'viostream-player-svelte';
|
|
170
|
+
import type { CreateViostreamPlayerOptions } from 'viostream-player-svelte';
|
|
171
|
+
|
|
172
|
+
const player = await createViostreamPlayer({
|
|
173
|
+
accountKey: 'vc-100100100',
|
|
174
|
+
publicKey: 'nhedxonrxsyfee',
|
|
175
|
+
target: 'my-video-div', // element id (string) or HTMLElement
|
|
176
|
+
options: {
|
|
177
|
+
displayTitle: true,
|
|
178
|
+
sharing: true,
|
|
179
|
+
speedSelector: true
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Options
|
|
185
|
+
|
|
186
|
+
| Property | Type | Description |
|
|
187
|
+
|---|---|---|
|
|
188
|
+
| `accountKey` | `string` | Your Viostream account key. |
|
|
189
|
+
| `publicKey` | `string` | Public key of the media asset. |
|
|
190
|
+
| `target` | `string \| HTMLElement` | Container element id or direct DOM reference. |
|
|
191
|
+
| `options` | `ViostreamEmbedOptions` | Embed options (same as component props above). |
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## Player Instance API
|
|
196
|
+
|
|
197
|
+
Both the component (via `onplayerready`) and `createViostreamPlayer()` provide a `ViostreamPlayerInstance` with the following methods.
|
|
198
|
+
|
|
199
|
+
### Playback Controls
|
|
200
|
+
|
|
201
|
+
```ts
|
|
202
|
+
player.play();
|
|
203
|
+
player.pause();
|
|
204
|
+
player.mute();
|
|
205
|
+
player.unmute();
|
|
206
|
+
player.setVolume(0.5); // 0 to 1
|
|
207
|
+
player.setLoop(true);
|
|
208
|
+
player.setCurrentTime(30); // seek to 30 seconds
|
|
209
|
+
player.setCurrentTime(30, true); // seek and auto-play
|
|
210
|
+
player.reload(); // reload the player
|
|
211
|
+
player.reload({ key: 'value' }); // reload with new settings
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Getters (Promise-based)
|
|
215
|
+
|
|
216
|
+
All getters return promises. The SDK converts the underlying callback-based API to `async`/`await`.
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
const volume = await player.getVolume(); // number (0–1)
|
|
220
|
+
const loop = await player.getLoop(); // boolean
|
|
221
|
+
const time = await player.getCurrentTime(); // number (seconds)
|
|
222
|
+
const paused = await player.getPaused(); // boolean
|
|
223
|
+
const duration = await player.getDuration(); // number (seconds)
|
|
224
|
+
const muted = await player.getMuted(); // boolean
|
|
225
|
+
const ratio = await player.getAspectRatio(); // number
|
|
226
|
+
const height = await player.getHeight(); // number (pixels)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Events
|
|
230
|
+
|
|
231
|
+
Subscribe to player events with `on()`. It returns an unsubscribe function.
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
// Subscribe
|
|
235
|
+
const unsubscribe = player.on('timeupdate', (data) => {
|
|
236
|
+
console.log(`${data.seconds}s / ${data.duration}s`);
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
// Unsubscribe later
|
|
240
|
+
unsubscribe();
|
|
241
|
+
|
|
242
|
+
// Or use off() directly
|
|
243
|
+
const handler = () => console.log('paused');
|
|
244
|
+
player.on('pause', handler);
|
|
245
|
+
player.off('pause', handler);
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### Available Events
|
|
249
|
+
|
|
250
|
+
| Event | Callback Data | Description |
|
|
251
|
+
|---|---|---|
|
|
252
|
+
| `play` | `void` | Playback started or resumed. |
|
|
253
|
+
| `pause` | `void` | Playback paused. |
|
|
254
|
+
| `ended` | `void` | Media finished playing. |
|
|
255
|
+
| `timeupdate` | `{ seconds: number, duration: number }` | Playback time changed. |
|
|
256
|
+
| `volumechange` | `{ volume: number }` | Volume changed. |
|
|
257
|
+
| `error` | `{ code?: number, message?: string }` | Error occurred. |
|
|
258
|
+
| `progress` | `{ percent: number }` | Buffering progress. |
|
|
259
|
+
| `ready` | `void` | Player is ready. |
|
|
260
|
+
| `seeked` | `void` | Seek completed. |
|
|
261
|
+
| `loaded` | `void` | Metadata loaded. |
|
|
262
|
+
|
|
263
|
+
Custom event names are also accepted via the string index signature:
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
player.on('my-custom-event', (data) => {
|
|
267
|
+
console.log(data);
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Destroy
|
|
272
|
+
|
|
273
|
+
When using `createViostreamPlayer()`, you are responsible for cleanup:
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
player.destroy();
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
After calling `destroy()`:
|
|
280
|
+
- All event listeners are removed.
|
|
281
|
+
- The player iframe is removed from the DOM.
|
|
282
|
+
- Getter calls will reject with `"Player has been destroyed"`.
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Script Loader
|
|
286
|
+
|
|
287
|
+
The SDK loads the Viostream API script automatically. If you need manual control over loading (e.g. preloading), you can use `loadViostream` directly:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
import { loadViostream } from 'viostream-player-svelte';
|
|
291
|
+
|
|
292
|
+
const api = await loadViostream('vc-100100100');
|
|
293
|
+
// api.embed(...) is now available
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
The loader:
|
|
297
|
+
- Injects `<script src="https://play.viostream.com/api/{accountKey}">` into `<head>`.
|
|
298
|
+
- Deduplicates requests -- calling it multiple times with the same key returns the same promise.
|
|
299
|
+
- Times out after 15 seconds if the script fails to load.
|
|
300
|
+
- Detects if the script tag already exists in the DOM (e.g. added manually) and waits for it.
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## TypeScript
|
|
305
|
+
|
|
306
|
+
Every export is fully typed. Import types alongside runtime exports:
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
import { ViostreamPlayer, createViostreamPlayer } from 'viostream-player-svelte';
|
|
310
|
+
import type {
|
|
311
|
+
ViostreamPlayerInstance,
|
|
312
|
+
ViostreamPlayerProps,
|
|
313
|
+
ViostreamEmbedOptions,
|
|
314
|
+
ViostreamTimeUpdateData,
|
|
315
|
+
ViostreamVolumeChangeData,
|
|
316
|
+
ViostreamErrorData,
|
|
317
|
+
ViostreamProgressData,
|
|
318
|
+
ViostreamPlayerEventMap,
|
|
319
|
+
ViostreamEventHandler,
|
|
320
|
+
CreateViostreamPlayerOptions,
|
|
321
|
+
} from 'viostream-player-svelte';
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Full Example
|
|
327
|
+
|
|
328
|
+
A complete example showing the component with custom controls, event logging, and async getters:
|
|
329
|
+
|
|
330
|
+
```svelte
|
|
331
|
+
<script lang="ts">
|
|
332
|
+
import { ViostreamPlayer } from 'viostream-player-svelte';
|
|
333
|
+
import type { ViostreamPlayerInstance, ViostreamTimeUpdateData } from 'viostream-player-svelte';
|
|
334
|
+
|
|
335
|
+
let player: ViostreamPlayerInstance | undefined = $state();
|
|
336
|
+
let currentTime = $state(0);
|
|
337
|
+
let duration = $state(0);
|
|
338
|
+
let paused = $state(true);
|
|
339
|
+
let log: string[] = $state([]);
|
|
340
|
+
|
|
341
|
+
function handleReady(p: ViostreamPlayerInstance) {
|
|
342
|
+
player = p;
|
|
343
|
+
p.getDuration().then((d) => (duration = d));
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function handleTimeUpdate(data: ViostreamTimeUpdateData) {
|
|
347
|
+
currentTime = data.seconds;
|
|
348
|
+
duration = data.duration;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function format(s: number): string {
|
|
352
|
+
return `${Math.floor(s / 60)}:${Math.floor(s % 60).toString().padStart(2, '0')}`;
|
|
353
|
+
}
|
|
354
|
+
</script>
|
|
355
|
+
|
|
356
|
+
<ViostreamPlayer
|
|
357
|
+
accountKey="vc-100100100"
|
|
358
|
+
publicKey="nhedxonrxsyfee"
|
|
359
|
+
displayTitle={true}
|
|
360
|
+
sharing={true}
|
|
361
|
+
speedSelector={true}
|
|
362
|
+
hlsQualitySelector={true}
|
|
363
|
+
onplay={() => { paused = false; log = ['play', ...log]; }}
|
|
364
|
+
onpause={() => { paused = true; log = ['pause', ...log]; }}
|
|
365
|
+
onended={() => { log = ['ended', ...log]; }}
|
|
366
|
+
ontimeupdate={handleTimeUpdate}
|
|
367
|
+
onplayerready={handleReady}
|
|
368
|
+
/>
|
|
369
|
+
|
|
370
|
+
<div>
|
|
371
|
+
<button onclick={() => paused ? player?.play() : player?.pause()}>
|
|
372
|
+
{paused ? 'Play' : 'Pause'}
|
|
373
|
+
</button>
|
|
374
|
+
<button onclick={() => player?.setCurrentTime(0)}>Restart</button>
|
|
375
|
+
<span>{format(currentTime)} / {format(duration)}</span>
|
|
376
|
+
</div>
|
|
377
|
+
|
|
378
|
+
<div>
|
|
379
|
+
<button onclick={async () => {
|
|
380
|
+
const vol = await player?.getVolume();
|
|
381
|
+
log = [`volume: ${vol}`, ...log];
|
|
382
|
+
}}>Get Volume</button>
|
|
383
|
+
</div>
|
|
384
|
+
|
|
385
|
+
<pre>{log.join('\n')}</pre>
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Development
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
# Install dependencies
|
|
394
|
+
npm install
|
|
395
|
+
|
|
396
|
+
# Start the dev server (serves the demo page)
|
|
397
|
+
npm run dev
|
|
398
|
+
|
|
399
|
+
# Type-check
|
|
400
|
+
npm run check
|
|
401
|
+
|
|
402
|
+
# Run tests
|
|
403
|
+
npm run test
|
|
404
|
+
|
|
405
|
+
# Run tests in watch mode
|
|
406
|
+
npm run test:watch
|
|
407
|
+
|
|
408
|
+
# Build the library for publishing
|
|
409
|
+
npm run package
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## License
|
|
413
|
+
|
|
414
|
+
MIT
|