@gcorevideo/player 2.23.3 → 2.24.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.
Files changed (38) hide show
  1. package/dist/core.js +1 -1
  2. package/dist/index.css +630 -630
  3. package/dist/index.js +116 -4
  4. package/dist/player.d.ts +52 -4
  5. package/docs/api/player.cmcdconfig._constructor_.md +50 -0
  6. package/docs/api/player.cmcdconfig.bindevents.md +19 -0
  7. package/docs/api/player.cmcdconfig.exportids.md +21 -0
  8. package/docs/api/player.cmcdconfig.md +191 -0
  9. package/docs/api/player.cmcdconfig.name.md +15 -0
  10. package/docs/api/player.cmcdconfig.supportedversion.md +14 -0
  11. package/docs/api/player.cmcdconfig.version.md +14 -0
  12. package/docs/api/player.cmcdconfigpluginsettings.md +18 -0
  13. package/docs/api/player.md +22 -0
  14. package/lib/index.plugins.d.ts +1 -0
  15. package/lib/index.plugins.d.ts.map +1 -1
  16. package/lib/index.plugins.js +1 -0
  17. package/lib/plugins/big-mute-button/BigMuteButton.d.ts +1 -1
  18. package/lib/plugins/big-mute-button/BigMuteButton.d.ts.map +1 -1
  19. package/lib/plugins/big-mute-button/BigMuteButton.js +3 -2
  20. package/lib/plugins/cmcd-config/CmcdConfig.d.ts +45 -0
  21. package/lib/plugins/cmcd-config/CmcdConfig.d.ts.map +1 -0
  22. package/lib/plugins/cmcd-config/CmcdConfig.js +110 -0
  23. package/lib/plugins/cmcd-config/utils.d.ts +2 -0
  24. package/lib/plugins/cmcd-config/utils.d.ts.map +1 -0
  25. package/lib/plugins/cmcd-config/utils.js +3 -0
  26. package/lib/testUtils.d.ts +5 -1
  27. package/lib/testUtils.d.ts.map +1 -1
  28. package/lib/testUtils.js +4 -2
  29. package/package.json +1 -1
  30. package/src/index.plugins.ts +1 -0
  31. package/src/plugins/big-mute-button/BigMuteButton.ts +3 -2
  32. package/src/plugins/cmcd-config/CmcdConfig.ts +148 -0
  33. package/src/plugins/cmcd-config/__tests__/CmcdConfig.test.ts +174 -0
  34. package/src/plugins/cmcd-config/utils.ts +3 -0
  35. package/src/plugins/media-control/__tests__/MediaControl.test.ts +4 -3
  36. package/src/testUtils.ts +4 -2
  37. package/temp/player.api.json +243 -0
  38. package/tsconfig.tsbuildinfo +1 -1
@@ -34,7 +34,7 @@ export class BigMuteButton extends UICorePlugin {
34
34
  */
35
35
  get events() {
36
36
  return {
37
- 'click .big-mute-icon': 'handleBigMuteBtnClick',
37
+ 'click .big-mute-icon': 'clicked',
38
38
  'click .big-mute-icon-wrapper': 'destroyBigMuteBtn',
39
39
  };
40
40
  }
@@ -48,6 +48,7 @@ export class BigMuteButton extends UICorePlugin {
48
48
  trace(`${T} bindEvents`, {
49
49
  mediacontrol: !!this.core.mediaControl,
50
50
  });
51
+ // TOOD use core.getPlugin('media_control')
51
52
  this.listenTo(this.core.mediaControl, Events.MEDIACONTROL_RENDERED, this.mediaControlRendered);
52
53
  }
53
54
  onCoreReady() {
@@ -141,7 +142,7 @@ export class BigMuteButton extends UICorePlugin {
141
142
  }
142
143
  this.destroy();
143
144
  }
144
- handleBigMuteBtnClick(e) {
145
+ clicked(e) {
145
146
  const localVolume = Utils.Config.restore('volume');
146
147
  const volume = !isNaN(localVolume) ? localVolume : 100;
147
148
  // TODO use container.setVolume() instead
@@ -0,0 +1,45 @@
1
+ import { Core, CorePlugin } from '@clappr/core';
2
+ /**
3
+ * @beta
4
+ */
5
+ export type CmcdConfigPluginSettings = {
6
+ /**
7
+ * Session ID. If ommitted, a random UUID will be generated
8
+ */
9
+ sessionId: string;
10
+ /**
11
+ * Content ID,
12
+ * If ommitted, the pathname part of the first source URL will be used
13
+ */
14
+ contentId?: string;
15
+ };
16
+ /**
17
+ * A `PLUGIN` that configures CMCD for playback
18
+ * @beta
19
+ * @remarks
20
+ * Configuration options
21
+ * `cmcd`: {@link CmcdConfigPluginSettings}
22
+ */
23
+ export declare class CmcdConfig extends CorePlugin {
24
+ private sid;
25
+ private cid;
26
+ /**
27
+ * @inheritdocs
28
+ */
29
+ get name(): string;
30
+ get version(): string;
31
+ get supportedVersion(): string;
32
+ constructor(core: Core);
33
+ /**
34
+ * @inheritdocs
35
+ */
36
+ bindEvents(): void;
37
+ exportIds(): {
38
+ sid: string;
39
+ cid: string;
40
+ };
41
+ private updateSettings;
42
+ private updateHlsjsSettings;
43
+ private generateContentId;
44
+ }
45
+ //# sourceMappingURL=CmcdConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CmcdConfig.d.ts","sourceRoot":"","sources":["../../../src/plugins/cmcd-config/CmcdConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,IAAI,EAAE,UAAU,EAAU,MAAM,cAAc,CAAA;AA6BrE;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;;OAEG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAID;;;;;;GAMG;AACH,qBAAa,UAAW,SAAQ,UAAU;IACxC,OAAO,CAAC,GAAG,CAAQ;IAEnB,OAAO,CAAC,GAAG,CAAK;IAEhB;;OAEG;IACH,IAAI,IAAI,WAEP;IAED,IAAI,OAAO,WAEV;IAED,IAAI,gBAAgB,WAEnB;gBAEW,IAAI,EAAE,IAAI;IAMtB;;OAEG;IACM,UAAU;IAMnB,SAAS,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;YAO3B,cAAc;IA8B5B,OAAO,CAAC,mBAAmB;IAiB3B,OAAO,CAAC,iBAAiB;CAK1B"}
@@ -0,0 +1,110 @@
1
+ import { $, CorePlugin, Events } from '@clappr/core';
2
+ // import { trace } from '@gcorevideo/utils'
3
+ import { generateSessionId } from './utils';
4
+ import { CLAPPR_VERSION } from '../../build.js';
5
+ const CMCD_KEYS = [
6
+ 'br',
7
+ 'd',
8
+ 'ot',
9
+ 'tb',
10
+ 'bl',
11
+ 'dl',
12
+ 'mtp',
13
+ 'nor',
14
+ 'nrr',
15
+ 'su',
16
+ 'bs',
17
+ 'rtp',
18
+ 'cid',
19
+ 'pr',
20
+ 'sf',
21
+ 'sid',
22
+ 'st',
23
+ 'v',
24
+ ];
25
+ // const T = 'plugins.cmcd'
26
+ /**
27
+ * A `PLUGIN` that configures CMCD for playback
28
+ * @beta
29
+ * @remarks
30
+ * Configuration options
31
+ * `cmcd`: {@link CmcdConfigPluginSettings}
32
+ */
33
+ export class CmcdConfig extends CorePlugin {
34
+ sid;
35
+ cid = '';
36
+ /**
37
+ * @inheritdocs
38
+ */
39
+ get name() {
40
+ return 'cmcd';
41
+ }
42
+ get version() {
43
+ return '0.1.0';
44
+ }
45
+ get supportedVersion() {
46
+ return CLAPPR_VERSION;
47
+ }
48
+ constructor(core) {
49
+ super(core);
50
+ this.sid = this.options.cmcd?.sessionId ?? generateSessionId();
51
+ this.cid = this.options.cmcd?.contentId ?? this.generateContentId();
52
+ }
53
+ /**
54
+ * @inheritdocs
55
+ */
56
+ bindEvents() {
57
+ this.listenTo(this.core, Events.CORE_CONTAINERS_CREATED, () => this.updateSettings(this.core.containers[0]));
58
+ }
59
+ exportIds() {
60
+ return {
61
+ sid: this.sid,
62
+ cid: this.cid,
63
+ };
64
+ }
65
+ async updateSettings(container) {
66
+ switch (container.playback.name) {
67
+ case 'dash':
68
+ $.extend(true, container.playback.options, {
69
+ dash: {
70
+ cmcd: {
71
+ enabled: true,
72
+ enabledKeys: CMCD_KEYS,
73
+ sid: this.sid,
74
+ cid: this.cid,
75
+ },
76
+ },
77
+ });
78
+ break;
79
+ case 'hls':
80
+ $.extend(true, container.playback.options, {
81
+ playback: {
82
+ hlsjsConfig: {
83
+ cmcd: {
84
+ includeKeys: CMCD_KEYS,
85
+ sessionId: this.sid,
86
+ contentId: this.cid,
87
+ },
88
+ },
89
+ },
90
+ });
91
+ break;
92
+ }
93
+ }
94
+ updateHlsjsSettings(options, { cid, sid }) {
95
+ $.extend(true, options, {
96
+ playback: {
97
+ hlsjsConfig: {
98
+ cmcd: {
99
+ includeKeys: CMCD_KEYS,
100
+ sessionId: sid,
101
+ contentId: cid,
102
+ },
103
+ },
104
+ },
105
+ });
106
+ }
107
+ generateContentId() {
108
+ return new URL(this.core.options.source ?? this.core.options.sources[0].source).pathname.slice(0, 64);
109
+ }
110
+ }
@@ -0,0 +1,2 @@
1
+ export declare function generateSessionId(): string;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/plugins/cmcd-config/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C"}
@@ -0,0 +1,3 @@
1
+ export function generateSessionId() {
2
+ return window.crypto.randomUUID();
3
+ }
@@ -5,6 +5,7 @@ export declare function createMockCore(options?: Record<string, unknown>, contai
5
5
  $el: any;
6
6
  activePlayback: any;
7
7
  activeContainer: any;
8
+ containers: any[];
8
9
  i18n: {
9
10
  t: import("vitest").Mock<(...args: any[]) => any>;
10
11
  };
@@ -28,7 +29,7 @@ export declare function createSpinnerPlugin(): Events<string | symbol, any> & {
28
29
  show: import("vitest").Mock<(...args: any[]) => any>;
29
30
  hide: import("vitest").Mock<(...args: any[]) => any>;
30
31
  };
31
- export declare function createMockPlayback(name?: string): Events<string | symbol, any> & {
32
+ export declare function createMockPlayback(name?: string, options?: Record<string, unknown>): Events<string | symbol, any> & {
32
33
  name: string;
33
34
  currentLevel: number;
34
35
  el: HTMLVideoElement;
@@ -36,6 +37,9 @@ export declare function createMockPlayback(name?: string): Events<string | symbo
36
37
  dvrInUse: boolean;
37
38
  isAudioOnly: boolean;
38
39
  levels: never[];
40
+ options: {
41
+ [x: string]: unknown;
42
+ };
39
43
  consent: import("vitest").Mock<(...args: any[]) => any>;
40
44
  play: import("vitest").Mock<(...args: any[]) => any>;
41
45
  pause: import("vitest").Mock<(...args: any[]) => any>;
@@ -1 +1 @@
1
- {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,MAAM,MAAM,eAAe,CAAA;AAGlC,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAAkC;;;;;;;;;;;;;;;;EAqB9C;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmC/C;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,QAAQ,GAAE,GAA0B;;;;;;;;;;;;;;;;;;;;;;;;EA6BrC;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,gBAiB/C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,OAe7C"}
1
+ {"version":3,"file":"testUtils.d.ts","sourceRoot":"","sources":["../src/testUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,MAAM,MAAM,eAAe,CAAA;AAGlC,wBAAgB,cAAc,CAC5B,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,SAAS,GAAE,GAAkC;;;;;;;;;;;;;;;;;EAsB9C;AAED,wBAAgB,gBAAgB;;;EAK/B;AAED,wBAAgB,mBAAmB;;;;;;EAKlC;AAED,wBAAgB,kBAAkB,CAAC,IAAI,SAAS,EAAE,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCtF;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACrC,QAAQ,GAAE,GAAgD;;;;;;;;;;;;;;;;;;;;;;;;EA6B3D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,gBAiB/C;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,OAe7C"}
package/lib/testUtils.js CHANGED
@@ -9,6 +9,7 @@ export function createMockCore(options = {}, container = createMockContainer(opt
9
9
  $el: $(el),
10
10
  activePlayback: container.playback,
11
11
  activeContainer: container,
12
+ containers: [container],
12
13
  i18n: {
13
14
  t: vi.fn().mockImplementation((key) => key),
14
15
  },
@@ -34,7 +35,7 @@ export function createSpinnerPlugin() {
34
35
  hide: vi.fn(),
35
36
  });
36
37
  }
37
- export function createMockPlayback(name = 'mock') {
38
+ export function createMockPlayback(name = 'mock', options = {}) {
38
39
  const emitter = new Events();
39
40
  return Object.assign(emitter, {
40
41
  name,
@@ -44,6 +45,7 @@ export function createMockPlayback(name = 'mock') {
44
45
  dvrInUse: false,
45
46
  isAudioOnly: false,
46
47
  levels: [],
48
+ options: { ...options },
47
49
  consent: vi.fn(),
48
50
  play: vi.fn(),
49
51
  pause: vi.fn(),
@@ -70,7 +72,7 @@ export function createMockPlayback(name = 'mock') {
70
72
  trigger: emitter.emit,
71
73
  });
72
74
  }
73
- export function createMockContainer(options = {}, playback = createMockPlayback()) {
75
+ export function createMockContainer(options = {}, playback = createMockPlayback('html5_video', options)) {
74
76
  const el = playback.el;
75
77
  const emitter = new Events();
76
78
  return Object.assign(emitter, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gcorevideo/player",
3
- "version": "2.23.3",
3
+ "version": "2.24.1",
4
4
  "description": "Gcore JavaScript video player",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -5,6 +5,7 @@ export { AudioTracks as AudioSelector } from "./plugins/audio-selector/AudioTrac
5
5
  export * from "./plugins/big-mute-button/BigMuteButton.js";
6
6
  export * from "./plugins/bottom-gear/BottomGear.js";
7
7
  export * from "./plugins/clappr-stats/ClapprStats.js";
8
+ export * from "./plugins/cmcd-config/CmcdConfig.js";
8
9
  export * from "./plugins/clappr-nerd-stats/NerdStats.js";
9
10
  export { NerdStats as ClapprNerdStats } from "./plugins/clappr-nerd-stats/NerdStats.js";
10
11
  export * from "./plugins/click-to-pause/ClickToPause.js";
@@ -47,7 +47,7 @@ export class BigMuteButton extends UICorePlugin {
47
47
  */
48
48
  override get events() {
49
49
  return {
50
- 'click .big-mute-icon': 'handleBigMuteBtnClick',
50
+ 'click .big-mute-icon': 'clicked',
51
51
  'click .big-mute-icon-wrapper': 'destroyBigMuteBtn',
52
52
  }
53
53
  }
@@ -62,6 +62,7 @@ export class BigMuteButton extends UICorePlugin {
62
62
  trace(`${T} bindEvents`, {
63
63
  mediacontrol: !!this.core.mediaControl,
64
64
  })
65
+ // TOOD use core.getPlugin('media_control')
65
66
  this.listenTo(
66
67
  this.core.mediaControl,
67
68
  Events.MEDIACONTROL_RENDERED,
@@ -199,7 +200,7 @@ export class BigMuteButton extends UICorePlugin {
199
200
  this.destroy()
200
201
  }
201
202
 
202
- private handleBigMuteBtnClick(e: MouseEvent) {
203
+ private clicked(e: MouseEvent) {
203
204
  const localVolume = Utils.Config.restore('volume')
204
205
  const volume = !isNaN(localVolume) ? localVolume : 100
205
206
 
@@ -0,0 +1,148 @@
1
+ import { $, Container, Core, CorePlugin, Events } from '@clappr/core'
2
+
3
+ // import { trace } from '@gcorevideo/utils'
4
+
5
+ import { generateSessionId } from './utils'
6
+ import { CLAPPR_VERSION } from '../../build.js'
7
+ import { CoreOptions } from 'src/internal.types'
8
+
9
+ const CMCD_KEYS = [
10
+ 'br',
11
+ 'd',
12
+ 'ot',
13
+ 'tb',
14
+ 'bl',
15
+ 'dl',
16
+ 'mtp',
17
+ 'nor',
18
+ 'nrr',
19
+ 'su',
20
+ 'bs',
21
+ 'rtp',
22
+ 'cid',
23
+ 'pr',
24
+ 'sf',
25
+ 'sid',
26
+ 'st',
27
+ 'v',
28
+ ]
29
+
30
+ /**
31
+ * @beta
32
+ */
33
+ export type CmcdConfigPluginSettings = {
34
+ /**
35
+ * Session ID. If ommitted, a random UUID will be generated
36
+ */
37
+ sessionId: string
38
+ /**
39
+ * Content ID,
40
+ * If ommitted, the pathname part of the first source URL will be used
41
+ */
42
+ contentId?: string
43
+ }
44
+
45
+ // const T = 'plugins.cmcd'
46
+
47
+ /**
48
+ * A `PLUGIN` that configures CMCD for playback
49
+ * @beta
50
+ * @remarks
51
+ * Configuration options
52
+ * `cmcd`: {@link CmcdConfigPluginSettings}
53
+ */
54
+ export class CmcdConfig extends CorePlugin {
55
+ private sid: string
56
+
57
+ private cid = ''
58
+
59
+ /**
60
+ * @inheritdocs
61
+ */
62
+ get name() {
63
+ return 'cmcd'
64
+ }
65
+
66
+ get version() {
67
+ return '0.1.0'
68
+ }
69
+
70
+ get supportedVersion() {
71
+ return CLAPPR_VERSION
72
+ }
73
+
74
+ constructor(core: Core) {
75
+ super(core)
76
+ this.sid = this.options.cmcd?.sessionId ?? generateSessionId()
77
+ this.cid = this.options.cmcd?.contentId ?? this.generateContentId()
78
+ }
79
+
80
+ /**
81
+ * @inheritdocs
82
+ */
83
+ override bindEvents() {
84
+ this.listenTo(this.core, Events.CORE_CONTAINERS_CREATED, () =>
85
+ this.updateSettings(this.core.containers[0]),
86
+ )
87
+ }
88
+
89
+ exportIds(): { sid: string; cid: string } {
90
+ return {
91
+ sid: this.sid,
92
+ cid: this.cid,
93
+ }
94
+ }
95
+
96
+ private async updateSettings(container: Container) {
97
+ switch (container.playback.name) {
98
+ case 'dash':
99
+ $.extend(true, container.playback.options, {
100
+ dash: {
101
+ cmcd: {
102
+ enabled: true,
103
+ enabledKeys: CMCD_KEYS,
104
+ sid: this.sid,
105
+ cid: this.cid,
106
+ },
107
+ },
108
+ })
109
+ break
110
+ case 'hls':
111
+ $.extend(true, container.playback.options, {
112
+ playback: {
113
+ hlsjsConfig: {
114
+ cmcd: {
115
+ includeKeys: CMCD_KEYS,
116
+ sessionId: this.sid,
117
+ contentId: this.cid,
118
+ },
119
+ },
120
+ },
121
+ })
122
+ break
123
+ }
124
+ }
125
+
126
+ private updateHlsjsSettings(
127
+ options: CoreOptions,
128
+ { cid, sid }: { cid: string; sid: string },
129
+ ) {
130
+ $.extend(true, options, {
131
+ playback: {
132
+ hlsjsConfig: {
133
+ cmcd: {
134
+ includeKeys: CMCD_KEYS,
135
+ sessionId: sid,
136
+ contentId: cid,
137
+ },
138
+ },
139
+ },
140
+ })
141
+ }
142
+
143
+ private generateContentId() {
144
+ return new URL(
145
+ this.core.options.source ?? this.core.options.sources[0].source,
146
+ ).pathname.slice(0, 64)
147
+ }
148
+ }
@@ -0,0 +1,174 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
2
+
3
+ import { CmcdConfig } from '../CmcdConfig'
4
+ import { createMockCore } from '../../../testUtils'
5
+ import { Events } from '@clappr/core'
6
+
7
+ vi.mock('../utils', () => ({
8
+ generateSessionId: vi.fn().mockReturnValue('123'),
9
+ }))
10
+
11
+ const CMCD_KEYS = [
12
+ 'br',
13
+ 'd',
14
+ 'ot',
15
+ 'tb',
16
+ 'bl',
17
+ 'dl',
18
+ 'mtp',
19
+ 'nor',
20
+ 'nrr',
21
+ 'su',
22
+ 'bs',
23
+ 'rtp',
24
+ 'cid',
25
+ 'pr',
26
+ 'sf',
27
+ 'sid',
28
+ 'st',
29
+ 'v',
30
+ ]
31
+
32
+ describe('CmcdConfig', () => {
33
+ let core: any
34
+ let plugin: CmcdConfig
35
+ describe('basically', () => {
36
+ beforeEach(() => {
37
+ core = createMockCore({
38
+ sources: [
39
+ {
40
+ source: 'https://zulu.com/123.mpd',
41
+ mimeType: 'application/dash+xml',
42
+ },
43
+ ],
44
+ })
45
+ })
46
+ describe('when container is created', () => {
47
+ describe('dash.js', () => {
48
+ beforeEach(async () => {
49
+ core.containers[0].playback.name = 'dash'
50
+ plugin = new CmcdConfig(core)
51
+ core.trigger(Events.CORE_CONTAINERS_CREATED)
52
+ await new Promise((resolve) => setTimeout(resolve, 0))
53
+ })
54
+ it('should update DASH.js CMCD settings', () => {
55
+ expect(core.containers[0].playback.options).toEqual(
56
+ expect.objectContaining({
57
+ dash: expect.objectContaining({
58
+ cmcd: expect.objectContaining({
59
+ enabled: true,
60
+ enabledKeys: CMCD_KEYS,
61
+ }),
62
+ }),
63
+ }),
64
+ )
65
+ })
66
+ it('should generate unique session ID', () => {
67
+ expect(core.containers[0].playback.options).toEqual(
68
+ expect.objectContaining({
69
+ dash: expect.objectContaining({
70
+ cmcd: expect.objectContaining({
71
+ sid: '123',
72
+ }),
73
+ }),
74
+ }),
75
+ )
76
+ })
77
+ it('should compute content ID from source URL', () => {
78
+ expect(core.containers[0].playback.options).toEqual(
79
+ expect.objectContaining({
80
+ dash: expect.objectContaining({
81
+ cmcd: expect.objectContaining({
82
+ cid: '/123.mpd',
83
+ }),
84
+ }),
85
+ }),
86
+ )
87
+ })
88
+ })
89
+ describe('hls.js', () => {
90
+ beforeEach(async () => {
91
+ core.containers[0].playback.name = 'hls'
92
+ plugin = new CmcdConfig(core)
93
+ core.trigger(Events.CORE_CONTAINERS_CREATED)
94
+ })
95
+ it('should update HLS.js CMCD settings', () => {
96
+ expect(core.containers[0].playback.options).toEqual(
97
+ expect.objectContaining({
98
+ playback: expect.objectContaining({
99
+ hlsjsConfig: expect.objectContaining({
100
+ cmcd: expect.objectContaining({
101
+ includeKeys: CMCD_KEYS,
102
+ contentId: '/123.mpd',
103
+ sessionId: '123',
104
+ }),
105
+ }),
106
+ }),
107
+ }),
108
+ )
109
+ })
110
+ })
111
+ })
112
+ })
113
+ describe('custom content ID', () => {
114
+ beforeEach(async () => {
115
+ core = createMockCore({
116
+ cmcd: {
117
+ contentId:
118
+ 'e287ea99b57c09b7a185aaaf36e075f2c0b346ce90aeced72976b1732678a8c6',
119
+ },
120
+ sources: [
121
+ {
122
+ source: 'https://zulu.com/123.mpd',
123
+ mimeType: 'application/dash+xml',
124
+ },
125
+ ],
126
+ })
127
+ core.containers[0].playback.name = 'dash'
128
+ core.containers[0].playback.options.src = 'https://123.mpd'
129
+ plugin = new CmcdConfig(core)
130
+ core.trigger(Events.CORE_CONTAINERS_CREATED)
131
+ await new Promise((resolve) => setTimeout(resolve, 0))
132
+ })
133
+ it('should use custom content ID', () => {
134
+ expect(core.containers[0].playback.options).toEqual(
135
+ expect.objectContaining({
136
+ dash: expect.objectContaining({
137
+ cmcd: expect.objectContaining({
138
+ cid: 'e287ea99b57c09b7a185aaaf36e075f2c0b346ce90aeced72976b1732678a8c6',
139
+ }),
140
+ }),
141
+ }),
142
+ )
143
+ })
144
+ })
145
+ describe('custom session ID', () => {
146
+ beforeEach(async () => {
147
+ core = createMockCore({
148
+ cmcd: { sessionId: '456' },
149
+ sources: [
150
+ {
151
+ source: 'https://zulu.com/123.mpd',
152
+ mimeType: 'application/dash+xml',
153
+ },
154
+ ],
155
+ })
156
+ core.containers[0].playback.name = 'dash'
157
+ core.containers[0].playback.options.src = 'https://123.mpd'
158
+ plugin = new CmcdConfig(core)
159
+ core.trigger(Events.CORE_CONTAINERS_CREATED)
160
+ await new Promise((resolve) => setTimeout(resolve, 0))
161
+ })
162
+ it('should use custom session ID', () => {
163
+ expect(core.containers[0].playback.options).toEqual(
164
+ expect.objectContaining({
165
+ dash: expect.objectContaining({
166
+ cmcd: expect.objectContaining({
167
+ sid: '456',
168
+ }),
169
+ }),
170
+ }),
171
+ )
172
+ })
173
+ })
174
+ })
@@ -0,0 +1,3 @@
1
+ export function generateSessionId(): string {
2
+ return window.crypto.randomUUID()
3
+ }
@@ -5,7 +5,6 @@ import {
5
5
  MediaControlSettings,
6
6
  } from '../MediaControl'
7
7
  import { createMockCore } from '../../../testUtils'
8
- import { LogTracer, Logger, setTracer } from '@gcorevideo/utils'
9
8
  import { $, Events, Playback } from '@clappr/core'
10
9
 
11
10
  vi.mock('../../utils/fullscreen', () => ({
@@ -13,8 +12,10 @@ vi.mock('../../utils/fullscreen', () => ({
13
12
  isFullscreen: vi.fn().mockReturnValue(false),
14
13
  }))
15
14
 
16
- Logger.enable('*')
17
- setTracer(new LogTracer('MediaControl.test'))
15
+ // import { LogTracer, Logger, setTracer } from '@gcorevideo/utils'
16
+
17
+ // Logger.enable('*')
18
+ // setTracer(new LogTracer('MediaControl.test'))
18
19
 
19
20
  describe('MediaControl', () => {
20
21
  let core: any
package/src/testUtils.ts CHANGED
@@ -13,6 +13,7 @@ export function createMockCore(
13
13
  $el: $(el),
14
14
  activePlayback: container.playback,
15
15
  activeContainer: container,
16
+ containers: [container],
16
17
  i18n: {
17
18
  t: vi.fn().mockImplementation((key: string) => key),
18
19
  },
@@ -41,7 +42,7 @@ export function createSpinnerPlugin() {
41
42
  })
42
43
  }
43
44
 
44
- export function createMockPlayback(name = 'mock') {
45
+ export function createMockPlayback(name = 'mock', options: Record<string, unknown> = {}) {
45
46
  const emitter = new Events()
46
47
  return Object.assign(emitter, {
47
48
  name,
@@ -51,6 +52,7 @@ export function createMockPlayback(name = 'mock') {
51
52
  dvrInUse: false,
52
53
  isAudioOnly: false,
53
54
  levels: [],
55
+ options: { ...options },
54
56
  consent: vi.fn(),
55
57
  play: vi.fn(),
56
58
  pause: vi.fn(),
@@ -80,7 +82,7 @@ export function createMockPlayback(name = 'mock') {
80
82
 
81
83
  export function createMockContainer(
82
84
  options: Record<string, unknown> = {},
83
- playback: any = createMockPlayback(),
85
+ playback: any = createMockPlayback('html5_video', options),
84
86
  ) {
85
87
  const el = playback.el
86
88
  const emitter = new Events()