@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
@@ -2,59 +2,71 @@ import createPlayerContextMock, { createMockNpoPlayer, createMockNpoPlayerAPI }
2
2
  import { discardAdBreak } from './discardAdBreak';
3
3
  describe('discardAdBreak', () => {
4
4
  let mockNpoPlayerAPI;
5
- let npoplayerMock;
5
+ let npoPlayerMock;
6
6
  const activeAdBreakMock = { id: 'ad-break-id' };
7
7
  afterEach(() => {
8
8
  jest.resetAllMocks();
9
9
  });
10
+ it('should not discard ad break if player is undefined', () => {
11
+ npoPlayerMock = createMockNpoPlayer({
12
+ adBreakActive: true
13
+ });
14
+ const playerContextMock = createPlayerContextMock({
15
+ player: undefined,
16
+ npoPlayer: npoPlayerMock
17
+ });
18
+ discardAdBreak(playerContextMock);
19
+ expect(npoPlayerMock.adBreakActive).toBe(true);
20
+ });
10
21
  it('should not discard ad break if adBreakActive is false', () => {
11
22
  mockNpoPlayerAPI = createMockNpoPlayerAPI({
12
- getActiveAdBreak: jest.fn().mockReturnValue(undefined),
23
+ getActiveAdBreak: jest.fn().mockReturnValue(activeAdBreakMock),
13
24
  discardAdBreak: jest.fn()
14
25
  });
15
- npoplayerMock = createMockNpoPlayer({
26
+ npoPlayerMock = createMockNpoPlayer({
16
27
  adBreakActive: false
17
28
  });
18
29
  const playerContextMock = createPlayerContextMock({
19
30
  player: mockNpoPlayerAPI,
20
- npoplayer: npoplayerMock
31
+ npoPlayer: npoPlayerMock
21
32
  });
22
33
  discardAdBreak(playerContextMock);
23
34
  expect(mockNpoPlayerAPI.getActiveAdBreak).not.toHaveBeenCalled();
24
- expect(mockNpoPlayerAPI.discardAdBreak).not.toHaveBeenCalled();
35
+ expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).not.toHaveBeenCalled();
36
+ expect(npoPlayerMock.adBreakActive).toBe(false);
25
37
  });
26
38
  it('should discard active ad break if adBreakActive is true and ad break exists', () => {
27
39
  mockNpoPlayerAPI = createMockNpoPlayerAPI({
28
40
  getActiveAdBreak: jest.fn().mockReturnValue(activeAdBreakMock),
29
41
  discardAdBreak: jest.fn()
30
42
  });
31
- npoplayerMock = createMockNpoPlayer({
43
+ npoPlayerMock = createMockNpoPlayer({
32
44
  adBreakActive: true
33
45
  });
34
46
  const playerContextMock = createPlayerContextMock({
35
47
  player: mockNpoPlayerAPI,
36
- npoplayer: npoplayerMock
48
+ npoPlayer: npoPlayerMock
37
49
  });
38
50
  discardAdBreak(playerContextMock);
39
51
  expect(mockNpoPlayerAPI.getActiveAdBreak).toHaveBeenCalled();
40
- expect(mockNpoPlayerAPI.discardAdBreak).toHaveBeenCalledWith(activeAdBreakMock.id);
41
- expect(npoplayerMock.adBreakActive).toBe(false);
52
+ expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).toHaveBeenCalledWith(activeAdBreakMock.id);
53
+ expect(npoPlayerMock.adBreakActive).toBe(false);
42
54
  });
43
55
  it('should not discard ad break if active ad break does not exist', () => {
44
56
  mockNpoPlayerAPI = createMockNpoPlayerAPI({
45
57
  getActiveAdBreak: jest.fn().mockReturnValue(undefined),
46
58
  discardAdBreak: jest.fn()
47
59
  });
48
- npoplayerMock = createMockNpoPlayer({
60
+ npoPlayerMock = createMockNpoPlayer({
49
61
  adBreakActive: true
50
62
  });
51
63
  const playerContextMock = createPlayerContextMock({
52
64
  player: mockNpoPlayerAPI,
53
- npoplayer: npoplayerMock
65
+ npoPlayer: npoPlayerMock
54
66
  });
55
67
  discardAdBreak(playerContextMock);
56
68
  expect(mockNpoPlayerAPI.getActiveAdBreak).toHaveBeenCalled();
57
- expect(mockNpoPlayerAPI.discardAdBreak).not.toHaveBeenCalled();
58
- expect(npoplayerMock.adBreakActive).toBe(false);
69
+ expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).not.toHaveBeenCalled();
70
+ expect(npoPlayerMock.adBreakActive).toBe(false);
59
71
  });
60
72
  });
@@ -3,12 +3,12 @@ import { NpoPlayerUIVariants } from '../../types/interfaces';
3
3
  import { NpoPlayerEvent } from '../../types/events';
4
4
  export async function handlePreRolls(playerContext) {
5
5
  return new Promise((resolve) => {
6
- if (playerContext.npoplayer.streamObject.metadata.hasPreroll == 'false' ||
7
- playerContext.npoplayer.streamObject.assets.preroll == undefined) {
6
+ if (playerContext.npoPlayer.streamObject.metadata.hasPreroll == 'false' ||
7
+ playerContext.npoPlayer.streamObject.assets.preroll == undefined) {
8
8
  resolve();
9
9
  return;
10
10
  }
11
- const prerollUrl = playerContext.npoplayer.streamObject.assets.preroll;
11
+ const prerollUrl = playerContext.npoPlayer.streamObject.assets.preroll;
12
12
  let adIndex = 0;
13
13
  let totalAds = 0;
14
14
  let currentClickListener;
@@ -35,13 +35,13 @@ export async function handlePreRolls(playerContext) {
35
35
  const activeAdBreak = playerContext.player.getActiveAdBreak();
36
36
  if (!activeAdBreak || !activeAdBreak.ads)
37
37
  return false;
38
- playerContext.npoplayer.uiManager?.release();
39
- playerContext.npoplayer.uiManager = undefined;
40
- if (playerContext.npoplayer.playerContext) {
41
- playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.AD);
38
+ playerContext.npoPlayer.uiManager?.release();
39
+ playerContext.npoPlayer.uiManager = undefined;
40
+ if (playerContext.npoPlayer.playerContext) {
41
+ void playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.AD);
42
42
  }
43
43
  adUiSet = true;
44
- const adButton = playerContext.npoplayer.uiComponents.adbutton;
44
+ const adButton = playerContext.npoPlayer.uiComponents.adbutton;
45
45
  const currentAd = activeAdBreak.ads[0];
46
46
  adIndex = 1;
47
47
  totalAds = activeAdBreak.ads.length;
@@ -49,7 +49,7 @@ export async function handlePreRolls(playerContext) {
49
49
  adButton.show();
50
50
  adClickHandler(currentAd, adButton);
51
51
  }
52
- playerContext.npoplayer.uiComponents.adlabel?.setText(`Advertentie 1 van ${activeAdBreak.ads.length}`);
52
+ playerContext.npoPlayer.uiComponents.adlabel?.setText(`Advertentie 1 van ${activeAdBreak.ads.length}`);
53
53
  return true;
54
54
  }
55
55
  function attemptSetAdUi(attemptsLeft = 10) {
@@ -71,7 +71,7 @@ export async function handlePreRolls(playerContext) {
71
71
  }
72
72
  if (!adUiSet)
73
73
  attemptSetAdUi();
74
- playerContext.npoplayer.adBreakActive = true;
74
+ playerContext.npoPlayer.adBreakActive = true;
75
75
  }
76
76
  playerContext.player.on(NpoPlayerEvent.AdStarted, handleAdStarted);
77
77
  function adClickHandler(ad, button) {
@@ -102,26 +102,26 @@ export async function handlePreRolls(playerContext) {
102
102
  handleAdBreakFinished();
103
103
  return;
104
104
  }
105
- const adButton = playerContext.npoplayer.uiComponents.adbutton;
105
+ const adButton = playerContext.npoPlayer.uiComponents.adbutton;
106
106
  const nextAd = activeAdBreak.ads[adIndex];
107
107
  adIndex += 1;
108
108
  if (adButton) {
109
109
  adButton.show();
110
110
  adClickHandler(nextAd, adButton);
111
111
  }
112
- playerContext.npoplayer.uiComponents.adlabel?.setText(`Advertentie ${adIndex} van ${activeAdBreak.ads.length}`);
112
+ playerContext.npoPlayer.uiComponents.adlabel?.setText(`Advertentie ${adIndex} van ${activeAdBreak.ads.length}`);
113
113
  }
114
114
  playerContext.player.on(NpoPlayerEvent.AdFinished, handleAdFinished);
115
115
  function handleAdBreakFinished() {
116
116
  playerContext.player.off(NpoPlayerEvent.AdBreakFinished, handleAdBreakFinished);
117
117
  playerContext.player.off(NpoPlayerEvent.AdError, handleAdBreakFinished);
118
- playerContext.npoplayer.adBreakActive = false;
119
- playerContext.npoplayer.uiComponents.adbutton?.hide();
120
- playerContext.npoplayer.uiComponents.adlabel?.hide();
121
- playerContext.npoplayer.uiManager?.release();
122
- playerContext.npoplayer.uiManager = undefined;
123
- if (playerContext.npoplayer.playerContext) {
124
- playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.DEFAULT);
118
+ playerContext.npoPlayer.adBreakActive = false;
119
+ playerContext.npoPlayer.uiComponents.adbutton?.hide();
120
+ playerContext.npoPlayer.uiComponents.adlabel?.hide();
121
+ playerContext.npoPlayer.uiManager?.release();
122
+ playerContext.npoPlayer.uiManager = undefined;
123
+ if (playerContext.npoPlayer.playerContext) {
124
+ void playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.DEFAULT);
125
125
  }
126
126
  adUiSet = false;
127
127
  resolve();
@@ -15,7 +15,7 @@ describe('handlePreRolls', () => {
15
15
  };
16
16
  });
17
17
  it('should not schedule ads when hasPreroll is false', async () => {
18
- const npoplayerMock = createMockNpoPlayer({
18
+ const npoPlayerMock = createMockNpoPlayer({
19
19
  streamObject: {
20
20
  metadata: {
21
21
  hasPreroll: 'false'
@@ -26,13 +26,13 @@ describe('handlePreRolls', () => {
26
26
  }
27
27
  });
28
28
  const playerContextMock = createPlayerContextMock({
29
- npoplayer: npoplayerMock
29
+ npoPlayer: npoPlayerMock
30
30
  });
31
31
  await handlePreRolls(playerContextMock);
32
32
  expect(mockPlayerAPI.ads.schedule).not.toHaveBeenCalled();
33
33
  });
34
34
  it('should not schedule ads if preroll URL is missing', async () => {
35
- const npoplayerMock = createMockNpoPlayer({
35
+ const npoPlayerMock = createMockNpoPlayer({
36
36
  streamObject: {
37
37
  metadata: {
38
38
  hasPreroll: 'true'
@@ -41,7 +41,7 @@ describe('handlePreRolls', () => {
41
41
  }
42
42
  });
43
43
  const playerContextMock = createPlayerContextMock({
44
- npoplayer: npoplayerMock
44
+ npoPlayer: npoPlayerMock
45
45
  });
46
46
  await handlePreRolls(playerContextMock);
47
47
  expect(mockPlayerAPI.ads.schedule).not.toHaveBeenCalled();
@@ -2,9 +2,11 @@ export function createImmutableMap(entries) {
2
2
  const map = new Map(entries);
3
3
  return Object.freeze(map);
4
4
  }
5
+ const nepFastlyProvider = 'NEP-FASTLY';
5
6
  export const npoCdnProvidersData = [
6
- ['nep.global.ssl.fastly.net', 'NEP-FASTLY'],
7
- ['npo-fsly.cdn.streamgate.io', 'NEP-FASTLY'],
7
+ ['nep.global.ssl.fastly.net', nepFastlyProvider],
8
+ ['npo-fsly.cdn.streamgate.io', nepFastlyProvider],
9
+ ['npo-fsly-2.cdn.streamgate.io', nepFastlyProvider],
8
10
  ['cdn.streamgate.nl', 'NEP'],
9
11
  ['pr.lswcdn.net', 'NEP-LSW'],
10
12
  ['cdn.eurovisioncdn.net', 'EUROVISION'],
@@ -5,7 +5,7 @@ export async function decideProfile(playerContext, preferredDRM = '') {
5
5
  console.error('No player detected');
6
6
  return { profileName: '', drm: '' };
7
7
  }
8
- const player = playerContext.player;
8
+ const { player } = playerContext;
9
9
  const supportedTech = player.getSupportedTech();
10
10
  const supportedDRM = await player.getSupportedDRM();
11
11
  const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
@@ -13,7 +13,7 @@ describe('decideProfile', () => {
13
13
  .fn()
14
14
  .mockResolvedValue(['com.widevine.alpha', 'com.microsoft.playready', 'com.apple.fps.1_0'])
15
15
  };
16
- mockPlayerContext = { player: mockPlayer, npoplayer: mockNpoplayer };
16
+ mockPlayerContext = { player: mockPlayer, npoPlayer: mockNpoplayer };
17
17
  });
18
18
  afterEach(() => {
19
19
  jest.clearAllMocks();
@@ -2,7 +2,7 @@ import { convertJwtToBase64, convertBase64ToObject } from '../../js/utilities/ut
2
2
  import { getStreamObject } from '../../js/api/getstreamobject';
3
3
  export async function verifyDRM(playerContext, payload) {
4
4
  try {
5
- const { player, npoplayer: { streamObject, sourceConfig } } = playerContext;
5
+ const { player, npoPlayer: { streamObject, sourceConfig } } = playerContext;
6
6
  const { stream } = streamObject;
7
7
  if (stream.drmToken) {
8
8
  const drmJsonTimestamp = getDRMTokenTimestamp(stream.drmToken);
@@ -29,12 +29,12 @@ function getDRMTokenTimestamp(drmToken) {
29
29
  return convertBase64ToObject(drmBase64).iat;
30
30
  }
31
31
  async function refreshDRMToken(playerContext, payload) {
32
- const backupStreamObject = await getStreamObject(playerContext.npoplayer, payload);
32
+ const backupStreamObject = await getStreamObject(playerContext.npoPlayer, payload);
33
33
  const newDrmToken = backupStreamObject.stream.drmToken;
34
34
  const clonedStreamObject = {
35
- ...playerContext.npoplayer.streamObject,
36
- stream: { ...playerContext.npoplayer.streamObject.stream, drmToken: newDrmToken }
35
+ ...playerContext.npoPlayer.streamObject,
36
+ stream: { ...playerContext.npoPlayer.streamObject.stream, drmToken: newDrmToken }
37
37
  };
38
- playerContext.npoplayer.streamObject = clonedStreamObject;
39
- await loadPlayer(playerContext, playerContext.npoplayer.sourceConfig);
38
+ playerContext.npoPlayer.streamObject = clonedStreamObject;
39
+ await loadPlayer(playerContext, playerContext.npoPlayer.sourceConfig);
40
40
  }
@@ -18,7 +18,7 @@ beforeEach(() => {
18
18
  streamObject: { stream: { drmToken: undefined } },
19
19
  load: jest.fn()
20
20
  };
21
- mockPlayerContext = { player: mockPlayer, npoplayer: mockNpoplayer };
21
+ mockPlayerContext = { player: mockPlayer, npoPlayer: mockNpoplayer };
22
22
  });
23
23
  afterEach(() => {
24
24
  jest.clearAllMocks();
@@ -42,7 +42,7 @@ describe('Test DRM verification', () => {
42
42
  streamURL: '',
43
43
  drmToken: drmToken
44
44
  };
45
- mockPlayerContext.npoplayer.sourceConfig = sourceConfig;
45
+ mockPlayerContext.npoPlayer.sourceConfig = sourceConfig;
46
46
  jest.spyOn(global.Date, 'now').mockImplementation(() => currentTime * 1000);
47
47
  convertJwtToBase64.mockReturnValue(JSON.stringify({ iat: drmJsonTimestamp }));
48
48
  convertBase64ToObject.mockReturnValue({ iat: drmJsonTimestamp });
@@ -62,14 +62,14 @@ describe('Test DRM verification', () => {
62
62
  streamURL: '',
63
63
  drmToken: drmToken
64
64
  };
65
- mockPlayerContext.npoplayer.sourceConfig = sourceConfig;
65
+ mockPlayerContext.npoPlayer.sourceConfig = sourceConfig;
66
66
  jest.spyOn(global.Date, 'now').mockImplementation(() => currentTime * 1000);
67
67
  convertJwtToBase64.mockReturnValue(JSON.stringify({ iat: drmJsonTimestamp }));
68
68
  convertBase64ToObject.mockReturnValue({ iat: drmJsonTimestamp });
69
69
  getStreamObject.mockResolvedValue({ stream: { drmToken: 'newToken' } });
70
70
  jest.spyOn(mockPlayerContext.player, 'load').mockResolvedValue(undefined);
71
71
  await verifyDRM(mockPlayerContext, payload);
72
- expect(getStreamObject).toHaveBeenCalledWith(mockPlayerContext.npoplayer, payload);
72
+ expect(getStreamObject).toHaveBeenCalledWith(mockPlayerContext.npoPlayer, payload);
73
73
  expect(mockPlayerContext.player.load).toHaveBeenCalledWith(sourceConfig);
74
74
  });
75
75
  it('should call loadPlayer when the drmToken is null', async () => {
@@ -82,7 +82,7 @@ describe('Test DRM verification', () => {
82
82
  streamURL: '',
83
83
  drmToken: undefined
84
84
  };
85
- mockPlayerContext.npoplayer.sourceConfig = sourceConfig;
85
+ mockPlayerContext.npoPlayer.sourceConfig = sourceConfig;
86
86
  await verifyDRM(mockPlayerContext, payload);
87
87
  expect(mockPlayerContext.player.load).toHaveBeenCalledWith(sourceConfig);
88
88
  });
@@ -1,6 +1,6 @@
1
1
  import { NpoPlayerEvent } from '../../types/events';
2
2
  export const removeEventListeners = (playerContext) => {
3
- const { eventListeners } = playerContext.npoplayer;
3
+ const { eventListeners } = playerContext.npoPlayer;
4
4
  if (eventListeners) {
5
5
  const { segmentHandleTimeChangedCallback, segmentSeekFunctionCallback, liveStreamHandleTimeChangedCallback } = eventListeners;
6
6
  const eventMapping = [
@@ -13,6 +13,6 @@ export const removeEventListeners = (playerContext) => {
13
13
  playerContext.player.off(event, callback);
14
14
  }
15
15
  }
16
- playerContext.npoplayer.eventListeners = undefined;
16
+ playerContext.npoPlayer.eventListeners = undefined;
17
17
  }
18
18
  };
@@ -8,35 +8,35 @@ describe('removeEventListeners', () => {
8
8
  mockPlayerContext = createPlayerContextMock();
9
9
  });
10
10
  it('should remove TimeChanged event listener if exists', () => {
11
- mockPlayerContext.npoplayer.eventListeners = {
11
+ mockPlayerContext.npoPlayer.eventListeners = {
12
12
  segmentHandleTimeChangedCallback: jest.fn(),
13
13
  liveStreamHandleTimeChangedCallback: jest.fn(),
14
14
  segmentSeekFunctionCallback: jest.fn()
15
15
  };
16
16
  removeEventListeners(mockPlayerContext);
17
- if (mockPlayerContext.npoplayer.eventListeners) {
18
- expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, mockPlayerContext.npoplayer.eventListeners.segmentHandleTimeChangedCallback);
19
- expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, mockPlayerContext.npoplayer.eventListeners.liveStreamHandleTimeChangedCallback);
17
+ if (mockPlayerContext.npoPlayer.eventListeners) {
18
+ expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, mockPlayerContext.npoPlayer.eventListeners.segmentHandleTimeChangedCallback);
19
+ expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, mockPlayerContext.npoPlayer.eventListeners.liveStreamHandleTimeChangedCallback);
20
20
  }
21
21
  });
22
22
  it('should remove Seek event listener if exists', () => {
23
- mockPlayerContext.npoplayer.eventListeners = {
23
+ mockPlayerContext.npoPlayer.eventListeners = {
24
24
  segmentHandleTimeChangedCallback: jest.fn(),
25
25
  liveStreamHandleTimeChangedCallback: jest.fn(),
26
26
  segmentSeekFunctionCallback: jest.fn()
27
27
  };
28
28
  removeEventListeners(mockPlayerContext);
29
- if (mockPlayerContext.npoplayer.eventListeners) {
30
- expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.Seek, mockPlayerContext.npoplayer.eventListeners.segmentSeekFunctionCallback);
29
+ if (mockPlayerContext.npoPlayer.eventListeners) {
30
+ expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.Seek, mockPlayerContext.npoPlayer.eventListeners.segmentSeekFunctionCallback);
31
31
  }
32
32
  });
33
33
  it('should reset EventListeners in playerContext', () => {
34
- mockPlayerContext.npoplayer.eventListeners = {
34
+ mockPlayerContext.npoPlayer.eventListeners = {
35
35
  segmentHandleTimeChangedCallback: jest.fn(),
36
36
  liveStreamHandleTimeChangedCallback: jest.fn(),
37
37
  segmentSeekFunctionCallback: jest.fn()
38
38
  };
39
39
  removeEventListeners(mockPlayerContext);
40
- expect(mockPlayerContext.npoplayer.eventListeners).toBeUndefined();
40
+ expect(mockPlayerContext.npoPlayer.eventListeners).toBeUndefined();
41
41
  });
42
42
  });
@@ -23,17 +23,17 @@ export function resolveKeyPress(playerContext, e) {
23
23
  ArrowUp: () => {
24
24
  if (isMuted)
25
25
  playerContext.player.unmute();
26
- playerContext.npoplayer.increaseVolume();
26
+ playerContext.npoPlayer.increaseVolume();
27
27
  },
28
28
  ArrowDown: () => {
29
29
  if (isMuted)
30
30
  playerContext.player.unmute();
31
- playerContext.npoplayer.decreaseVolume();
31
+ playerContext.npoPlayer.decreaseVolume();
32
32
  },
33
- ArrowLeft: () => playerContext.npoplayer.goBackwards(10),
34
- ArrowRight: () => playerContext.npoplayer.goForward(10),
33
+ ArrowLeft: () => playerContext.npoPlayer.goBackwards(10),
34
+ ArrowRight: () => playerContext.npoPlayer.goForward(10),
35
35
  Escape: () => {
36
- const { settingsPanels } = playerContext.npoplayer.uiComponents;
36
+ const { settingsPanels } = playerContext.npoPlayer.uiComponents;
37
37
  if (settingsPanels && settingsPanels.length > 0) {
38
38
  for (const panel of settingsPanels) {
39
39
  if (panel.isShown()) {
@@ -32,7 +32,7 @@ describe('resolveKeyPress', () => {
32
32
  })
33
33
  };
34
34
  e = new KeyboardEvent('keydown');
35
- mockPlayerContext = { player: mockPlayer, npoplayer: mockNpoplayer };
35
+ mockPlayerContext = { player: mockPlayer, npoPlayer: mockNpoplayer };
36
36
  });
37
37
  it('should mute/unmute the player when "KeyM" is pressed', () => {
38
38
  mockPlayer.isMuted.mockReturnValue(true);
@@ -1,9 +1,9 @@
1
1
  import { NpoPlayerEvent } from '../../types/events';
2
2
  export const handleLiveStreamControls = (playerContext) => {
3
3
  const liveStreamHandleTimeChangedCallback = () => updateForwardButtonState(playerContext.player);
4
- const { player, npoplayer } = playerContext;
4
+ const { player, npoPlayer } = playerContext;
5
5
  player.on(NpoPlayerEvent.TimeChanged, liveStreamHandleTimeChangedCallback);
6
- npoplayer.eventListeners = {
6
+ npoPlayer.eventListeners = {
7
7
  liveStreamHandleTimeChangedCallback
8
8
  };
9
9
  };
@@ -11,8 +11,8 @@ describe('handleLiveStreamControls', () => {
11
11
  });
12
12
  it('should add TimeChanged event listener and store it in eventListeners', () => {
13
13
  handleLiveStreamControls(mockPlayerContext);
14
- expect(mockPlayerContext.player.on).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, mockPlayerContext.npoplayer.eventListeners?.liveStreamHandleTimeChangedCallback);
15
- expect(mockPlayerContext.npoplayer.eventListeners?.liveStreamHandleTimeChangedCallback).toBeDefined();
14
+ expect(mockPlayerContext.player.on).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, mockPlayerContext.npoPlayer.eventListeners?.liveStreamHandleTimeChangedCallback);
15
+ expect(mockPlayerContext.npoPlayer.eventListeners?.liveStreamHandleTimeChangedCallback).toBeDefined();
16
16
  });
17
17
  });
18
18
  describe('updateForwardButtonState', () => {
@@ -18,7 +18,7 @@ export function getLocalStorage() {
18
18
  }
19
19
  export function setValuesBasedOnLocalStorage(playerContext) {
20
20
  const localStorageData = getLocalStorage();
21
- const player = playerContext.player;
21
+ const { player } = playerContext;
22
22
  if (!player) {
23
23
  console.error('Player is undefined in playerContext');
24
24
  return;
@@ -28,6 +28,6 @@ export function setValuesBasedOnLocalStorage(playerContext) {
28
28
  player.mute();
29
29
  }
30
30
  if (localStorageData.subtitles_enabled === 'true') {
31
- playerContext.npoplayer.streamOptions.enableSubtitles = true;
31
+ playerContext.npoPlayer.streamOptions.enableSubtitles = true;
32
32
  }
33
33
  }
@@ -54,14 +54,11 @@ describe('localStorageHandler', () => {
54
54
  };
55
55
  playerContext = {
56
56
  player: mockPlayerAPI,
57
- npoplayer: {
57
+ npoPlayer: {
58
58
  ...mockNpoPlayer,
59
59
  streamOptions: {
60
60
  enableSubtitles: false
61
61
  },
62
- userPreferences: {
63
- subtitles_enabled: 'false'
64
- },
65
62
  container: document.createElement('div'),
66
63
  streamObject: {},
67
64
  playerConfig: {},
@@ -102,7 +99,7 @@ describe('localStorageHandler', () => {
102
99
  it('should enable subtitles if localStorage subtitles_enabled is true', () => {
103
100
  localStorage.setItem('npoplayer-subtitles_enabled', JSON.stringify('true'));
104
101
  setValuesBasedOnLocalStorage(playerContext);
105
- expect(playerContext.npoplayer.streamOptions.enableSubtitles).toBe(true);
102
+ expect(playerContext.npoPlayer.streamOptions.enableSubtitles).toBe(true);
106
103
  });
107
104
  });
108
105
  });
@@ -0,0 +1,5 @@
1
+ import { PlayerContext } from '../../types/interfaces';
2
+ export declare function processNicam(playerContext: PlayerContext, nicamElement: HTMLElement | undefined): void;
3
+ export declare function addNicamIcon(character: string, nicamElement: Element): void;
4
+ export declare function showNicamAfterUiDelay(playerContext: PlayerContext): void;
5
+ export declare function setupNicamKijkwijzerIcons(playerContext: PlayerContext): void;
@@ -1,6 +1,8 @@
1
- import { PlayerEvent } from 'bitmovin-player';
2
- export function processNicam(streamObject, nicamElement, streamOptions) {
3
- const effectiveMetadata = streamOptions ? { ...streamObject.metadata, ...streamOptions } : streamObject.metadata;
1
+ import { NpoPlayerEvent } from '../../types/events';
2
+ export function processNicam(playerContext, nicamElement) {
3
+ const streamOptions = playerContext.npoPlayer.streamOptions;
4
+ const metadata = playerContext?.npoPlayer?.streamObject?.metadata ?? {};
5
+ const effectiveMetadata = { ...metadata, ...streamOptions };
4
6
  if (nicamElement) {
5
7
  nicamElement.innerHTML = '';
6
8
  if (effectiveMetadata.ageRating !== undefined && isNicamIconValid(effectiveMetadata.ageRating.toLowerCase())) {
@@ -43,21 +45,28 @@ export function addNicamIcon(character, nicamElement) {
43
45
  span.classList.add('nicam-icon', iconClass);
44
46
  nicamElement.appendChild(span);
45
47
  }
46
- export function showNicamAfterUiDelay(player, uiManager) {
47
- player.off(PlayerEvent.Play, () => {
48
- showNicamAfterUiDelay(player, uiManager);
48
+ export function showNicamAfterUiDelay(playerContext) {
49
+ const { player, npoPlayer } = playerContext;
50
+ const { uiManager } = npoPlayer;
51
+ const showNicamClassName = 'bmpui-show-nicam';
52
+ const playerContainer = player.getNpoPlayerElement();
53
+ player.off(NpoPlayerEvent.Ready, () => {
54
+ npoPlayer.npoPlayerServices.showNicamAfterUiDelay(playerContext);
49
55
  });
50
- if (uiManager === null)
56
+ if (!playerContainer || !uiManager)
51
57
  return;
52
- const playerContainer = player.getContainer().querySelector('.bmpui-npo-player.bmpui-layout-max-width-400') ||
53
- player.getContainer().querySelector('.bmpui-npo-player.bmpui-layout-max-width-600');
54
- if (!playerContainer)
55
- return;
56
- uiManager?.activeUi.onControlsHide.subscribeOnce(() => {
57
- const className = 'bmpui-show-nicam';
58
- playerContainer.classList.add(className);
58
+ uiManager.activeUi.onControlsHide.subscribe(() => {
59
+ playerContainer.classList.add(showNicamClassName);
59
60
  setTimeout(() => {
60
- playerContainer.classList.remove(className);
61
+ playerContainer.classList.remove(showNicamClassName);
61
62
  }, 3000);
62
63
  });
64
+ uiManager?.activeUi.onControlsShow.subscribe(() => {
65
+ playerContainer.classList.remove(showNicamClassName);
66
+ });
67
+ }
68
+ export function setupNicamKijkwijzerIcons(playerContext) {
69
+ const { container } = playerContext.npoPlayer;
70
+ const nicamElement = container.querySelector('.bmpui-nicam');
71
+ processNicam(playerContext, nicamElement);
63
72
  }