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