@gcorevideo/player 0.1.0 → 0.2.3

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.
Files changed (43) hide show
  1. package/dist/index.js +29198 -27398
  2. package/lib/Player.d.ts +8 -25
  3. package/lib/Player.d.ts.map +1 -1
  4. package/lib/Player.js +79 -131
  5. package/lib/backend.js +2 -2
  6. package/lib/index.d.ts +1 -0
  7. package/lib/index.d.ts.map +1 -1
  8. package/lib/index.js +1 -0
  9. package/lib/internal.types.d.ts +9 -2
  10. package/lib/internal.types.d.ts.map +1 -1
  11. package/lib/plugins/dash-playback/DashPlayback.d.ts.map +1 -1
  12. package/lib/plugins/dash-playback/DashPlayback.js +1 -11
  13. package/lib/plugins/hls-playback/HlsPlayback.d.ts.map +1 -1
  14. package/lib/plugins/hls-playback/HlsPlayback.js +5 -1
  15. package/lib/types.d.ts +16 -3
  16. package/lib/types.d.ts.map +1 -1
  17. package/lib/types.js +8 -1
  18. package/lib/utils/utils.d.ts +0 -4
  19. package/lib/utils/utils.d.ts.map +1 -1
  20. package/lib/utils/utils.js +0 -26
  21. package/lib/version.d.ts +5 -0
  22. package/lib/version.d.ts.map +1 -0
  23. package/lib/version.js +8 -0
  24. package/package.json +2 -1
  25. package/rollup.config.js +3 -1
  26. package/src/Player.ts +89 -166
  27. package/src/backend.ts +2 -2
  28. package/src/index.ts +1 -0
  29. package/src/internal.types.ts +11 -3
  30. package/src/plugins/dash-playback/DashPlayback.ts +1 -11
  31. package/src/plugins/hls-playback/HlsPlayback.ts +7 -3
  32. package/src/types.ts +18 -6
  33. package/src/{xtypings → typings}/@clappr/core/player.d.ts +0 -7
  34. package/src/typings/@clappr/plugins.d.ts +23 -0
  35. package/src/utils/utils.ts +0 -26
  36. package/src/version.ts +9 -0
  37. package/tsconfig.tsbuildinfo +1 -1
  38. package/src/utils/scripts-load.ts +0 -26
  39. /package/src/{xtypings → typings}/@clappr/core/error_mixin.d.ts +0 -0
  40. /package/src/{xtypings → typings}/@clappr/core/events.d.ts +0 -0
  41. /package/src/{xtypings → typings}/@clappr/core/html5_video.d.ts +0 -0
  42. /package/src/{xtypings → typings}/@clappr/core/playback.d.ts +0 -0
  43. /package/src/{xtypings → typings}/globals.d.ts +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,qBAMvC;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyBxD;AAGD,wBAAgB,YAAY,CAAC,EAAE,EAAE,WAAW,GAAG,OAAO,CAQrD;AAED,eAAO,MAAM,aAAa;uBACI,gBAAgB,KAAG,OAAO;CAYvD,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,qBAMvC;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyBxD"}
@@ -1,6 +1,3 @@
1
- // import LogManager from './LogManager';
2
- import { Browser } from '@clappr/core';
3
- import assert from 'assert';
4
1
  export function getLocation(href) {
5
2
  const l = document.createElement('a');
6
3
  l.href = href;
@@ -32,26 +29,3 @@ export function strtimeToMiliseconds(str) {
32
29
  }
33
30
  return (h + m + s);
34
31
  }
35
- // TODO refactor
36
- export function isFullscreen(el) {
37
- const video = el.nodeName === "video" ? el : el.querySelector('video');
38
- assert.ok(video, 'element must be a video or contain a video element');
39
- if (Browser.isiOS) {
40
- return FullscreenIOS.isFullscreen(video);
41
- }
42
- return !!(document.fullscreenElement);
43
- }
44
- export const FullscreenIOS = {
45
- isFullscreen: function (el) {
46
- try {
47
- if (el.webkitDisplayingFullscreen !== undefined) {
48
- return !!(el.webkitDisplayingFullscreen);
49
- }
50
- }
51
- catch (e) {
52
- // LogManager.exception(error);
53
- reportError(e);
54
- }
55
- return false;
56
- }
57
- };
@@ -0,0 +1,5 @@
1
+ export declare function version(): {
2
+ gplayer: string;
3
+ clappr: string;
4
+ };
5
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAGA,wBAAgB,OAAO;;;EAKtB"}
package/lib/version.js ADDED
@@ -0,0 +1,8 @@
1
+ import * as pkg from '../package.json' with { "type": "json" };
2
+ import * as lock from '../package-lock.json' with { "type": "json" };
3
+ export function version() {
4
+ return {
5
+ gplayer: pkg.version,
6
+ clappr: lock.packages['node_modules/@clappr/core'].version,
7
+ };
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gcorevideo/player",
3
- "version": "0.1.0",
3
+ "version": "0.2.3",
4
4
  "description": "Gcore JavaScript video player",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -31,6 +31,7 @@
31
31
  "homepage": "https://github.com/G-Core/gcore-videoplayer-js#readme",
32
32
  "devDependencies": {
33
33
  "@rollup/plugin-commonjs": "^28.0.1",
34
+ "@rollup/plugin-json": "^6.1.0",
34
35
  "@rollup/plugin-node-resolve": "^15.3.0",
35
36
  "@types/node": "^22.10.1",
36
37
  "assert": "^2.1.0",
package/rollup.config.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // https://github.com/rollup/rollup-starter-lib
2
- import resolve from '@rollup/plugin-node-resolve';
3
2
  import commonjs from '@rollup/plugin-commonjs';
3
+ import json from '@rollup/plugin-json';
4
+ import resolve from '@rollup/plugin-node-resolve';
4
5
  import sass from 'rollup-plugin-sass';
5
6
  import { string } from 'rollup-plugin-string';
6
7
  import polyfillNode from 'rollup-plugin-polyfill-node';
@@ -15,6 +16,7 @@ export default [
15
16
  }),
16
17
  resolve(),
17
18
  commonjs(),
19
+ json(),
18
20
  string({
19
21
  include: [
20
22
  '**/*.ejs',
package/src/Player.ts CHANGED
@@ -1,17 +1,15 @@
1
1
  import {
2
2
  Browser,
3
3
  Events as ClapprEvents,
4
+ HTML5Video,
4
5
  Log,
5
6
  Player as PlayerClappr,
6
7
  $,
7
8
  Loader,
8
9
  } from '@clappr/core';
9
10
  import assert from 'assert';
10
- import Hls from 'hls.js';
11
11
  import EventLite from "event-lite";
12
12
 
13
- import '../assets/style/main.scss'; // TODO check if needed
14
-
15
13
  import type {
16
14
  CorePlayerEvents,
17
15
  CoreOptions,
@@ -19,33 +17,26 @@ import type {
19
17
  PlayerMediaSource,
20
18
  } from "./internal.types.js";
21
19
  import type {
20
+ BitrateInfo,
21
+ PlaybackType,
22
22
  PlayerPlugin,
23
23
  StreamMediaSource,
24
- } from "./types";
25
-
26
- import { reportError, trace } from "./trace/index.js";
24
+ } from "./types.js";
25
+ import { reportError } from "./trace/index.js";
27
26
  import {
28
27
  PlayerConfig,
29
- MediaTransport,
30
- TransportPreference,
28
+ PlayerEvent,
31
29
  } from "./types.js";
32
30
  import DashPlayback from './plugins/dash-playback/DashPlayback.js';
33
31
  import HlsPlayback from './plugins/hls-playback/HlsPlayback.js';
34
- import Playback from '@clappr/core/types/base/playback/playback';
35
-
36
- export enum PlayerEvent {
37
- Ready = 'ready',
38
- Play = 'play',
39
- Pause = 'pause',
40
- Stop = 'stop',
41
- Ended = 'ended',
42
- }
32
+
33
+ import '../assets/style/main.scss'; // TODO check if needed
43
34
 
44
35
  // TODO implement transport retry/failover and fallback logic
45
36
 
46
37
  type PlayerEventHandler<T extends PlayerEvent> = () => void;
47
38
 
48
- const T = "Player";
39
+ const T = "GPlayer";
49
40
 
50
41
  const DEFAULT_OPTIONS: Partial<PlayerConfig> = {
51
42
  autoPlay: false,
@@ -55,20 +46,6 @@ const DEFAULT_OPTIONS: Partial<PlayerConfig> = {
55
46
 
56
47
  export type PlaybackModule = 'dash' | 'hls' | 'native';
57
48
 
58
- // TODO drop
59
- // export type PlaybackInfo = {
60
- // bitrate: number;
61
- // hd: boolean;
62
- // latency: number;
63
- // }
64
-
65
- type BitrateInfo = {
66
- height: number;
67
- width: number;
68
- bitrate: number;
69
- level: number;
70
- }
71
-
72
49
  type PluginOptions = Record<string, unknown>;
73
50
 
74
51
  /**
@@ -87,13 +64,11 @@ export class Player {
87
64
 
88
65
  private tuneInEntered = false;
89
66
 
90
- private supportedMediaTransports: MediaTransport[] = [];
91
-
92
67
  private config: PlayerConfig;
93
68
 
94
69
  private bitrateInfo: BitrateInfo | null = null;
95
70
 
96
- get playbackModule(): PlaybackModule | null {
71
+ get activePlayback(): PlaybackModule | null {
97
72
  if (!this.player?.core.activePlayback) {
98
73
  return null;
99
74
  }
@@ -115,6 +90,10 @@ export class Player {
115
90
  return this.player?.core.activePlayback?.isHighDefinitionInUse || false;
116
91
  }
117
92
 
93
+ get playbackType(): PlaybackType | undefined{
94
+ return this.player?.core.activePlayback?.getPlaybackType();
95
+ }
96
+
118
97
  get playing() {
119
98
  return this.player ? this.player.isPlaying() : false;
120
99
  }
@@ -137,9 +116,13 @@ export class Player {
137
116
  this.emitter.off(event, handler);
138
117
  }
139
118
 
119
+ configure(config: Partial<PlayerConfig>) {
120
+ $.extend(true, this.config, config);
121
+ }
122
+
140
123
  async init(playerElement: HTMLElement) {
141
124
  assert.ok(!this.player, 'Player already initialized');
142
- assert.ok(playerElement, 'Player element is required');
125
+ assert.ok(playerElement, 'Player container element is required');
143
126
  if (
144
127
  this.config.debug === 'all' ||
145
128
  this.config.debug === 'clappr'
@@ -147,26 +130,25 @@ export class Player {
147
130
  Log.setLevel(0);
148
131
  }
149
132
 
150
- Log.debug('Config', this.config);
151
-
152
- this.configurePlugins();
153
- return this.loadPlugins().then(async () => {
154
- const coreOpts = this.buildCoreOptions(playerElement);
155
- const {
156
- core,
157
- container,
158
- } = Loader.registeredPlugins;
159
- coreOpts.plugins = {
160
- core: Object.values(core),
161
- container: Object.values(container),
162
- playback: Loader.registeredPlaybacks,
163
- } as CorePluginOptions;
164
- return this.initPlayer(coreOpts);
165
- });
133
+ Log.debug(T, 'Config', this.config);
134
+
135
+ this.configurePlaybacks();
136
+ const coreOpts = this.buildCoreOptions(playerElement);
137
+ const {
138
+ core,
139
+ container,
140
+ } = Loader.registeredPlugins;
141
+ coreOpts.plugins = {
142
+ core: Object.values(core),
143
+ container: Object.values(container),
144
+ playback: Loader.registeredPlaybacks,
145
+ } as CorePluginOptions;
146
+ Log.debug(T, 'coreOpts', coreOpts);
147
+ return this.initPlayer(coreOpts);
166
148
  }
167
149
 
168
150
  destroy() {
169
- trace(`${T} destroy`, { player: !!this.player });
151
+ Log.debug(T, 'destroy', { player: !!this.player });
170
152
  if (this.player) {
171
153
  this.player.destroy();
172
154
  this.player = null;
@@ -197,8 +179,8 @@ export class Player {
197
179
  Loader.registerPlugin(plugin);
198
180
  }
199
181
 
200
- private loadPlugins(): Promise<void> {
201
- return Promise.all(this.pluginLoaders.map((loader) => loader())).then(() => { });
182
+ static unregisterPlugin(plugin: PlayerPlugin) {
183
+ Loader.unregisterPlugin(plugin);
202
184
  }
203
185
 
204
186
  private initPlayer(coreOptions: CoreOptions) {
@@ -229,7 +211,7 @@ export class Player {
229
211
  // TODO sort this out
230
212
  private async tuneIn() {
231
213
  assert.ok(this.player);
232
- trace(`${T} tuneIn enter`, {
214
+ Log.debug(T, 'tuneIn enter', {
233
215
  ready: this.clapprReady,
234
216
  tuneInEntered: this.tuneInEntered,
235
217
  });
@@ -247,7 +229,6 @@ export class Player {
247
229
  this.bindBitrateChangeHandler();
248
230
  }
249
231
  player.core.on(ClapprEvents.CORE_ACTIVE_CONTAINER_CHANGED, () => {
250
- trace(`${T} onActiveContainerChanged`);
251
232
  this.bindBitrateChangeHandler();
252
233
  }, null);
253
234
  if (
@@ -267,33 +248,9 @@ export class Player {
267
248
  }
268
249
  }
269
250
 
270
- private configurePlugins() {
271
- // TODO remove !isiOS?
272
- const useDash = !Browser.isiOS && this.config.multisources.some(
273
- (el) => el.sourceDash && DashPlayback.canPlay(el.sourceDash)
274
- );
275
- if (useDash) {
276
- this.scheduleLoad(async () => {
277
- const module = await import('./plugins/dash-playback/DashPlayback.js');
278
- Loader.registerPlayback(module.default);
279
- })
280
- }
281
- // TODO remove !isiOS?
282
- // if (!Browser.isiOS && this.config.multisources.some((el) => el.hls_mpegts_url)) {
283
- const useHls = this.config.multisources.some(
284
- (el) => HlsPlayback.canPlay(el.hlsCmafUrl || el.hlsMpegtsUrl || el.source)
285
- );
286
- if (useHls) {
287
- this.scheduleLoad(async () => {
288
- const module = await import('./plugins/hls-playback/HlsPlayback.js');
289
- Loader.registerPlayback(module.default);
290
- })
291
- }
292
- }
293
-
294
251
  private events: CorePlayerEvents = {
295
252
  onReady: () => {
296
- trace(`${T} onReady`, { clapprReady: this.clapprReady, player: !!this.player, core: !!this.player?.core, activeContainer: !!this.player?.core.activeContainer });
253
+ Log.debug(T, 'onReady', { clapprReady: this.clapprReady, player: !!this.player, core: !!this.player?.core, activeContainer: !!this.player?.core.activeContainer });
297
254
  if (this.clapprReady) {
298
255
  return;
299
256
  }
@@ -303,9 +260,6 @@ export class Player {
303
260
  clearTimeout(this.timer);
304
261
  this.timer = null;
305
262
  }
306
- // trace(`${T} onReady`, {
307
- // activeContainer: !!this.player?.core.activeContainer,
308
- // });
309
263
  setTimeout(() => this.tuneIn(), 0);
310
264
  },
311
265
  onPlay: () => {
@@ -339,20 +293,21 @@ export class Player {
339
293
  };
340
294
 
341
295
  private buildCoreOptions(playerElement: HTMLElement): CoreOptions {
342
- this.checkMediaTransportsSupport();
343
- const multisources = this.processMultisources(this.config.priorityTransport);
344
- const mediaSources = multisources.map(ms => ms.source);
345
- const mainSource = this.findMainSource();
346
- const mainSourceUrl = unwrapSource(mainSource ? this.selectMediaTransport(mainSource, this.config.priorityTransport) : undefined);
296
+ const multisources = this.config.multisources;
297
+ const mainSource = this.config.playbackType === 'live' ? multisources.find(ms => ms.live !== false) : multisources[0];
298
+ const mediaSources = mainSource ? this.buildMediaSourcesList(mainSource): [];
299
+ const mainSourceUrl = mediaSources[0];
347
300
  const poster = mainSource?.poster ?? this.config.poster;
348
301
 
349
302
  const coreOptions: CoreOptions & PluginOptions = {
303
+ ...this.config.pluginSettings,
350
304
  autoPlay: this.config.autoPlay,
351
305
  debug: this.config.debug || 'none',
352
306
  events: this.events,
307
+ height: playerElement.clientHeight,
308
+ loop: this.config.loop,
353
309
  multisources,
354
310
  mute: this.config.mute,
355
- ...this.config.pluginSettings,
356
311
  playback: {
357
312
  controls: false,
358
313
  preload: Browser.isiOS ? 'metadata' : 'none',
@@ -366,94 +321,62 @@ export class Player {
366
321
  playbackType: this.config.playbackType,
367
322
  poster,
368
323
  width: playerElement.clientWidth,
369
- height: playerElement.clientHeight,
370
- loop: this.config.loop,
371
- strings: this.config.strings,
372
324
  source: mainSourceUrl,
373
325
  sources: mediaSources,
326
+ strings: this.config.strings,
374
327
  };
375
- trace(`${T} buildCoreOptions`, coreOptions);
376
328
  return coreOptions;
377
329
  }
378
330
 
379
- private findMainSource(): StreamMediaSource | undefined {
380
- return this.config.multisources.find(ms => ms.live !== false);
381
- }
382
-
383
- private scheduleLoad(cb: () => Promise<void>) {
384
- this.pluginLoaders.push(cb);
385
- }
386
-
387
- private selectMediaTransport(ms: StreamMediaSource, priorityTransport: TransportPreference = ms.priorityTransport): string {
388
- const cmafUrl = ms.hlsCmafUrl || ms.source; // source is default url for hls
389
- const mpegtsUrl = ms.hlsMpegtsUrl; // no-low-latency HLS
390
- const dashUrl = ms.sourceDash;
391
- const masterSource = ms.source;
392
-
393
- const mts = this.getAvailableTransportsPreference(priorityTransport);
394
- for (const mt of mts) {
395
- switch (mt) {
396
- case 'dash':
397
- if (dashUrl) {
398
- return dashUrl;
399
- }
400
- break;
401
- case 'hls':
402
- if (cmafUrl) {
403
- return cmafUrl;
404
- }
405
- break;
406
- default:
407
- return mpegtsUrl || masterSource;
408
- }
409
- }
410
- // no supported transport found
411
- return '';
412
- }
413
-
414
- private getAvailableTransportsPreference(priorityTransport: TransportPreference): MediaTransport[] {
415
- const mtp: MediaTransport[] = [];
416
- if (priorityTransport !== 'auto' && this.supportedMediaTransports.includes(priorityTransport)) {
417
- mtp.push(priorityTransport);
418
- }
419
- for (const mt of this.supportedMediaTransports) {
420
- if (mt !== priorityTransport) {
421
- mtp.push(mt);
422
- }
423
- }
424
- return mtp;
425
- }
426
-
427
- private checkMediaTransportsSupport() {
428
- const isDashSupported = typeof (globalThis.MediaSource || (globalThis as any).WebKitMediaSource) === 'function';
429
- if (isDashSupported) {
430
- this.supportedMediaTransports.push('dash');
431
- }
432
- if (Hls.isSupported()) {
433
- this.supportedMediaTransports.push('hls');
434
- }
435
- this.supportedMediaTransports.push('mpegts');
436
- }
437
-
438
- private processMultisources(transport?: TransportPreference): StreamMediaSource[] {
439
- return this.config.multisources.map((ms: StreamMediaSource): StreamMediaSource => ({
440
- ...ms,
441
- source: this.selectMediaTransport(ms, transport),
442
- })).filter((el): el is StreamMediaSource => !!el.source);
331
+ private configurePlaybacks() {
332
+ Loader.registerPlayback(DashPlayback);
333
+ Loader.registerPlayback(HlsPlayback);
334
+ Loader.registerPlayback(HTML5Video);
443
335
  }
444
336
 
445
337
  private bindBitrateChangeHandler() {
446
- trace(`${T} bindBitrateChangeHandler`, { activePlayback: !!this.player?.core.activePlayback });
447
338
  this.player?.core.activeContainer.on(ClapprEvents.CONTAINER_BITRATE, (bitrate: BitrateInfo) => {
448
- trace(`${T} onPlaybackBitrate`, { bitrate });
449
339
  this.bitrateInfo = bitrate;
450
340
  });
451
341
  }
452
- }
453
342
 
454
- function unwrapSource(s: PlayerMediaSource | undefined): string | undefined {
455
- if (!s) {
456
- return;
343
+ private buildMediaSourcesList(ms: StreamMediaSource): string[] {
344
+ const msl: string[] = [];
345
+ const sources: Record<'dash' | 'master' | 'hls' | 'mpegts', string | null> = {
346
+ dash: ms.sourceDash,
347
+ master: ms.source,
348
+ hls: ms.hlsCmafUrl,
349
+ mpegts: ms.hlsMpegtsUrl,
350
+ }
351
+ switch (this.config.priorityTransport) {
352
+ case 'dash':
353
+ if (sources.dash) {
354
+ msl.push(sources.dash);
355
+ sources.dash = null;
356
+ }
357
+ break;
358
+ case 'hls':
359
+ if (sources.hls) {
360
+ msl.push(sources.hls);
361
+ sources.hls = null;
362
+ }
363
+ if (sources.master?.endsWith('.m3u8')) {
364
+ msl.push(sources.master);
365
+ sources.master = null;
366
+ }
367
+ break;
368
+ case 'mpegts':
369
+ if (sources.mpegts) {
370
+ msl.push(sources.mpegts);
371
+ sources.mpegts = null
372
+ }
373
+ break;
374
+ }
375
+ Object.values(sources).forEach(s => {
376
+ if (s) {
377
+ msl.push(s);
378
+ }
379
+ });
380
+ return msl;
457
381
  }
458
- return typeof s === "string" ? s : s.source;
459
382
  }
package/src/backend.ts CHANGED
@@ -3,8 +3,8 @@ import { StreamMediaSource, StreamMediaSourceDto } from "./types";
3
3
  export function fromStreamMediaSourceDto(s: StreamMediaSourceDto): StreamMediaSource {
4
4
  return ({
5
5
  ...s,
6
- hlsCmafUrl: s.hls_cmaf_url,
7
- hlsMpegtsUrl: s.hls_mpegts_url,
6
+ hlsCmafUrl: s.hls_cmaf_url ?? null,
7
+ hlsMpegtsUrl: s.hls_mpegts_url ?? null,
8
8
  priorityTransport: s.priority_transport,
9
9
  sourceDash: s.source_dash,
10
10
  vtt: s.vtt,
package/src/index.ts CHANGED
@@ -7,3 +7,4 @@ export * from "./trace/index.js";
7
7
  export * from "./trace/types.js";
8
8
  export * from "./types.js";
9
9
  export * from "./utils/Logger.js";
10
+ export * from "./version.js";
@@ -1,11 +1,17 @@
1
1
  import type {
2
2
  CorePlugin,
3
3
  ContainerPlugin,
4
- Playback as PlaybackPlugin,
5
- ExternalTrack,
4
+ Playback as ClapprPlayback,
6
5
  } from "@clappr/core";
7
6
  import { PlaybackType, PlayerDebugTag, StreamMediaSource } from "./types";
8
7
 
8
+ type ExternalTrack = {
9
+ kind?: "subtitles" | "captions";
10
+ src: string;
11
+ label: string;
12
+ lang: string;
13
+ }
14
+
9
15
  type MediacontrolStyles = {
10
16
  // TODO
11
17
  seekbar?: string;
@@ -76,10 +82,12 @@ export type ClapprVersionSpec = {
76
82
  // TODO
77
83
  }
78
84
 
85
+ export type PlaybackPluginFactory = typeof ClapprPlayback;
86
+
79
87
  export type CorePluginOptions = {
80
88
  core?: CorePlugin[];
81
89
  container?: ContainerPlugin[];
82
- playback?: PlaybackPlugin[];
90
+ playback?: PlaybackPluginFactory[];
83
91
  loadExternalPluginsFirst?: boolean;
84
92
  loadExternalPlaybacksFirst?: boolean;
85
93
  }
@@ -12,7 +12,6 @@ import DASHJS, {
12
12
  IManifestInfo
13
13
  } from 'dashjs';
14
14
 
15
- import { trace } from '../../trace/index.js';
16
15
  import { Duration, TimePosition, TimeValue } from '../../playback.types.js';
17
16
 
18
17
  const AUTO = -1;
@@ -243,7 +242,6 @@ export default class DashPlayback extends HTML5Video {
243
242
  }
244
243
 
245
244
  _setup() {
246
- trace(`${T} _setup`, { el: this.el });
247
245
  const dash = DASHJS.MediaPlayer().create();
248
246
  this._dash = dash;
249
247
  this._dash.initialize();
@@ -265,7 +263,6 @@ export default class DashPlayback extends HTML5Video {
265
263
 
266
264
  this._dash.on(DASHJS.MediaPlayer.events.STREAM_INITIALIZED, () => {
267
265
  const bitrates = dash.getBitrateInfoListFor('video');
268
- trace(`${T} STREAM_INITIALIZED`, { bitrates });
269
266
 
270
267
  this._updatePlaybackType();
271
268
  this._fillLevels(bitrates);
@@ -575,7 +572,6 @@ export default class DashPlayback extends HTML5Video {
575
572
  }
576
573
 
577
574
  play() {
578
- trace(`${T} play`, { dash: !!this._dash });
579
575
  if (!this._dash) {
580
576
  this._setup();
581
577
  }
@@ -619,13 +615,9 @@ export default class DashPlayback extends HTML5Video {
619
615
  _updatePlaybackType() {
620
616
  assert.ok(this._dash, 'An instance of dashjs MediaPlayer is required to update the playback type');
621
617
  this._playbackType = this._dash.isDynamic() ? Playback.LIVE : Playback.VOD;
622
- trace(`${T} _updatePlaybackType`, {
623
- playbackType: this._playbackType,
624
- });
625
618
  }
626
619
 
627
620
  _fillLevels(levels: BitrateInfo[]) {
628
- // trace(`${T} _fillLevels`, {levels});
629
621
  // TOOD check that levels[i].qualityIndex === i
630
622
  this._levels = levels.map((level) => {
631
623
  return { id: level.qualityIndex, level: level };
@@ -775,7 +767,6 @@ export default class DashPlayback extends HTML5Video {
775
767
  // }
776
768
 
777
769
  private onLevelSwitch(currentLevel: BitrateInfo) {
778
- trace(`${T} onLevelSwitch`, {currentLevel});
779
770
  this.trigger(Events.PLAYBACK_BITRATE, {
780
771
  height: currentLevel.height,
781
772
  width: currentLevel.width,
@@ -794,12 +785,11 @@ export default class DashPlayback extends HTML5Video {
794
785
  }
795
786
 
796
787
  DashPlayback.canPlay = function (resource, mimeType) {
797
- trace(`${T} canPlay resource:%s mimeType:%s`, {resource, mimeType});
798
788
  const resourceParts = resource.split('?')[0].match(/.*\.(.*)$/) || [];
799
789
  const isDash = ((resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'mpd') ||
800
790
  mimeType === 'application/dash+xml' || mimeType === 'video/mp4');
801
791
  const ctor = window.MediaSource || ('WebKitMediaSource' in window ? window.WebKitMediaSource : undefined);
802
792
  const hasBrowserSupport = typeof ctor === 'function';
803
- trace(`${T} canPlay isSupportByBrowser:%s isDash:%s`, {isSupportByBrowser: hasBrowserSupport, isDash});
793
+ Log.debug(T, 'canPlay', {hasBrowserSupport, isDash});
804
794
  return !!(hasBrowserSupport && isDash);
805
795
  };
@@ -16,8 +16,9 @@ import HLSJS, {
16
16
  type LevelLoadedData,
17
17
  type LevelSwitchingData,
18
18
  } from 'hls.js';
19
- import { PlaybackType } from '../../types';
19
+
20
20
  import { TimePosition } from '../../playback.types.js';
21
+ import { PlaybackType } from '../../types';
21
22
  import { TimerId } from '../../utils/types';
22
23
 
23
24
  const { now, listContainsIgnoreCase } = Utils;
@@ -904,6 +905,9 @@ export default class HlsPlayback extends HTML5Video {
904
905
  HlsPlayback.canPlay = function (resource: string, mimeType?: string): boolean {
905
906
  const resourceParts = resource.split('?')[0].match(/.*\.(.*)$/) || [];
906
907
  const isHls = ((resourceParts.length > 1 && resourceParts[1].toLowerCase() === 'm3u8') || listContainsIgnoreCase(mimeType, ['application/vnd.apple.mpegurl', 'application/x-mpegURL']));
907
-
908
- return !!(HLSJS.isSupported() && isHls);
908
+ const isSupported = HLSJS.isSupported();
909
+ Log.debug(T, 'canPlay', {
910
+ isSupported, isHls,
911
+ })
912
+ return !!(isSupported && isHls);
909
913
  };
package/src/types.ts CHANGED
@@ -7,11 +7,9 @@ export type TransportPreference = MediaTransport | 'auto';
7
7
 
8
8
  export type PlayerPlugin = {
9
9
  new(...args: any[]): unknown;
10
- type: 'core' | 'container' | 'playback';
10
+ type: string; // 'core' | 'container' | 'playback';
11
11
  }
12
12
 
13
- // export type PluginName = StdPluginName | string;
14
-
15
13
  export type PlayerConfig = {
16
14
  autoPlay?: boolean;
17
15
  debug?: PlayerDebugSettings;
@@ -20,7 +18,6 @@ export type PlayerConfig = {
20
18
  multisources: StreamMediaSource[];
21
19
  mute?: boolean;
22
20
  playbackType: PlaybackType;
23
- // plugins?: PluginName[];
24
21
  pluginSettings?: Record<string, unknown>;
25
22
  poster?: string;
26
23
  priorityTransport?: TransportPreference;
@@ -79,8 +76,8 @@ export type StreamMediaSourceDto = {
79
76
  export type StreamMediaSource = {
80
77
  description: string;
81
78
  dvr: boolean;
82
- hlsCmafUrl?: string;
83
- hlsMpegtsUrl?: string;
79
+ hlsCmafUrl: string | null;
80
+ hlsMpegtsUrl: string | null;
84
81
  id: number;
85
82
  live: boolean;
86
83
  priorityTransport: TransportPreference;
@@ -98,3 +95,18 @@ export type SrcProjectionType = 'regular' | '360' | 'vr180' | 'vr360tb';
98
95
  export type ProjectionType = '360' | '180' | '360_TB';
99
96
 
100
97
  export type TranslationSettings = Partial<Record<LangTag, Record<TranslationKey, string>>>;
98
+
99
+ export type BitrateInfo = {
100
+ height: number;
101
+ width: number;
102
+ bitrate: number;
103
+ level: number;
104
+ };
105
+
106
+ export enum PlayerEvent {
107
+ Ready = 'ready',
108
+ Play = 'play',
109
+ Pause = 'pause',
110
+ Stop = 'stop',
111
+ Ended = 'ended',
112
+ }