@npo/player 1.24.7 → 1.26.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.
Files changed (170) hide show
  1. package/README.md +1 -1
  2. package/lib/js/api/getstreamobject.d.ts +1 -1
  3. package/lib/js/api/getstreamobject.js +4 -4
  4. package/lib/js/api/getstreamobject.test.js +13 -13
  5. package/lib/js/playeractions/handlers/handleoffsets.js +9 -7
  6. package/lib/js/playeractions/handlers/handleoffsets.test.js +1 -1
  7. package/lib/js/playeractions/handlers/processplayerconfig.d.ts +1 -1
  8. package/lib/js/playeractions/handlers/processplayerconfig.js +18 -4
  9. package/lib/js/playeractions/handlers/processplayerconfig.test.js +116 -0
  10. package/lib/js/playeractions/handlers/processsourceconfig.d.ts +3 -1
  11. package/lib/js/playeractions/handlers/processsourceconfig.js +20 -10
  12. package/lib/js/playeractions/handlers/processsourceconfig.test.js +25 -0
  13. package/lib/js/settings/localization.d.ts +76 -1
  14. package/lib/js/settings/localization.js +2 -2
  15. package/lib/js/tracking/handlers/eventbinding.js +25 -17
  16. package/lib/js/tracking/handlers/eventlogging.js +3 -8
  17. package/lib/js/tracking/handlers/playertrackerinit.d.ts +2 -2
  18. package/lib/js/tracking/handlers/playertrackerinit.js +8 -6
  19. package/lib/js/tracking/handlers/playertrackerinit.test.d.ts +1 -0
  20. package/lib/js/tracking/handlers/playertrackerinit.test.js +74 -0
  21. package/lib/js/tracking/handlers/playertrackerstart.js +1 -1
  22. package/lib/js/utilities/utilities.element.d.ts +6 -0
  23. package/lib/js/utilities/utilities.element.js +10 -0
  24. package/lib/js/utilities/utilities.element.test.js +18 -5
  25. package/lib/lang/nl.json +1 -1
  26. package/lib/lang/subtitleLabels/nl.json +14 -0
  27. package/lib/npoplayer.d.ts +15 -6
  28. package/lib/npoplayer.js +57 -50
  29. package/lib/npoplayer.test.js +12 -4
  30. package/lib/package.json +3 -3
  31. package/lib/services/a11y/setup.js +2 -5
  32. package/lib/services/a11y/setup.test.js +2 -19
  33. package/lib/services/advertHandlers/discardAdBreak.js +4 -4
  34. package/lib/services/advertHandlers/discardAdBreak.test.js +25 -13
  35. package/lib/services/advertHandlers/handlePreRolls.js +19 -19
  36. package/lib/services/advertHandlers/handlePrerolls.test.js +4 -4
  37. package/lib/services/cdnProviders/cdnProviders.js +4 -2
  38. package/lib/services/drmHandlers/decideprofile.js +1 -1
  39. package/lib/services/drmHandlers/decideprofile.test.js +1 -1
  40. package/lib/services/drmHandlers/verifydrm.js +6 -6
  41. package/lib/services/drmHandlers/verifydrm.test.js +5 -5
  42. package/lib/services/eventListenerHandlers/removeEventListeners.js +2 -2
  43. package/lib/services/eventListenerHandlers/removeEventListeners.test.js +9 -9
  44. package/lib/services/keyboardHandlers/resolvekeypress.js +5 -5
  45. package/lib/services/keyboardHandlers/resolvekeypress.test.js +1 -1
  46. package/lib/services/liveStreamHandlers/handleLiveStreamControls.js +2 -2
  47. package/lib/services/liveStreamHandlers/handleLiveStreamControls.test.js +2 -2
  48. package/lib/services/localStorageHandlers/localStorageHandlers.js +2 -2
  49. package/lib/services/localStorageHandlers/localStorageHandlers.test.js +2 -5
  50. package/lib/services/nicamHandlers/nicamhandler.d.ts +5 -0
  51. package/lib/{ui/handlers → services/nicamHandlers}/nicamhandler.js +24 -15
  52. package/lib/services/nicamHandlers/nicamhandler.test.js +132 -0
  53. package/lib/services/npoPlayerAPI/npoPlayerAPI.d.ts +3 -2
  54. package/lib/services/npoPlayerAPI/npoPlayerAPI.js +19 -23
  55. package/lib/services/preferences/handlePreferences.d.ts +2 -0
  56. package/lib/services/preferences/handlePreferences.js +42 -0
  57. package/lib/services/preferences/handlePreferences.test.d.ts +1 -0
  58. package/lib/services/preferences/handlePreferences.test.js +102 -0
  59. package/lib/services/segmentHandlers/addSegmentEventListeners.js +2 -2
  60. package/lib/services/segmentHandlers/addSegmentEventListeners.test.js +1 -1
  61. package/lib/services/segmentHandlers/setSegmentMarkers.js +1 -1
  62. package/lib/services/services.d.ts +7 -0
  63. package/lib/services/services.js +26 -0
  64. package/lib/services/streamoptionsHandlers/streamOptionsHandler.d.ts +6 -0
  65. package/lib/services/streamoptionsHandlers/streamOptionsHandler.js +78 -0
  66. package/lib/services/streamoptionsHandlers/streamOptionsHandler.test.js +187 -0
  67. package/lib/services/uiHandlers/uiVisiblityHandler.d.ts +3 -0
  68. package/lib/services/uiHandlers/uiVisiblityHandler.js +26 -0
  69. package/lib/services/uiHandlers/uiVisiblityHandler.test.d.ts +1 -0
  70. package/lib/services/uiHandlers/uiVisiblityHandler.test.js +62 -0
  71. package/lib/src/js/api/getstreamobject.d.ts +1 -1
  72. package/lib/src/js/playeractions/handlers/processplayerconfig.d.ts +1 -1
  73. package/lib/src/js/playeractions/handlers/processplayerconfig.test.d.ts +1 -0
  74. package/lib/src/js/playeractions/handlers/processsourceconfig.d.ts +3 -1
  75. package/lib/src/js/playeractions/handlers/processsourceconfig.test.d.ts +1 -0
  76. package/lib/src/js/settings/localization.d.ts +76 -1
  77. package/lib/src/js/tracking/handlers/playertrackerinit.d.ts +2 -2
  78. package/lib/src/js/tracking/handlers/playertrackerinit.test.d.ts +1 -0
  79. package/lib/src/js/utilities/utilities.element.d.ts +6 -0
  80. package/lib/src/npoplayer.d.ts +15 -6
  81. package/lib/src/services/nicamHandlers/nicamhandler.d.ts +5 -0
  82. package/lib/src/services/nicamHandlers/nicamhandler.test.d.ts +1 -0
  83. package/lib/src/services/npoPlayerAPI/npoPlayerAPI.d.ts +3 -2
  84. package/lib/src/services/preferences/handlePreferences.d.ts +2 -0
  85. package/lib/src/services/preferences/handlePreferences.test.d.ts +1 -0
  86. package/lib/src/services/services.d.ts +7 -0
  87. package/lib/src/services/streamoptionsHandlers/streamOptionsHandler.d.ts +6 -0
  88. package/lib/src/services/streamoptionsHandlers/streamOptionsHandler.test.d.ts +1 -0
  89. package/lib/src/services/uiHandlers/uiVisiblityHandler.d.ts +3 -0
  90. package/lib/src/services/uiHandlers/uiVisiblityHandler.test.d.ts +1 -0
  91. package/lib/src/types/classes.d.ts +6 -0
  92. package/lib/src/types/interfaces.d.ts +25 -3
  93. package/lib/src/ui/components/adbutton.d.ts +1 -1
  94. package/lib/src/ui/components/adlabel.d.ts +1 -1
  95. package/lib/src/ui/components/buttons.d.ts +10 -17
  96. package/lib/src/ui/components/controlbar.d.ts +2 -2
  97. package/lib/src/ui/components/ctabar.d.ts +1 -1
  98. package/lib/src/ui/components/nativemobile/buttons.d.ts +8 -0
  99. package/lib/src/ui/components/playnext.d.ts +1 -3
  100. package/lib/src/ui/components/seekbar.d.ts +1 -1
  101. package/lib/src/ui/components/titlebar.d.ts +1 -1
  102. package/lib/src/ui/components/topbar.d.ts +2 -2
  103. package/lib/src/ui/components/verticalvideo/controlbar.d.ts +2 -2
  104. package/lib/src/ui/handlers/playnextscreen.test.d.ts +1 -0
  105. package/lib/src/ui/handlers/timecontrolhandlers.d.ts +3 -3
  106. package/lib/src/ui/uicontainer.d.ts +2 -3
  107. package/lib/src/ui/uicontainer.test.d.ts +1 -0
  108. package/lib/tests/mocks/mockLogEmitter.d.ts +2 -0
  109. package/lib/tests/mocks/mockLogEmitter.js +20 -0
  110. package/lib/tests/mocks/mockNpoplayer.js +4 -2
  111. package/lib/tests/mocks/playerContextMock.d.ts +5 -3
  112. package/lib/tests/mocks/playerContextMock.js +8 -5
  113. package/lib/types/classes.d.ts +6 -0
  114. package/lib/types/classes.js +12 -0
  115. package/lib/types/interfaces.d.ts +25 -3
  116. package/lib/types/interfaces.js +1 -0
  117. package/lib/ui/components/adbutton.d.ts +1 -1
  118. package/lib/ui/components/adbutton.js +3 -3
  119. package/lib/ui/components/adlabel.d.ts +1 -1
  120. package/lib/ui/components/adlabel.js +3 -3
  121. package/lib/ui/components/buttons.d.ts +10 -17
  122. package/lib/ui/components/buttons.js +44 -27
  123. package/lib/ui/components/controlbar.d.ts +2 -2
  124. package/lib/ui/components/controlbar.js +20 -32
  125. package/lib/ui/components/ctabar.d.ts +1 -1
  126. package/lib/ui/components/ctabar.js +4 -4
  127. package/lib/ui/components/nativemobile/buttons.d.ts +8 -0
  128. package/lib/ui/components/nativemobile/buttons.js +41 -1
  129. package/lib/ui/components/nativemobile/controlbar.js +1 -2
  130. package/lib/ui/components/nativemobile/topbar.js +2 -2
  131. package/lib/ui/components/playnext.d.ts +1 -3
  132. package/lib/ui/components/playnext.js +3 -3
  133. package/lib/ui/components/seekbar.d.ts +1 -1
  134. package/lib/ui/components/seekbar.js +5 -3
  135. package/lib/ui/components/settingspanel.js +9 -9
  136. package/lib/ui/components/titlebar.d.ts +1 -1
  137. package/lib/ui/components/titlebar.js +2 -2
  138. package/lib/ui/components/topbar.d.ts +2 -2
  139. package/lib/ui/components/topbar.js +8 -17
  140. package/lib/ui/components/verticalvideo/controlbar.d.ts +2 -2
  141. package/lib/ui/components/verticalvideo/controlbar.js +4 -4
  142. package/lib/ui/handlers/playnextscreen.test.d.ts +1 -0
  143. package/lib/ui/handlers/timecontrolhandlers.d.ts +3 -3
  144. package/lib/ui/nativemobileuifactory.js +20 -24
  145. package/lib/ui/nativemobileuifactory.test.js +2 -6
  146. package/lib/ui/uicontainer.d.ts +2 -3
  147. package/lib/ui/uicontainer.js +13 -30
  148. package/lib/ui/uicontainer.test.d.ts +1 -0
  149. package/lib/ui/uicontainer.test.js +80 -0
  150. package/package.json +3 -3
  151. package/src/style/components/_advert.scss +0 -9
  152. package/src/style/components/_icons.scss +5 -0
  153. package/src/style/components/_nicam.scss +5 -4
  154. package/src/style/components/_settingspanel.scss +48 -17
  155. package/src/style/components/vertical-video/_settingspanel.scss +1 -1
  156. package/src/style/npoplayer.css +26 -20
  157. package/src/style/variants/_player-base.scss +4 -0
  158. package/src/style/variants/_player-large.scss +5 -1
  159. package/src/style/variants/_player-small.scss +11 -8
  160. package/lib/src/ui/handlers/nicamhandler.d.ts +0 -6
  161. package/lib/src/ui/handlers/streamhandler.d.ts +0 -2
  162. package/lib/ui/handlers/nicamhandler.d.ts +0 -6
  163. package/lib/ui/handlers/nicamhandler.test.js +0 -36
  164. package/lib/ui/handlers/streamhandler.d.ts +0 -2
  165. package/lib/ui/handlers/streamhandler.js +0 -60
  166. /package/lib/{src/ui/handlers/playnextstreen.test.d.ts → js/playeractions/handlers/processplayerconfig.test.d.ts} +0 -0
  167. /package/lib/{ui/handlers/playnextstreen.test.d.ts → js/playeractions/handlers/processsourceconfig.test.d.ts} +0 -0
  168. /package/lib/{src/ui/handlers → services/nicamHandlers}/nicamhandler.test.d.ts +0 -0
  169. /package/lib/{ui/handlers/nicamhandler.test.d.ts → services/streamoptionsHandlers/streamOptionsHandler.test.d.ts} +0 -0
  170. /package/lib/ui/handlers/{playnextstreen.test.js → playnextscreen.test.js} +0 -0
@@ -1,15 +1,17 @@
1
1
  import { newATInternetPlugin, newGovoltePlugin, newPageTracker, newTag } from '@npotag/tag';
2
2
  const npoTagPlugins = [newGovoltePlugin({ maxRetryCount: 5, delayBetweenRetriesInMs: 3000 }), newATInternetPlugin()];
3
- export function initPlayerTracker(npoplayer, _npotag, _npotaginstance) {
4
- if (npoplayer.npoTag == undefined) {
5
- npoplayer.npoTag = {
3
+ export function initPlayerTracker(npoPlayer, _npoTag, _npoTagInstance, _npoTagPageTracker) {
4
+ if (!npoPlayer.npoTag) {
5
+ npoPlayer.npoTag = {
6
6
  npoTagInstance: undefined,
7
7
  pageTracker: undefined,
8
8
  heartbeatInterval: undefined
9
9
  };
10
10
  }
11
- npoplayer.npoTag.npoTagInstance = _npotag == undefined ? _npotaginstance : newTag(_npotag, npoTagPlugins);
12
- if (npoplayer.npoTag.npoTagInstance != undefined) {
13
- npoplayer.npoTag.pageTracker = newPageTracker(npoplayer.npoTag.npoTagInstance);
11
+ if (!npoPlayer.npoTag?.npoTagInstance) {
12
+ npoPlayer.npoTag.npoTagInstance = _npoTagInstance ?? (_npoTag ? newTag(_npoTag, npoTagPlugins) : undefined);
13
+ }
14
+ if (!npoPlayer.npoTag?.pageTracker && npoPlayer.npoTag?.npoTagInstance) {
15
+ npoPlayer.npoTag.pageTracker = _npoTagPageTracker ?? newPageTracker(npoPlayer.npoTag.npoTagInstance);
14
16
  }
15
17
  }
@@ -0,0 +1,74 @@
1
+ import { newPageTracker, newTag } from '@npotag/tag';
2
+ import { initPlayerTracker } from './playertrackerinit';
3
+ jest.mock('@npotag/tag', () => ({
4
+ newATInternetPlugin: jest.fn(),
5
+ newGovoltePlugin: jest.fn(),
6
+ newPageTracker: jest.fn(),
7
+ newTag: jest.fn()
8
+ }));
9
+ describe('initPlayerTracker', () => {
10
+ let mockNpoPlayer;
11
+ beforeEach(() => {
12
+ mockNpoPlayer = {
13
+ npoTag: undefined
14
+ };
15
+ jest.clearAllMocks();
16
+ });
17
+ it('should initialize npoTag if it is undefined', () => {
18
+ initPlayerTracker(mockNpoPlayer);
19
+ expect(mockNpoPlayer.npoTag).toBeDefined();
20
+ expect(mockNpoPlayer.npoTag?.npoTagInstance).toBeUndefined();
21
+ expect(mockNpoPlayer.npoTag?.pageTracker).toBeUndefined();
22
+ });
23
+ it('should initialize npoTagInstance if _npoTagInstance is provided', () => {
24
+ const mockNpoTagInstance = {};
25
+ initPlayerTracker(mockNpoPlayer, undefined, mockNpoTagInstance);
26
+ expect(mockNpoPlayer.npoTag?.npoTagInstance).toBe(mockNpoTagInstance);
27
+ expect(mockNpoPlayer.npoTag?.pageTracker).toBeUndefined();
28
+ });
29
+ it('should create a new npoTagInstance if _npoTag is provided and _npoTagInstance is undefined', () => {
30
+ const mockNpoTag = {};
31
+ const mockNewTagInstance = {};
32
+ newTag.mockReturnValue(mockNewTagInstance);
33
+ initPlayerTracker(mockNpoPlayer, mockNpoTag);
34
+ expect(newTag).toHaveBeenCalledWith(mockNpoTag, expect.any(Array));
35
+ expect(mockNpoPlayer.npoTag?.npoTagInstance).toBe(mockNewTagInstance);
36
+ expect(mockNpoPlayer.npoTag?.pageTracker).toBeUndefined();
37
+ });
38
+ it('should initialize pageTracker if _npoTagPageTracker is provided', () => {
39
+ const mockPageTracker = {};
40
+ const mockNpoTagInstance = {};
41
+ mockNpoPlayer.npoTag = {
42
+ npoTagInstance: mockNpoTagInstance,
43
+ pageTracker: undefined,
44
+ heartbeatInterval: undefined
45
+ };
46
+ initPlayerTracker(mockNpoPlayer, undefined, mockNpoTagInstance, mockPageTracker);
47
+ expect(mockNpoPlayer.npoTag?.pageTracker).toBe(mockPageTracker);
48
+ });
49
+ it('should create a new pageTracker if _npoTagPageTracker is undefined', () => {
50
+ const mockNpoTagInstance = {};
51
+ const mockNewPageTracker = {};
52
+ newPageTracker.mockReturnValue(mockNewPageTracker);
53
+ mockNpoPlayer.npoTag = {
54
+ npoTagInstance: mockNpoTagInstance,
55
+ pageTracker: undefined,
56
+ heartbeatInterval: undefined
57
+ };
58
+ initPlayerTracker(mockNpoPlayer);
59
+ expect(newPageTracker).toHaveBeenCalledWith(mockNpoTagInstance);
60
+ expect(mockNpoPlayer.npoTag?.pageTracker).toBe(mockNewPageTracker);
61
+ });
62
+ it('should not overwrite existing pageTracker', () => {
63
+ const mockPageTracker = {};
64
+ const mockNpoTagInstance = {};
65
+ mockNpoPlayer.npoTag = {
66
+ npoTagInstance: mockNpoTagInstance,
67
+ pageTracker: mockPageTracker,
68
+ heartbeatInterval: undefined
69
+ };
70
+ initPlayerTracker(mockNpoPlayer);
71
+ expect(mockNpoPlayer.npoTag?.pageTracker).toBe(mockPageTracker);
72
+ expect(newPageTracker).not.toHaveBeenCalled();
73
+ });
74
+ });
@@ -12,7 +12,7 @@ export function startPlayerTracker(playerInstance, duration, version, source) {
12
12
  stream_length: duration,
13
13
  stream_id: validatePrid(source),
14
14
  player_id: 'npoplayer-web',
15
- av_type: playerInstance.npoplayerServices.getAVType(playerInstance.streamObject.stream.avType),
15
+ av_type: playerInstance.npoPlayerServices.getAVType(playerInstance.streamObject.stream.avType),
16
16
  player_version: version,
17
17
  sko_player_version: '1.0.0'
18
18
  };
@@ -4,7 +4,13 @@ interface ElementByQuery {
4
4
  }
5
5
  interface RemoveClassFromElementByQuery extends ElementByQuery {
6
6
  className: string;
7
+ condition: boolean;
8
+ }
9
+ export interface UpdateClassFromElementByQuery extends ElementByQuery {
10
+ className: string;
11
+ condition: boolean;
7
12
  }
8
13
  export declare function getElementByQuery({ container, query }: ElementByQuery): Element | null;
9
14
  export declare function removeClassFromElementByQuery(params: RemoveClassFromElementByQuery): void;
15
+ export declare function updateClassFromElementByQuery(params: UpdateClassFromElementByQuery): void;
10
16
  export {};
@@ -6,3 +6,13 @@ export function removeClassFromElementByQuery(params) {
6
6
  const element = getElementByQuery({ container, query });
7
7
  element?.classList.remove(className);
8
8
  }
9
+ export function updateClassFromElementByQuery(params) {
10
+ const { className, container, query, condition } = params;
11
+ const element = getElementByQuery({ container, query });
12
+ if (condition && element) {
13
+ element.classList.add(className);
14
+ }
15
+ else if (element) {
16
+ element.classList.remove(className);
17
+ }
18
+ }
@@ -1,5 +1,6 @@
1
- import { getElementByQuery, removeClassFromElementByQuery } from './utilities.element';
1
+ import { getElementByQuery, updateClassFromElementByQuery } from './utilities.element';
2
2
  const CLASS = 'element-class';
3
+ const NEW_CLASS = 'new-class';
3
4
  const ID = 'element-id';
4
5
  const PARENT_ELEMENT = document.createElement('div');
5
6
  const CHILD_ELEMENT_WITH_ID = document.createElement('div');
@@ -13,13 +14,25 @@ describe('getElementByQuery', () => {
13
14
  expect(getElementByQuery({ container: PARENT_ELEMENT, query: `#${ID}` })).toEqual(CHILD_ELEMENT_WITH_ID);
14
15
  });
15
16
  });
16
- describe('removeClassFromElementByQuery', () => {
17
- it('should remove the specified class from from the queried element', () => {
18
- removeClassFromElementByQuery({
17
+ describe('updateClassFromElementByQuery', () => {
18
+ it('should remove the specified class from the queried element', () => {
19
+ updateClassFromElementByQuery({
19
20
  container: PARENT_ELEMENT,
20
21
  query: `.${CLASS}`,
21
- className: CLASS
22
+ className: CLASS,
23
+ condition: false
22
24
  });
23
25
  expect(PARENT_ELEMENT.querySelector(`.${CLASS}`)).toBeNull();
24
26
  });
27
+ it('should add the specified class to the queried element', () => {
28
+ const ELEMENT_WITHOUT_CLASS = document.createElement('div');
29
+ PARENT_ELEMENT.appendChild(ELEMENT_WITHOUT_CLASS);
30
+ updateClassFromElementByQuery({
31
+ container: PARENT_ELEMENT,
32
+ query: 'div:not([class])',
33
+ className: NEW_CLASS,
34
+ condition: true
35
+ });
36
+ expect(PARENT_ELEMENT.querySelector(`.${NEW_CLASS}`)).not.toBeNull();
37
+ });
25
38
  });
package/lib/lang/nl.json CHANGED
@@ -52,7 +52,7 @@
52
52
  "googleCast": "Google Cast",
53
53
  "vr": "VR",
54
54
  "off": "Uit",
55
- "auto": "automatisch",
55
+ "auto": "Automatisch",
56
56
  "back": "Terug",
57
57
  "reset": "Herstellen",
58
58
  "replay": "Replay",
@@ -0,0 +1,14 @@
1
+ {
2
+ "ar": "Arabisch",
3
+ "bg": "Bulgaars",
4
+ "de": "Duits",
5
+ "en": "Engels",
6
+ "es": "Spaans",
7
+ "fr": "Frans",
8
+ "it": "Italiaans",
9
+ "nl": "Nederlands",
10
+ "ma": "Marokkaans",
11
+ "pl": "Pools",
12
+ "ua": "Oekraïens",
13
+ "tr": "Turks"
14
+ }
@@ -1,18 +1,21 @@
1
1
  import { NpoPlayerServices } from './services/services';
2
- import { type StreamTracker, type NPOTag } from '@npotag/tag';
2
+ import { type StreamTracker, type NPOTag, type PageTracker } from '@npotag/tag';
3
3
  import { type InitialisationProps } from '@npotag/tag/dist/types/src/npoTag';
4
4
  import { type PlayerAPI, type PlayerConfig, type SourceConfig } from 'bitmovin-player';
5
5
  import { UIManager } from 'bitmovin-player-ui';
6
6
  import { LogEmitter } from './types/classes';
7
- import { type DRMProfile, type ApiPayload, type NPOTagObject, type StreamObject, type StreamOptions, type UIComponents, type TimeLineMarker, type LocalStorageData, type PlayerContext, type EventListeners, NpoPlayerUIVariants } from './types/interfaces';
7
+ import { type DRMProfile, type ApiPayload, type NPOTagObject, type StreamObject, type StreamOptions, type UIComponents, type TimeLineMarker, type PlayerContext, type EventListeners, NpoPlayerUIVariants } from './types/interfaces';
8
8
  export { type PlayerConfig, type InitialisationProps, type NPOTagObject, type StreamOptions, NpoPlayerUIVariants };
9
9
  export default class NpoPlayer {
10
- playerConfig: PlayerConfig;
10
+ playerConfig: PlayerConfig | undefined;
11
11
  sourceConfig: SourceConfig;
12
12
  streamObject: StreamObject;
13
13
  player: PlayerAPI | undefined;
14
14
  uiManager: UIManager | undefined;
15
15
  npoTag: NPOTagObject | undefined;
16
+ npoTagInitialisation: InitialisationProps | undefined;
17
+ npoTagInstance: NPOTag | undefined;
18
+ npoTagPageTracker: PageTracker | undefined;
16
19
  streamTracker: StreamTracker | undefined;
17
20
  logEmitter: LogEmitter;
18
21
  uiComponents: UIComponents;
@@ -27,11 +30,17 @@ export default class NpoPlayer {
27
30
  isShowingPlayNextScreen: boolean;
28
31
  canceledPlayNextScreen: boolean;
29
32
  playerContext: PlayerContext | undefined;
30
- npoplayerServices: NpoPlayerServices;
33
+ npoPlayerServices: NpoPlayerServices;
31
34
  eventListeners: EventListeners | undefined;
32
35
  mockNpoPlayer: any;
33
- userPreferences: LocalStorageData;
34
- constructor(_container: HTMLElement, _playerConfig: PlayerConfig, _npotag?: InitialisationProps | undefined, _npotaginstance?: NPOTag | undefined, _variant?: NpoPlayerUIVariants);
36
+ constructor(container: HTMLElement | {
37
+ container: HTMLElement;
38
+ playerConfig: PlayerConfig;
39
+ npoTag?: InitialisationProps | undefined;
40
+ npoTagInstance?: NPOTag | undefined;
41
+ variant?: NpoPlayerUIVariants;
42
+ npoTagPageTracker?: PageTracker | undefined;
43
+ }, playerConfig?: PlayerConfig | undefined, npoTag?: InitialisationProps | undefined, npoTagInstance?: NPOTag | undefined, variant?: NpoPlayerUIVariants, npoTagPageTracker?: PageTracker | undefined);
35
44
  initPlayer(_container: HTMLElement, playerConfig: PlayerConfig): void;
36
45
  loadStream(source: string, options?: StreamOptions): Promise<void>;
37
46
  doError(input: any, status?: number): void;
package/lib/npoplayer.js CHANGED
@@ -11,19 +11,16 @@ import { isMediaUrl, isUrl } from './js/utilities/utilities.url';
11
11
  import { logVersion } from './js/utilities/utilities.version';
12
12
  import { getStreamDurationInSeconds } from './js/utilities/utilities.stream';
13
13
  import { LogEmitter } from './types/classes';
14
- import { handlePreRolls } from './services/advertHandlers/handlePreRolls';
15
14
  import pkg from '../package.json';
16
- import { NpoPlayerUIVariants, LocalStorageValues } from './types/interfaces';
15
+ import { NpoPlayerUIVariants } from './types/interfaces';
17
16
  import { nativeMobileUiFactory } from './ui/nativemobileuifactory';
18
17
  import { setupMediaSessionActionHandlers } from './js/playeractions/handlers/mediasessionactions';
19
18
  import { removeReplayClass } from './js/playeractions/handlers/removereplayclass';
20
- import { showNicamAfterUiDelay } from './ui/handlers/nicamhandler';
21
19
  import { updateLiveMarkers } from './js/markers/updateLiveMarkers';
22
20
  import { NpoPlayerAPI } from './services/npoPlayerAPI/npoPlayerAPI';
23
- import { discardAdBreak } from './services/advertHandlers/discardAdBreak';
24
21
  export { NpoPlayerUIVariants };
25
22
  export default class NpoPlayer {
26
- constructor(_container, _playerConfig, _npotag, _npotaginstance, _variant) {
23
+ constructor(container, playerConfig, npoTag, npoTagInstance, variant, npoTagPageTracker) {
27
24
  this.sourceConfig = {};
28
25
  this.streamObject = {
29
26
  stream: { drmType: '', streamProfile: '', streamURL: '', avType: '', sourceProfile: '' },
@@ -33,6 +30,9 @@ export default class NpoPlayer {
33
30
  };
34
31
  this.player = undefined;
35
32
  this.uiManager = undefined;
33
+ this.npoTagInitialisation = undefined;
34
+ this.npoTagInstance = undefined;
35
+ this.npoTagPageTracker = undefined;
36
36
  this.streamTracker = undefined;
37
37
  this.logEmitter = new LogEmitter();
38
38
  this.uiComponents = {};
@@ -45,48 +45,59 @@ export default class NpoPlayer {
45
45
  this.isShowingPlayNextScreen = false;
46
46
  this.canceledPlayNextScreen = false;
47
47
  this.playerContext = undefined;
48
- this.npoplayerServices = new NpoPlayerServices();
48
+ this.npoPlayerServices = new NpoPlayerServices();
49
49
  this.eventListeners = undefined;
50
- this.userPreferences = {};
51
- this.playerConfig = _playerConfig;
52
- this.container = _container;
53
- this.variant = _variant || NpoPlayerUIVariants.DEFAULT;
54
- initPlayerTracker(this, _npotag, _npotaginstance);
55
- this.initPlayer(this.container, _playerConfig);
50
+ if (typeof container === 'object' && !(container instanceof HTMLElement)) {
51
+ const params = container;
52
+ this.container = params.container;
53
+ this.playerConfig = params.playerConfig;
54
+ this.npoTagInitialisation = params.npoTag || undefined;
55
+ this.npoTagInstance = params.npoTagInstance;
56
+ this.variant = params.variant || NpoPlayerUIVariants.DEFAULT;
57
+ this.npoTagPageTracker = params.npoTagPageTracker || undefined;
58
+ }
59
+ else {
60
+ this.container = container;
61
+ this.playerConfig = playerConfig || undefined;
62
+ this.npoTagInitialisation = npoTag || undefined;
63
+ this.npoTagInstance = npoTagInstance;
64
+ this.variant = variant || NpoPlayerUIVariants.DEFAULT;
65
+ this.npoTagPageTracker = npoTagPageTracker || undefined;
66
+ console.warn('As of NPO Player version 1.25, parameter-based initialization has been deprecated in favor of object-based initialization. This feature will be removed in version 2.0. Please update your implementation to ensure compatibility. For more details, refer to the documentation at: https://docs.npoplayer.nl/implementation/web/player.');
67
+ }
68
+ if (!this.playerConfig) {
69
+ console.error('Player configuration is missing. Ensure that playerConfig is properly initialized before using the player.');
70
+ return;
71
+ }
72
+ if (this.npoTagInstance) {
73
+ initPlayerTracker(this, this.npoTagInitialisation, this.npoTagInstance, this.npoTagPageTracker);
74
+ }
75
+ this.initPlayer(this.container, this.playerConfig);
56
76
  }
57
77
  initPlayer(_container, playerConfig) {
58
78
  const processedPlayerConfig = playerAction.processPlayerConfig(this, playerConfig);
59
79
  this.player = new Player(_container, processedPlayerConfig);
60
80
  Player.addModule(getModuleExport(AdsModuleBM));
61
81
  const npoPlayerAPI = new NpoPlayerAPI(this.player);
62
- this.playerContext = { player: npoPlayerAPI, npoplayer: this };
63
- this.userPreferences = this.npoplayerServices.getStoredUserPrefs();
64
- this.npoplayerServices.handleUserPrefs(this.playerContext);
65
- this.npoplayerServices.setAccessibilityAttributes(this.playerContext);
66
- window.addEventListener('beforeunload', () => {
67
- if (this.player) {
68
- this.npoplayerServices.setStoredUserPrefs(LocalStorageValues.SUBTITLES_ENABLED, npoPlayerAPI.areSubtitlesEnabled().toString());
69
- this.npoplayerServices.setStoredUserPrefs(LocalStorageValues.VOLUME, npoPlayerAPI.getVolume());
70
- this.npoplayerServices.setStoredUserPrefs(LocalStorageValues.IS_MUTED, npoPlayerAPI.isMuted().toString());
71
- }
72
- });
82
+ this.playerContext = { player: npoPlayerAPI, npoPlayer: this };
83
+ this.npoPlayerServices.handleUserPrefs(this.playerContext);
84
+ this.npoPlayerServices.setAccessibilityAttributes(this.playerContext);
85
+ this.npoPlayerServices.handlePreferences(this.playerContext);
73
86
  this.container.addEventListener('keydown', (e) => {
74
87
  if (!this.playerContext)
75
88
  return;
76
- this.npoplayerServices.keyboardHandler(this.playerContext, e);
89
+ this.npoPlayerServices.keyboardHandler(this.playerContext, e);
77
90
  }, true);
78
91
  }
79
92
  async loadStream(source, options = {}) {
80
93
  if (!this.playerContext)
81
94
  return;
82
95
  this.streamOptions = options;
83
- if (this.player == undefined) {
96
+ if (!this.player) {
84
97
  console.error('Er is nog geen player geladen.');
85
98
  return;
86
99
  }
87
- if (this.playerContext) {
88
- discardAdBreak(this.playerContext);
89
- }
100
+ this.npoPlayerServices.discardAdBreak(this.playerContext);
90
101
  let _streamObject;
91
102
  const sourceIsUrl = isUrl(source);
92
103
  const sourceIsMedia = await isMediaUrl(source);
@@ -105,16 +116,17 @@ export default class NpoPlayer {
105
116
  analytics: {
106
117
  customData2: 'other',
107
118
  customData3: 'unknown',
108
- customData4: this.npoTag?.npoTagInstance?.getParty(),
119
+ customData4: this.npoTagInstance?.getParty(),
109
120
  customData5: this.version
110
121
  }
111
122
  };
123
+ await this.playerContext.player.createUIManager(this.playerContext, this.variant);
112
124
  await this.playerContext.player?.load(this.sourceConfig);
113
125
  getDurationAndStartPlayerTracker();
114
126
  }
115
127
  else if (sourceIsJWTToken) {
116
128
  this.jwt = source;
117
- const profile = await this.npoplayerServices.decideProfile(this.playerContext, options?.preferredDRM ?? '');
129
+ const profile = await this.npoPlayerServices.decideProfile(this.playerContext, options?.preferredDRM ?? '');
118
130
  const defaultEndpoint = 'https://prod.npoplayer.nl/';
119
131
  const endpoint = options?.endpoint ?? defaultEndpoint;
120
132
  const payload = {
@@ -131,12 +143,10 @@ export default class NpoPlayer {
131
143
  }
132
144
  }
133
145
  };
146
+ await this.playerContext.player.createUIManager(this.playerContext, this.variant);
134
147
  try {
135
148
  _streamObject = await getStreamObject(this, payload);
136
149
  this.streamObject = _streamObject;
137
- if (_streamObject) {
138
- await this.playerContext.player.createUIManager(this.playerContext, this.variant);
139
- }
140
150
  }
141
151
  catch (error) {
142
152
  this.doError('Het is niet gelukt de stream op te halen. \n' + error);
@@ -146,8 +156,8 @@ export default class NpoPlayer {
146
156
  if (this.streamObject?.stream == undefined)
147
157
  return;
148
158
  const drmType = this.streamObject.stream.drmType ?? undefined;
149
- this.sourceConfig = await playerAction.processSourceConfig(this.npoplayerServices, options.sourceConfig ?? {}, this.streamObject, drmType && drmType.length > 0 ? profile.drm : undefined, this.streamOptions, this.version, this.npoTag?.npoTagInstance?.getParty(), this.npoplayerServices);
150
- await this.npoplayerServices.verifyDRM(this.playerContext, payload);
159
+ this.sourceConfig = await playerAction.processSourceConfig(this.npoPlayerServices, source, options.sourceConfig ?? {}, this.streamObject, drmType && drmType.length > 0 ? profile.drm : undefined, this.streamOptions, this.version, this.npoTag?.npoTagInstance);
160
+ await this.npoPlayerServices.verifyDRM(this.playerContext, payload);
151
161
  setupMediaSessionActionHandlers(this.player, this.sourceConfig, _streamObject);
152
162
  logEvent(this, 'load');
153
163
  let streamDuration = _streamObject.metadata.duration;
@@ -170,7 +180,7 @@ export default class NpoPlayer {
170
180
  this.streamObject.assets.preroll) {
171
181
  this.player.on(PlayerEvent.AdBreakFinished, initAndStartTracker);
172
182
  this.player.on(PlayerEvent.AdError, initAndStartTracker);
173
- await handlePreRolls(this.playerContext);
183
+ await this.npoPlayerServices.schedulePreRolls(this.playerContext);
174
184
  }
175
185
  else {
176
186
  initAndStartTracker();
@@ -179,12 +189,12 @@ export default class NpoPlayer {
179
189
  else {
180
190
  this.doError(`Het is niet gelukt de stream op te halen: \n Input is geen valide token of media object.`, 500);
181
191
  }
182
- this.npoplayerServices.handleVerticalVideoControls(this.playerContext, this.variant);
183
- if (this.sourceConfig?.metadata) {
184
- this.sourceConfig.metadata.jwt = source;
185
- this.sourceConfig.metadata.streamLinkAsJsonString = JSON.stringify(this.streamObject);
186
- this.sourceConfig.metadata.npoTagSession = String(this.npoTag?.npoTagInstance?.getSerializedSessionInfo());
187
- }
192
+ this.npoPlayerServices.handleStreamOptions(this.playerContext);
193
+ this.npoPlayerServices.setupNicamKijkwijzerIcons(this.playerContext);
194
+ this.player.on(PlayerEvent.Ready, () => {
195
+ this.npoPlayerServices.showNicamAfterUiDelay(this.playerContext);
196
+ });
197
+ this.npoPlayerServices.handleVerticalVideoControls(this.playerContext, this.variant);
188
198
  this.player.on(PlayerEvent.Seek, () => {
189
199
  removeReplayClass(this.player);
190
200
  });
@@ -196,9 +206,6 @@ export default class NpoPlayer {
196
206
  this.hidePlayNextScreen();
197
207
  });
198
208
  }
199
- this.player.on(PlayerEvent.Play, () => {
200
- showNicamAfterUiDelay(this.player, this.uiManager);
201
- });
202
209
  const setLiveOffsetListener = function () {
203
210
  if (this.playerContext === undefined)
204
211
  return;
@@ -208,7 +215,7 @@ export default class NpoPlayer {
208
215
  this.player.on(PlayerEvent.Ready, setLiveOffsetListener);
209
216
  }
210
217
  doError(input, status) {
211
- if (this.player == undefined)
218
+ if (!this.player)
212
219
  return;
213
220
  if (status) {
214
221
  this.logEmitter.emit('logError', status);
@@ -307,9 +314,12 @@ export default class NpoPlayer {
307
314
  const destroyLogic = async () => {
308
315
  try {
309
316
  if (this.npoTag != undefined) {
310
- clearInterval(this.npoTag.heartbeatInterval);
317
+ clearInterval(this.npoTag?.heartbeatInterval);
311
318
  }
312
319
  logEvent(this, 'stop');
320
+ if (this.playerContext) {
321
+ this.npoPlayerServices.removeUivisiblityHandlers(this.playerContext);
322
+ }
313
323
  this.uiManager?.release();
314
324
  this.uiManager = undefined;
315
325
  await this.player?.destroy();
@@ -332,9 +342,6 @@ export default class NpoPlayer {
332
342
  if (this.npoTag != undefined) {
333
343
  clearInterval(this.npoTag.heartbeatInterval);
334
344
  }
335
- if (this.playerContext) {
336
- discardAdBreak(this.playerContext);
337
- }
338
345
  this.hidePlayNextScreen();
339
346
  await this.player?.unload();
340
347
  return true;
@@ -3,12 +3,20 @@ const div = document.createElement('div');
3
3
  const testPlayerConfig = {
4
4
  key: 'dummy-key'
5
5
  };
6
- jest.mock('./ui/handlers/streamhandler', () => ({
7
- processStream: jest.fn()
6
+ jest.mock('./services/streamoptionsHandlers/streamOptionsHandler', () => ({
7
+ handleStreamOptions: jest.fn()
8
8
  }));
9
9
  let player;
10
- test('player init', async () => {
10
+ test('player init with parameters', async () => {
11
11
  player = new NpoPlayer(div, testPlayerConfig);
12
12
  expect(player).toBeInstanceOf(NpoPlayer);
13
- expect(player.playerConfig.key).toBe(testPlayerConfig.key);
13
+ expect(player.playerConfig?.key).toBe(testPlayerConfig.key);
14
+ });
15
+ test('player init with parameters', async () => {
16
+ player = new NpoPlayer({
17
+ container: div,
18
+ playerConfig: testPlayerConfig
19
+ });
20
+ expect(player).toBeInstanceOf(NpoPlayer);
21
+ expect(player.playerConfig?.key).toBe(testPlayerConfig.key);
14
22
  });
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npo/player",
3
- "version": "1.24.7",
3
+ "version": "1.26.0",
4
4
  "description": "NPO Player",
5
5
  "author": "Publieke Omroep <player@npo.nl>",
6
6
  "contributors": [
@@ -89,8 +89,8 @@
89
89
  "webpack-dev-server": "^4.11.1"
90
90
  },
91
91
  "dependencies": {
92
- "@npotag/tag": "3.2.1",
93
- "bitmovin-player": "8.173.0",
92
+ "@npotag/tag": "3.2.4",
93
+ "bitmovin-player": "^8.166.0",
94
94
  "bitmovin-player-ui": "3.67.0"
95
95
  },
96
96
  "browserslist": [
@@ -1,16 +1,13 @@
1
1
  import { NpoPlayerEvent } from '../../types/events';
2
2
  import { addAccessibilityAttributes } from '../../ui/handlers/accessibilityhandler';
3
3
  export function setupAccessibilityAttributes(playerContext) {
4
- const { player, npoplayer } = playerContext;
4
+ const { player, npoPlayer } = playerContext;
5
5
  const events = [NpoPlayerEvent.SourceLoaded, NpoPlayerEvent.AdBreakFinished, NpoPlayerEvent.AdError];
6
6
  const triggerAddAccessibilityAttributes = () => {
7
7
  for (const event of events) {
8
8
  player?.off(event, triggerAddAccessibilityAttributes);
9
9
  }
10
- if (npoplayer.streamOptions.enableSubtitles === true || npoplayer.userPreferences.subtitles_enabled === 'true') {
11
- player?.enableSubtitles();
12
- }
13
- addAccessibilityAttributes(npoplayer.container, npoplayer.streamObject.metadata);
10
+ addAccessibilityAttributes(npoPlayer.container, npoPlayer.streamObject.metadata);
14
11
  };
15
12
  for (const event of events) {
16
13
  player?.on(event, triggerAddAccessibilityAttributes);
@@ -31,14 +31,11 @@ describe('setupAccessibilityAttributes', () => {
31
31
  };
32
32
  playerContext = {
33
33
  player: mockPlayerAPI,
34
- npoplayer: {
34
+ npoPlayer: {
35
35
  ...mockNpoPlayer,
36
36
  streamOptions: {
37
37
  enableSubtitles: false
38
38
  },
39
- userPreferences: {
40
- subtitles_enabled: 'false'
41
- },
42
39
  container: document.createElement('div'),
43
40
  streamObject: {},
44
41
  playerConfig: {},
@@ -69,20 +66,6 @@ describe('setupAccessibilityAttributes', () => {
69
66
  afterEach(() => {
70
67
  jest.clearAllMocks();
71
68
  });
72
- it('should enable subtitles if playerContext.npoplayer.userPreferences.subtitles_enabled is "true"', () => {
73
- playerContext.npoplayer.userPreferences.subtitles_enabled = 'true';
74
- setupAccessibilityAttributes(playerContext);
75
- const triggerFunction = mockAddEventListener.mock.calls[0][1];
76
- triggerFunction();
77
- expect(mockEnableSubtitles).toHaveBeenCalled();
78
- });
79
- it('should enable subtitles if streamOptions.enableSubtitles is true', () => {
80
- playerContext.npoplayer.streamOptions.enableSubtitles = true;
81
- setupAccessibilityAttributes(playerContext);
82
- const triggerFunction = mockAddEventListener.mock.calls[0][1];
83
- triggerFunction();
84
- expect(mockEnableSubtitles).toHaveBeenCalled();
85
- });
86
69
  it('should set up event listeners for specified events', () => {
87
70
  setupAccessibilityAttributes(playerContext);
88
71
  expect(mockAddEventListener).toHaveBeenCalledTimes(3);
@@ -103,6 +86,6 @@ describe('setupAccessibilityAttributes', () => {
103
86
  setupAccessibilityAttributes(playerContext);
104
87
  const triggerFunction = mockAddEventListener.mock.calls[0][1];
105
88
  triggerFunction();
106
- expect(addAccessibilityAttributes).toHaveBeenCalledWith(playerContext.npoplayer.container, playerContext.npoplayer.streamObject.metadata);
89
+ expect(addAccessibilityAttributes).toHaveBeenCalledWith(playerContext.npoPlayer.container, playerContext.npoPlayer.streamObject.metadata);
107
90
  });
108
91
  });
@@ -1,11 +1,11 @@
1
1
  export function discardAdBreak(playerContext) {
2
- const { npoplayer, player } = playerContext;
3
- const { adBreakActive } = npoplayer;
2
+ const { npoPlayer, player } = playerContext;
3
+ const { adBreakActive } = npoPlayer;
4
4
  if (!player || adBreakActive === false)
5
5
  return;
6
6
  const activeAdBreak = player.getActiveAdBreak();
7
7
  if (activeAdBreak?.id) {
8
- player.discardAdBreak(activeAdBreak.id);
8
+ player.playerAPI.ads.discardAdBreak(activeAdBreak.id);
9
9
  }
10
- npoplayer.adBreakActive = false;
10
+ npoPlayer.adBreakActive = false;
11
11
  }