@gcorevideo/player 2.16.17 → 2.18.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 +68 -19
- package/dist/index.js +272 -125
- package/dist/player.d.ts +230 -73
- package/docs/api/index.md +1 -1
- package/docs/api/player.containersize.md +19 -0
- package/docs/api/player.dashsettings.md +2 -0
- package/docs/api/player.errorlevel.md +1 -0
- package/docs/api/player.langtag.md +6 -0
- package/docs/api/player.md +59 -24
- package/docs/api/player.mediatransport.md +1 -0
- package/docs/api/player.playbackerror.code.md +2 -0
- package/docs/api/player.playbackerror.description.md +2 -0
- package/docs/api/player.playbackerror.level.md +2 -0
- package/docs/api/player.playbackerror.md +43 -4
- package/docs/api/player.playbackerror.message.md +2 -0
- package/docs/api/player.playbackerror.origin.md +21 -0
- package/docs/api/player.playbackerror.scope.md +16 -0
- package/docs/api/player.playbackerrorcode.md +8 -7
- package/docs/api/player.playbackmodule.md +1 -0
- package/docs/api/player.player.attachto.md +26 -0
- package/docs/api/player.player.configure.md +6 -2
- package/docs/api/player.player.destroy.md +1 -1
- package/docs/api/player.player.getcurrenttime.md +6 -2
- package/docs/api/player.player.getduration.md +4 -0
- package/docs/api/player.player.getvolume.md +22 -0
- package/docs/api/player.player.isdvrenabled.md +20 -0
- package/docs/api/player.player.isdvrinuse.md +24 -0
- package/docs/api/player.player.isplaying.md +20 -0
- package/docs/api/player.player.md +76 -8
- package/docs/api/player.player.mute.md +1 -1
- package/docs/api/player.player.off.md +5 -5
- package/docs/api/player.player.on.md +5 -5
- package/docs/api/player.player.registerplugin.md +14 -1
- package/docs/api/player.player.resize.md +6 -5
- package/docs/api/player.player.seek.md +1 -1
- package/docs/api/player.player.setvolume.md +56 -0
- package/docs/api/player.player.unmute.md +1 -1
- package/docs/api/player.player.unregisterplugin.md +2 -2
- package/docs/api/player.playercomponenttype.md +16 -0
- package/docs/api/player.playerdebugsettings.md +1 -1
- package/docs/api/player.playerdebugtag.md +1 -0
- package/docs/api/player.playerevent.md +96 -0
- package/docs/api/player.playereventhandler.md +3 -2
- package/docs/api/player.playereventparams.md +20 -0
- package/docs/api/player.playermediasourcedesc.md +1 -1
- package/docs/api/player.playermediasourcedesc.mimetype.md +1 -1
- package/docs/api/player.qualitylevel.bitrate.md +16 -0
- package/docs/api/player.qualitylevel.height.md +16 -0
- package/docs/api/player.qualitylevel.level.md +16 -0
- package/docs/api/player.qualitylevel.md +104 -7
- package/docs/api/player.qualitylevel.width.md +16 -0
- package/docs/api/player.timeposition.current.md +16 -0
- package/docs/api/player.timeposition.md +65 -7
- package/docs/api/player.timeposition.total.md +16 -0
- package/docs/api/player.timevalue.md +1 -1
- package/docs/api/player.translationsettings.md +7 -1
- package/docs/api/player.transportpreference.md +1 -0
- package/lib/Player.d.ts +107 -26
- package/lib/Player.d.ts.map +1 -1
- package/lib/Player.js +161 -77
- package/lib/index.d.ts +2 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -3
- package/lib/internal.types.d.ts +3 -5
- package/lib/internal.types.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.d.ts +2 -0
- package/lib/playback/dash-playback/DashPlayback.d.ts.map +1 -1
- package/lib/playback/dash-playback/DashPlayback.js +37 -25
- package/lib/playback/hls-playback/HlsPlayback.d.ts +3 -0
- package/lib/playback/hls-playback/HlsPlayback.d.ts.map +1 -1
- package/lib/playback/hls-playback/HlsPlayback.js +33 -18
- package/lib/playback.types.d.ts +65 -6
- package/lib/playback.types.d.ts.map +1 -1
- package/lib/playback.types.js +10 -0
- package/lib/types.d.ts +54 -5
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +31 -2
- package/package.json +1 -1
- package/rollup.config.js +1 -1
- package/src/Player.ts +202 -91
- package/src/__tests__/Player.test.ts +9 -3
- package/src/index.ts +2 -3
- package/src/internal.types.ts +3 -2
- package/src/playback/dash-playback/DashPlayback.ts +64 -35
- package/src/playback/hls-playback/HlsPlayback.ts +46 -22
- package/src/playback.types.ts +65 -5
- package/src/types.ts +56 -6
- package/src/utils/__tests__/mediaSources.test.ts +8 -2
- package/temp/player.api.json +771 -106
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/DashPlayback-BRJzl8D8.js +0 -901
package/src/Player.ts
CHANGED
|
@@ -15,19 +15,33 @@ import type {
|
|
|
15
15
|
CoreOptions,
|
|
16
16
|
CorePluginOptions,
|
|
17
17
|
} from './internal.types.js'
|
|
18
|
-
import type { PlayerMediaSourceDesc, PlayerPlugin } from './types.js'
|
|
18
|
+
import type { ContainerSize, PlayerMediaSourceDesc, PlayerPlugin } from './types.js'
|
|
19
19
|
import { PlayerConfig, PlayerEvent } from './types.js'
|
|
20
20
|
import {
|
|
21
21
|
buildMediaSourcesList,
|
|
22
|
-
unwrapSource,
|
|
23
22
|
wrapSource,
|
|
24
23
|
} from './utils/mediaSources.js'
|
|
25
24
|
import { registerPlaybacks } from './playback/index.js'
|
|
25
|
+
import { PlaybackError, TimePosition } from './playback.types.js'
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* @beta
|
|
29
29
|
*/
|
|
30
|
-
export type
|
|
30
|
+
export type PlayerEventParams<E extends PlayerEvent> =
|
|
31
|
+
E extends PlayerEvent.Seek ? [number]
|
|
32
|
+
: E extends PlayerEvent.VolumeUpdate ? [number]
|
|
33
|
+
: E extends PlayerEvent.TimeUpdate ? [TimePosition]
|
|
34
|
+
: E extends PlayerEvent.Resize ? [{ width: number, height: number }]
|
|
35
|
+
: E extends PlayerEvent.Fullscreen ? [boolean]
|
|
36
|
+
: E extends PlayerEvent.Error ? [PlaybackError]
|
|
37
|
+
: []
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Type of a listener callback function for a player event.
|
|
41
|
+
* See the description of the event parameters in {@link PlayerEvent}.
|
|
42
|
+
* @beta
|
|
43
|
+
*/
|
|
44
|
+
export type PlayerEventHandler<E extends PlayerEvent> = (...args: PlayerEventParams<E>) => void
|
|
31
45
|
|
|
32
46
|
const T = 'GPlayer'
|
|
33
47
|
|
|
@@ -43,6 +57,7 @@ const DEFAULT_OPTIONS: PlayerConfig = {
|
|
|
43
57
|
}
|
|
44
58
|
|
|
45
59
|
/**
|
|
60
|
+
* Module to perform the playback.
|
|
46
61
|
* @beta
|
|
47
62
|
*/
|
|
48
63
|
export type PlaybackModule = 'dash' | 'hls' | 'html5_video'
|
|
@@ -51,11 +66,11 @@ type PluginOptions = Record<string, unknown>
|
|
|
51
66
|
|
|
52
67
|
/**
|
|
53
68
|
* The main component to use in the application code.
|
|
69
|
+
* @beta
|
|
54
70
|
* @remarks
|
|
55
71
|
* The Player object provides very basic API to control playback.
|
|
56
72
|
* To build a sophisticated UI, use the plugins framework to tap into the Clappr core.
|
|
57
73
|
* {@link https://github.com/clappr/clappr/wiki/Architecture}
|
|
58
|
-
* @beta
|
|
59
74
|
*/
|
|
60
75
|
export class Player {
|
|
61
76
|
private config: PlayerConfig = DEFAULT_OPTIONS
|
|
@@ -81,29 +96,31 @@ export class Player {
|
|
|
81
96
|
|
|
82
97
|
/**
|
|
83
98
|
* Adds a listener to a player event
|
|
84
|
-
* @param event -
|
|
85
|
-
* @param handler -
|
|
99
|
+
* @param event - event type, see {@link PlayerEvent}
|
|
100
|
+
* @param handler - a callback function to handle the event
|
|
86
101
|
*/
|
|
87
|
-
on<
|
|
102
|
+
on<E extends PlayerEvent>(event: E, handler: PlayerEventHandler<E>) {
|
|
88
103
|
this.emitter.on(event, handler)
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
/**
|
|
92
|
-
* Removes a
|
|
107
|
+
* Removes a previously added event listener
|
|
93
108
|
* @param event - See {@link PlayerEvent}
|
|
94
|
-
* @param handler -
|
|
109
|
+
* @param handler - a callback attached earlier to that event type
|
|
95
110
|
*/
|
|
96
|
-
off<
|
|
111
|
+
off<E extends PlayerEvent>(event: E, handler: PlayerEventHandler<E>) {
|
|
97
112
|
this.emitter.off(event, handler)
|
|
98
113
|
}
|
|
99
114
|
|
|
100
115
|
/**
|
|
101
116
|
* Configures the player.
|
|
102
117
|
*
|
|
103
|
-
* Can be called multiple times. Each consequent call extends the previous configuration.
|
|
104
|
-
* After a reconfiguration, if something significant has changed, the must be reinitialized (i.e, a `.destroy()` followed by an `.init()` call).
|
|
105
|
-
*
|
|
106
118
|
* @param config - complete or partial configuration
|
|
119
|
+
* @remarks
|
|
120
|
+
* Can be called multiple times.
|
|
121
|
+
* Each consequent call extends the previous configuration with only the new keys overridden.
|
|
122
|
+
*
|
|
123
|
+
* After a reconfiguration, if something significant has changed, it might make sense reinitialize the player (i.e, a `.destroy()` followed by an `.init()` call).
|
|
107
124
|
*/
|
|
108
125
|
configure(config: Partial<PlayerConfig>) {
|
|
109
126
|
this.setConfig(config)
|
|
@@ -112,6 +129,29 @@ export class Player {
|
|
|
112
129
|
/**
|
|
113
130
|
* Initializes the player at the given container element.
|
|
114
131
|
* @param playerElement - DOM element to host the player
|
|
132
|
+
* @remarks
|
|
133
|
+
* The player will be initialized and attached to the given element.
|
|
134
|
+
*
|
|
135
|
+
* All the core plugins will be initialized at this point.
|
|
136
|
+
*
|
|
137
|
+
* If no sources were configured, it will trigger an error.
|
|
138
|
+
*
|
|
139
|
+
* The player container will be initialized and then all the registered UI plugins.
|
|
140
|
+
*
|
|
141
|
+
* If the `autoPlay` option is set, then it will trigger playback immediately.
|
|
142
|
+
*
|
|
143
|
+
* It is an error to call this method twice. If you need to attache player to another DOM element,
|
|
144
|
+
* first call {@link Player.destroy} and then {@link Player.attachTo}.
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```ts
|
|
148
|
+
* const player = new Player({
|
|
149
|
+
* sources: [{ source: 'https://example.com/a.mpd', mimeType: 'application/dash+xml' }],
|
|
150
|
+
* })
|
|
151
|
+
* document.addEventListener('DOMContentLoaded', () => {
|
|
152
|
+
* player.attachTo(document.getElementById('video-container'))
|
|
153
|
+
* })
|
|
154
|
+
* ```
|
|
115
155
|
*/
|
|
116
156
|
attachTo(playerElement: HTMLElement): void {
|
|
117
157
|
assert.ok(!this.player, 'Player already initialized')
|
|
@@ -134,7 +174,7 @@ export class Player {
|
|
|
134
174
|
}
|
|
135
175
|
|
|
136
176
|
/**
|
|
137
|
-
* Destroys the player, releasing all resources and
|
|
177
|
+
* Destroys the player, releasing all resources and unmounting its UI from the DOM.
|
|
138
178
|
*/
|
|
139
179
|
destroy() {
|
|
140
180
|
trace(`${T} destroy`, {
|
|
@@ -153,8 +193,11 @@ export class Player {
|
|
|
153
193
|
}
|
|
154
194
|
|
|
155
195
|
/**
|
|
156
|
-
* Current playback time
|
|
157
|
-
*
|
|
196
|
+
* Current playback (time since the beginning of the stream), if appropriate.
|
|
197
|
+
*
|
|
198
|
+
* @returns Time in seconds
|
|
199
|
+
* @remarks
|
|
200
|
+
* For live streams, it returns the current time within the current segment.
|
|
158
201
|
*/
|
|
159
202
|
getCurrentTime(): number {
|
|
160
203
|
if (!this.player) {
|
|
@@ -165,7 +208,10 @@ export class Player {
|
|
|
165
208
|
|
|
166
209
|
/**
|
|
167
210
|
* Duration of the current media in seconds, if appropriate.
|
|
168
|
-
*
|
|
211
|
+
*
|
|
212
|
+
* @returns Time in seconds
|
|
213
|
+
* @remarks
|
|
214
|
+
* For live streams, it returns the duration of the current segment.
|
|
169
215
|
*/
|
|
170
216
|
getDuration(): number {
|
|
171
217
|
if (!this.player) {
|
|
@@ -175,14 +221,37 @@ export class Player {
|
|
|
175
221
|
}
|
|
176
222
|
|
|
177
223
|
/**
|
|
178
|
-
*
|
|
224
|
+
* Indicates whether DVR is enabled.
|
|
225
|
+
*/
|
|
226
|
+
isDvrEnabled(): boolean {
|
|
227
|
+
return this.player?.isDvrEnabled() ?? false
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Indicates whether DVR is in use.
|
|
232
|
+
* @remarks
|
|
233
|
+
* DVR mode, if it is enabled, is triggered we a user seeks behind the live edge.
|
|
234
|
+
*/
|
|
235
|
+
isDvrInUse(): boolean {
|
|
236
|
+
return this.player?.isDvrInUse() ?? false
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Indicates the playing state.
|
|
241
|
+
*/
|
|
242
|
+
isPlaying(): boolean {
|
|
243
|
+
return this.player?.isPlaying() ?? false
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Mutes the sound of the video.
|
|
179
248
|
*/
|
|
180
249
|
mute() {
|
|
181
250
|
this.player?.mute()
|
|
182
251
|
}
|
|
183
252
|
|
|
184
253
|
/**
|
|
185
|
-
* Unmutes the
|
|
254
|
+
* Unmutes the video sound.
|
|
186
255
|
*/
|
|
187
256
|
unmute() {
|
|
188
257
|
this.player?.unmute()
|
|
@@ -205,19 +274,42 @@ export class Player {
|
|
|
205
274
|
/**
|
|
206
275
|
* Resizes the player container element and everything within it.
|
|
207
276
|
* @param newSize - new size of the player
|
|
277
|
+
* @remarks
|
|
278
|
+
* Use this method when the player itself does not detect properly the change in size of its container element.
|
|
279
|
+
* It can be a case for orientation change on some mobile devices.
|
|
208
280
|
*/
|
|
209
|
-
resize(newSize:
|
|
281
|
+
resize(newSize: ContainerSize) {
|
|
210
282
|
this.player?.resize(newSize)
|
|
211
283
|
}
|
|
212
284
|
|
|
213
285
|
/**
|
|
214
286
|
* Seeks to the given time.
|
|
215
|
-
* @param time - time to seek to in seconds
|
|
287
|
+
* @param time - time to seek to in seconds (since the beginning of the stream)
|
|
216
288
|
*/
|
|
217
289
|
seek(time: number) {
|
|
218
290
|
this.player?.seek(time)
|
|
219
291
|
}
|
|
220
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Gets the current volume of the media content being played.
|
|
295
|
+
* @returns a number between 0 and 1
|
|
296
|
+
*/
|
|
297
|
+
getVolume(): number {
|
|
298
|
+
// This method is provided by the MediaControl plugin
|
|
299
|
+
// @ts-ignore
|
|
300
|
+
return this.player?.getVolume?.() || 0
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Sets the current volume of the media content being played.
|
|
305
|
+
* @param volume - a number between 0 and 1
|
|
306
|
+
*/
|
|
307
|
+
setVolume(volume: number) {
|
|
308
|
+
// This method is provided by the MediaControl plugin
|
|
309
|
+
// @ts-ignore
|
|
310
|
+
this.player?.setVolume?.(volume)
|
|
311
|
+
}
|
|
312
|
+
|
|
221
313
|
/**
|
|
222
314
|
* Stops playback.
|
|
223
315
|
*/
|
|
@@ -227,15 +319,28 @@ export class Player {
|
|
|
227
319
|
|
|
228
320
|
/**
|
|
229
321
|
* Registers a plugin.
|
|
230
|
-
* @param plugin - plugin
|
|
322
|
+
* @param plugin - a plugin class
|
|
323
|
+
* @remarks
|
|
324
|
+
* Use this method to extend the player with custom behavior.
|
|
325
|
+
* The plugin class must inherit from one of the Clappr UIPlugin, UIContainerPlugin or CorePlugin classes.
|
|
326
|
+
* A core plugin will be initialized and attached to the player when the player is initialized.
|
|
327
|
+
* A UI plugin will be initialized and attached to the player container is initialized.
|
|
328
|
+
*
|
|
329
|
+
* @see {@link https://github.com/clappr/clappr/wiki/Architecture}
|
|
330
|
+
* @example
|
|
331
|
+
* ```ts
|
|
332
|
+
* import MyPlugin from './MyPlugin.js'
|
|
333
|
+
*
|
|
334
|
+
* Player.registerPlugin(MyPlugin)
|
|
335
|
+
* ```
|
|
231
336
|
*/
|
|
232
337
|
static registerPlugin(plugin: PlayerPlugin) {
|
|
233
338
|
Loader.registerPlugin(plugin)
|
|
234
339
|
}
|
|
235
340
|
|
|
236
341
|
/**
|
|
237
|
-
* Unregisters a plugin.
|
|
238
|
-
* @param plugin - plugin
|
|
342
|
+
* Unregisters a plugin registered earlier with {@link Player.registerPlugin}.
|
|
343
|
+
* @param plugin - a plugin class
|
|
239
344
|
*/
|
|
240
345
|
static unregisterPlugin(plugin: PlayerPlugin) {
|
|
241
346
|
Loader.unregisterPlugin(plugin)
|
|
@@ -277,50 +382,15 @@ export class Player {
|
|
|
277
382
|
}
|
|
278
383
|
this.tunedIn = true
|
|
279
384
|
const player = this.player
|
|
385
|
+
|
|
280
386
|
this.bindContainerEventListeners(player)
|
|
281
387
|
player.core.on(
|
|
282
388
|
ClapprEvents.CORE_ACTIVE_CONTAINER_CHANGED,
|
|
283
389
|
() => this.bindContainerEventListeners(player),
|
|
284
390
|
null,
|
|
285
391
|
)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
({ orientation }: { orientation: 'landscape' | 'portrait' }) => {
|
|
289
|
-
trace(`${T} CORE_SCREEN_ORIENTATION_CHANGED`, {
|
|
290
|
-
orientation,
|
|
291
|
-
rootNode: {
|
|
292
|
-
width: this.rootNode?.clientWidth,
|
|
293
|
-
height: this.rootNode?.clientHeight,
|
|
294
|
-
},
|
|
295
|
-
})
|
|
296
|
-
if (Browser.isiOS && this.rootNode) {
|
|
297
|
-
player.core.resize({
|
|
298
|
-
width: this.rootNode.clientWidth,
|
|
299
|
-
height: this.rootNode.clientHeight,
|
|
300
|
-
})
|
|
301
|
-
}
|
|
302
|
-
},
|
|
303
|
-
null,
|
|
304
|
-
)
|
|
305
|
-
player.core.on(
|
|
306
|
-
ClapprEvents.CORE_RESIZE,
|
|
307
|
-
({ width, height }: { width: number; height: number }) => {
|
|
308
|
-
trace(`${T} CORE_RESIZE`, {
|
|
309
|
-
width,
|
|
310
|
-
height,
|
|
311
|
-
})
|
|
312
|
-
},
|
|
313
|
-
null,
|
|
314
|
-
)
|
|
315
|
-
player.core.on(
|
|
316
|
-
ClapprEvents.CORE_FULLSCREEN,
|
|
317
|
-
(isFullscreen: boolean) => {
|
|
318
|
-
trace(`${T} CORE_FULLSCREEN`, {
|
|
319
|
-
isFullscreen,
|
|
320
|
-
})
|
|
321
|
-
},
|
|
322
|
-
null,
|
|
323
|
-
)
|
|
392
|
+
this.bindSizeManagementListeners(player)
|
|
393
|
+
|
|
324
394
|
if (this.config.autoPlay) {
|
|
325
395
|
setTimeout(() => {
|
|
326
396
|
trace(`${T} autoPlay`, {
|
|
@@ -338,6 +408,15 @@ export class Player {
|
|
|
338
408
|
}
|
|
339
409
|
}
|
|
340
410
|
|
|
411
|
+
private safeTriggerEvent<E extends PlayerEvent>(event: E, ...args: PlayerEventParams<E>) {
|
|
412
|
+
try {
|
|
413
|
+
this.emitter.emit(event, ...args)
|
|
414
|
+
} catch (e) {
|
|
415
|
+
reportError(e)
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// TODO test
|
|
341
420
|
private events: CorePlayerEvents = {
|
|
342
421
|
onReady: () => {
|
|
343
422
|
trace(`${T} onReady`, {
|
|
@@ -354,38 +433,29 @@ export class Player {
|
|
|
354
433
|
// TODO ensure that CORE_ACTIVE_CONTAINER_CHANGED does not get caught before onReady
|
|
355
434
|
setTimeout(() => this.tuneIn(), 0)
|
|
356
435
|
},
|
|
357
|
-
onResize: (newSize: { width: number; height: number }) => {
|
|
358
|
-
trace(`${T} onResize`, {
|
|
359
|
-
newSize,
|
|
360
|
-
})
|
|
361
|
-
},
|
|
362
436
|
onPlay: () => {
|
|
363
|
-
|
|
364
|
-
this.emitter.emit(PlayerEvent.Play)
|
|
365
|
-
} catch (e) {
|
|
366
|
-
reportError(e)
|
|
367
|
-
}
|
|
437
|
+
this.safeTriggerEvent(PlayerEvent.Play)
|
|
368
438
|
},
|
|
369
439
|
onPause: () => {
|
|
370
|
-
|
|
371
|
-
this.emitter.emit(PlayerEvent.Pause)
|
|
372
|
-
} catch (e) {
|
|
373
|
-
reportError(e)
|
|
374
|
-
}
|
|
440
|
+
this.safeTriggerEvent(PlayerEvent.Pause)
|
|
375
441
|
},
|
|
376
442
|
onEnded: () => {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
443
|
+
this.safeTriggerEvent(PlayerEvent.Ended)
|
|
444
|
+
},
|
|
445
|
+
onSeek: (time: number) => {
|
|
446
|
+
this.safeTriggerEvent(PlayerEvent.Seek, time)
|
|
382
447
|
},
|
|
383
448
|
onStop: () => {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
449
|
+
this.safeTriggerEvent(PlayerEvent.Stop)
|
|
450
|
+
},
|
|
451
|
+
onVolumeUpdate: (volume: number) => {
|
|
452
|
+
this.safeTriggerEvent(PlayerEvent.VolumeUpdate, volume)
|
|
453
|
+
},
|
|
454
|
+
onTimeUpdate: (time: TimePosition) => {
|
|
455
|
+
this.safeTriggerEvent(PlayerEvent.TimeUpdate, time)
|
|
456
|
+
},
|
|
457
|
+
onError: (error: PlaybackError) => {
|
|
458
|
+
this.safeTriggerEvent(PlayerEvent.Error, error)
|
|
389
459
|
},
|
|
390
460
|
}
|
|
391
461
|
|
|
@@ -416,6 +486,7 @@ export class Player {
|
|
|
416
486
|
mute: this.config.mute,
|
|
417
487
|
crossOrigin: 'anonymous', // TODO
|
|
418
488
|
hlsjsConfig: {
|
|
489
|
+
// TODO
|
|
419
490
|
debug: this.config.debug === 'all' || this.config.debug === 'hls',
|
|
420
491
|
},
|
|
421
492
|
},
|
|
@@ -424,7 +495,7 @@ export class Player {
|
|
|
424
495
|
width: rootNode.clientWidth,
|
|
425
496
|
source: source ? source.source : undefined,
|
|
426
497
|
mimeType: source ? source.mimeType : undefined,
|
|
427
|
-
sources,
|
|
498
|
+
sources,
|
|
428
499
|
strings: this.config.strings,
|
|
429
500
|
}
|
|
430
501
|
return coreOptions
|
|
@@ -443,9 +514,6 @@ export class Player {
|
|
|
443
514
|
}
|
|
444
515
|
|
|
445
516
|
private bindContainerEventListeners(player: PlayerClappr) {
|
|
446
|
-
trace(`${T} bindContainerEventListeners`, {
|
|
447
|
-
activePlayback: player.core.activePlayback?.name,
|
|
448
|
-
})
|
|
449
517
|
if (Browser.isiOS && player.core.activePlayback) {
|
|
450
518
|
player.core.activePlayback.$el.on('webkitendfullscreen', () => {
|
|
451
519
|
try {
|
|
@@ -456,4 +524,47 @@ export class Player {
|
|
|
456
524
|
})
|
|
457
525
|
}
|
|
458
526
|
}
|
|
527
|
+
|
|
528
|
+
private bindSizeManagementListeners(player: PlayerClappr) {
|
|
529
|
+
player.core.on(
|
|
530
|
+
ClapprEvents.CORE_SCREEN_ORIENTATION_CHANGED,
|
|
531
|
+
({ orientation }: { orientation: 'landscape' | 'portrait' }) => {
|
|
532
|
+
trace(`${T} on CORE_SCREEN_ORIENTATION_CHANGED`, {
|
|
533
|
+
orientation,
|
|
534
|
+
rootNode: {
|
|
535
|
+
width: this.rootNode?.clientWidth,
|
|
536
|
+
height: this.rootNode?.clientHeight,
|
|
537
|
+
},
|
|
538
|
+
})
|
|
539
|
+
if (Browser.isiOS && this.rootNode) {
|
|
540
|
+
player.core.resize({
|
|
541
|
+
width: this.rootNode.clientWidth,
|
|
542
|
+
height: this.rootNode.clientHeight,
|
|
543
|
+
})
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
null,
|
|
547
|
+
)
|
|
548
|
+
player.core.on(
|
|
549
|
+
ClapprEvents.CORE_RESIZE,
|
|
550
|
+
({ width, height }: { width: number; height: number }) => {
|
|
551
|
+
trace(`${T} on CORE_RESIZE`, {
|
|
552
|
+
width,
|
|
553
|
+
height,
|
|
554
|
+
})
|
|
555
|
+
this.safeTriggerEvent(PlayerEvent.Resize, { width, height })
|
|
556
|
+
},
|
|
557
|
+
null,
|
|
558
|
+
)
|
|
559
|
+
player.core.on(
|
|
560
|
+
ClapprEvents.CORE_FULLSCREEN,
|
|
561
|
+
(isFullscreen: boolean) => {
|
|
562
|
+
trace(`${T} CORE_FULLSCREEN`, {
|
|
563
|
+
isFullscreen,
|
|
564
|
+
})
|
|
565
|
+
this.safeTriggerEvent(PlayerEvent.Fullscreen, isFullscreen)
|
|
566
|
+
},
|
|
567
|
+
null,
|
|
568
|
+
)
|
|
569
|
+
}
|
|
459
570
|
}
|
|
@@ -34,21 +34,27 @@ vi.mock('@clappr/core', async () => {
|
|
|
34
34
|
const imported = await import('@clappr/core')
|
|
35
35
|
const MockDashPlayback = {
|
|
36
36
|
_supported: true,
|
|
37
|
-
|
|
37
|
+
prototype: {
|
|
38
|
+
name: 'dash',
|
|
39
|
+
},
|
|
38
40
|
canPlay(source, mimeType) {
|
|
39
41
|
return this._supported && (mimeType === 'application/dash+xml' || source.endsWith('.mpd'))
|
|
40
42
|
},
|
|
41
43
|
}
|
|
42
44
|
const MockHlsPlayback = {
|
|
43
45
|
_supported: true,
|
|
44
|
-
|
|
46
|
+
prototype: {
|
|
47
|
+
name: 'hls',
|
|
48
|
+
},
|
|
45
49
|
canPlay(source, mimeType) {
|
|
46
50
|
return this._supported && (['application/vnd.apple.mpegurl', 'application/x-mpegurl'].includes(mimeType) || source.endsWith('.m3u8'))
|
|
47
51
|
},
|
|
48
52
|
}
|
|
49
53
|
const MockHTML5VideoPlayback = {
|
|
50
54
|
_supported: true,
|
|
51
|
-
|
|
55
|
+
prototype: {
|
|
56
|
+
name: 'html5_video',
|
|
57
|
+
},
|
|
52
58
|
canPlay(source, mimeType) {
|
|
53
59
|
return this._supported && ['video/mp4', 'application/vnd.apple.mpegurl'].includes(mimeType)
|
|
54
60
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Video player for the
|
|
2
|
+
* Video player for the Gcore streaming platform
|
|
3
3
|
*
|
|
4
4
|
* @remarks
|
|
5
|
-
* This package provides a video player for the
|
|
5
|
+
* This package provides a video player for the Gcore streaming platform.
|
|
6
6
|
* It is built on top of the Clappr library and provides a framework for building custom integrations.
|
|
7
7
|
*
|
|
8
8
|
* @packageDocumentation
|
|
@@ -12,5 +12,4 @@ export { LogTracer, Logger, SentryTracer, reportError, setTracer, trace } from '
|
|
|
12
12
|
export * from './Player.js'
|
|
13
13
|
export * from './playback.types.js'
|
|
14
14
|
export * from './types.js'
|
|
15
|
-
export * from './utils/mediaSources.js'
|
|
16
15
|
export * from './version.js'
|
package/src/internal.types.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type {
|
|
|
4
4
|
Playback as ClapprPlayback,
|
|
5
5
|
} from "@clappr/core";
|
|
6
6
|
|
|
7
|
-
import { PlaybackType, PlayerDebugTag, PlayerMediaSource } from "./types";
|
|
7
|
+
import { ContainerSize, PlaybackType, PlayerDebugTag, PlayerMediaSource } from "./types";
|
|
8
8
|
import { PlaybackError } from "./playback.types";
|
|
9
9
|
|
|
10
10
|
type ExternalTrack = {
|
|
@@ -54,6 +54,7 @@ export interface CorePlaybackConfig {
|
|
|
54
54
|
playInline: boolean;
|
|
55
55
|
preload?: 'metadata' | 'auto' | 'none';
|
|
56
56
|
// preferredAudioLanguage?: string;
|
|
57
|
+
recycleVideo?: boolean;
|
|
57
58
|
shakaConfiguration?: ShakaConfig;
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -63,7 +64,7 @@ export interface CorePlaybackConfig {
|
|
|
63
64
|
export type CorePlayerEvents = {
|
|
64
65
|
// TODO event arguments types
|
|
65
66
|
onReady?: () => void;
|
|
66
|
-
onResize?: (data:
|
|
67
|
+
onResize?: (data: ContainerSize) => void;
|
|
67
68
|
onPlay?: (metadata: unknown) => void;
|
|
68
69
|
onPause?: (metadata: unknown) => void;
|
|
69
70
|
onStop?: (metadata: unknown) => void;
|