@npo/player 1.26.0 → 1.27.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 (175) hide show
  1. package/README.md +1 -1
  2. package/lib/js/playeractions/handlers/mediasessionactions.js +2 -2
  3. package/lib/js/playeractions/playeractions.d.ts +0 -1
  4. package/lib/js/playeractions/playeractions.js +0 -1
  5. package/lib/js/utilities/utilities.prid.d.ts +6 -0
  6. package/lib/js/utilities/utilities.prid.js +8 -0
  7. package/lib/js/utilities/utilities.prid.test.js +46 -0
  8. package/lib/npoplayer.d.ts +1 -1
  9. package/lib/npoplayer.js +50 -59
  10. package/lib/npoplayer.test.js +2 -2
  11. package/lib/package.json +1 -1
  12. package/lib/services/a11y/setup.test.js +0 -1
  13. package/lib/services/advertHandlers/discardAdBreak.js +2 -0
  14. package/lib/services/advertHandlers/discardAdBreak.test.js +6 -1
  15. package/lib/services/advertHandlers/handlePreRolls.js +2 -4
  16. package/lib/services/advertHandlers/handlePrerolls.test.js +62 -1
  17. package/lib/services/drmHandlers/decideprofile.js +7 -1
  18. package/lib/services/drmHandlers/decideprofile.test.js +4 -0
  19. package/lib/services/drmHandlers/verifydrm.js +5 -6
  20. package/lib/services/drmHandlers/verifydrm.test.js +28 -5
  21. package/lib/services/errors/errorBackground.test.js +48 -0
  22. package/lib/services/errors/errorHandler.d.ts +3 -0
  23. package/lib/services/errors/errorHandler.js +45 -0
  24. package/lib/services/errors/errorText.d.ts +2 -0
  25. package/lib/services/errors/errorText.js +59 -0
  26. package/lib/services/errors/errorText.test.js +66 -0
  27. package/lib/services/keyboardHandlers/resolvekeypress.js +21 -17
  28. package/lib/services/localStorageHandlers/localStorageHandlers.js +5 -2
  29. package/lib/services/localStorageHandlers/localStorageHandlers.test.js +0 -1
  30. package/lib/services/nicamHandlers/nicamhandler.js +0 -4
  31. package/lib/services/nicamHandlers/nicamhandler.test.js +0 -5
  32. package/lib/services/npoPlayerAPI/contants.d.ts +20 -0
  33. package/lib/services/npoPlayerAPI/contants.js +6 -0
  34. package/lib/services/npoPlayerAPI/npoPlayerAPI.d.ts +4 -1
  35. package/lib/services/npoPlayerAPI/npoPlayerAPI.js +29 -5
  36. package/lib/services/npoPlayerAPI/npoPlayerAPI.test.js +11 -0
  37. package/lib/services/services.d.ts +8 -2
  38. package/lib/services/services.js +28 -2
  39. package/lib/services/streamFetchHandler/fetchStream.d.ts +2 -0
  40. package/lib/services/streamFetchHandler/fetchStream.js +48 -0
  41. package/lib/services/streamFetchHandler/fetchstream.test.js +70 -0
  42. package/lib/services/trackingHandlers/eventBinding.d.ts +2 -0
  43. package/lib/{js/tracking/handlers/eventbinding.js → services/trackingHandlers/eventBinding.js} +16 -14
  44. package/lib/services/trackingHandlers/eventBinding.test.js +89 -0
  45. package/lib/services/trackingHandlers/eventLogging.d.ts +2 -0
  46. package/lib/{js/tracking/handlers/eventlogging.js → services/trackingHandlers/eventLogging.js} +18 -7
  47. package/lib/services/trackingHandlers/eventLogging.test.js +63 -0
  48. package/lib/services/trackingHandlers/index.d.ts +3 -0
  49. package/lib/services/trackingHandlers/index.js +3 -0
  50. package/lib/services/trackingHandlers/playerTrackerInit.d.ts +2 -0
  51. package/lib/{js/tracking/handlers/playertrackerinit.js → services/trackingHandlers/playerTrackerInit.js} +6 -3
  52. package/lib/services/trackingHandlers/playerTrackerInit.test.js +75 -0
  53. package/lib/services/trackingHandlers/playerTrackerStart.d.ts +2 -0
  54. package/lib/services/trackingHandlers/playerTrackerStart.js +25 -0
  55. package/lib/services/trackingHandlers/playerTrackerStart.test.js +59 -0
  56. package/lib/services/trackingHandlers/streamTrackerInit.d.ts +3 -0
  57. package/lib/services/trackingHandlers/streamTrackerInit.js +27 -0
  58. package/lib/services/trackingHandlers/streamTrackerInit.test.js +84 -0
  59. package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.d.ts +2 -2
  60. package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.js +4 -6
  61. package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.test.js +4 -17
  62. package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.d.ts +2 -0
  63. package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.js +26 -0
  64. package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.test.js +82 -0
  65. package/lib/src/js/playeractions/playeractions.d.ts +0 -1
  66. package/lib/src/js/utilities/utilities.prid.d.ts +6 -0
  67. package/lib/src/js/utilities/utilities.prid.test.d.ts +1 -0
  68. package/lib/src/npoplayer.d.ts +1 -1
  69. package/lib/src/services/errors/errorBackground.test.d.ts +1 -0
  70. package/lib/src/services/errors/errorHandler.d.ts +3 -0
  71. package/lib/src/services/errors/errorText.d.ts +2 -0
  72. package/lib/src/services/errors/errorText.test.d.ts +1 -0
  73. package/lib/src/services/npoPlayerAPI/contants.d.ts +20 -0
  74. package/lib/src/services/npoPlayerAPI/npoPlayerAPI.d.ts +4 -1
  75. package/lib/src/services/services.d.ts +8 -2
  76. package/lib/src/services/streamFetchHandler/fetchStream.d.ts +2 -0
  77. package/lib/src/services/streamFetchHandler/fetchstream.test.d.ts +1 -0
  78. package/lib/src/services/trackingHandlers/eventBinding.d.ts +2 -0
  79. package/lib/src/services/trackingHandlers/eventBinding.test.d.ts +1 -0
  80. package/lib/src/services/trackingHandlers/eventLogging.d.ts +2 -0
  81. package/lib/src/services/trackingHandlers/eventLogging.test.d.ts +1 -0
  82. package/lib/src/services/trackingHandlers/index.d.ts +3 -0
  83. package/lib/src/services/trackingHandlers/playerTrackerInit.d.ts +2 -0
  84. package/lib/src/services/trackingHandlers/playerTrackerInit.test.d.ts +1 -0
  85. package/lib/src/services/trackingHandlers/playerTrackerStart.d.ts +2 -0
  86. package/lib/src/services/trackingHandlers/playerTrackerStart.test.d.ts +1 -0
  87. package/lib/src/services/trackingHandlers/streamTrackerInit.d.ts +3 -0
  88. package/lib/src/services/trackingHandlers/streamTrackerInit.test.d.ts +1 -0
  89. package/lib/src/services/verticalVideoHandlers/handleVerticalVideoControls.d.ts +2 -2
  90. package/lib/src/services/verticalVideoHandlers/handleVerticalVideoSettings.d.ts +2 -0
  91. package/lib/src/services/verticalVideoHandlers/handleVerticalVideoSettings.test.d.ts +1 -0
  92. package/lib/src/types/interfaces.d.ts +15 -1
  93. package/lib/src/ui/components/seekbar.d.ts +2 -1
  94. package/lib/src/ui/components/verticalvideo/controlbar.d.ts +3 -3
  95. package/lib/src/ui/components/verticalvideo/settingspanel.d.ts +2 -0
  96. package/lib/tests/mocks/mockNpoplayer.js +1 -1
  97. package/lib/tests/mocks/mockStreamObject.d.ts +2 -0
  98. package/lib/tests/mocks/mockStreamObject.js +21 -0
  99. package/lib/tests/mocks/playerContextMock.d.ts +1 -0
  100. package/lib/tests/mocks/playerContextMock.js +5 -1
  101. package/lib/types/interfaces.d.ts +15 -1
  102. package/lib/ui/components/audio/controlbar.js +2 -1
  103. package/lib/ui/components/controlbar.js +1 -1
  104. package/lib/ui/components/seekbar.d.ts +2 -1
  105. package/lib/ui/components/seekbar.js +2 -2
  106. package/lib/ui/components/settingspanel.js +1 -3
  107. package/lib/ui/components/verticalvideo/controlbar.d.ts +3 -3
  108. package/lib/ui/components/verticalvideo/controlbar.js +14 -11
  109. package/lib/ui/components/verticalvideo/settingspanel.d.ts +2 -0
  110. package/lib/ui/components/verticalvideo/settingspanel.js +21 -0
  111. package/lib/ui/handlers/domhandlers.test.js +6 -26
  112. package/lib/ui/nativemobileuifactory.js +1 -1
  113. package/lib/ui/uicontainer.js +4 -1
  114. package/lib/ui/uicontainer.test.js +4 -1
  115. package/package.json +1 -1
  116. package/src/style/components/_advert.scss +3 -3
  117. package/src/style/components/_buffering.scss +14 -8
  118. package/src/style/components/_error.scss +44 -1
  119. package/src/style/components/_hugeplaybacktogglebutton.scss +1 -0
  120. package/src/style/components/_metadata.scss +13 -12
  121. package/src/style/components/_nicam.scss +11 -6
  122. package/src/style/components/_playnext.scss +1 -1
  123. package/src/style/components/_replay.scss +1 -6
  124. package/src/style/components/_settingspanel.scss +74 -79
  125. package/src/style/components/audio/_errors.scss +1 -1
  126. package/src/style/components/audio/_metadata.scss +14 -8
  127. package/src/style/components/audio/_playbutton.scss +1 -0
  128. package/src/style/components/audio/_topbar.scss +10 -2
  129. package/src/style/components/audio/_volumeslider.scss +3 -3
  130. package/src/style/components/vertical-video/_bottombar.scss +42 -1
  131. package/src/style/components/vertical-video/_hugeplaybacktogglebutton.scss +24 -4
  132. package/src/style/components/vertical-video/_settingspanel.scss +20 -3
  133. package/src/style/components/vertical-video/_topbar.scss +47 -6
  134. package/src/style/npoplayer.css +86 -53
  135. package/src/style/npoplayer.scss +4 -7
  136. package/src/style/variants/_player-base.scss +10 -2
  137. package/src/style/variants/_player-small.scss +15 -1
  138. package/src/style/vars/_fonts.scss +13 -7
  139. package/src/style/vars/_z-index.scss +1 -0
  140. package/lib/js/api/getstreamobject.d.ts +0 -3
  141. package/lib/js/api/getstreamobject.js +0 -38
  142. package/lib/js/api/getstreamobject.test.js +0 -48
  143. package/lib/js/playeractions/customerrors.test.js +0 -51
  144. package/lib/js/playeractions/handlers/customerrors.d.ts +0 -50
  145. package/lib/js/playeractions/handlers/customerrors.js +0 -56
  146. package/lib/js/playeractions/handlers/error.d.ts +0 -3
  147. package/lib/js/playeractions/handlers/error.js +0 -14
  148. package/lib/js/playeractions/handlers/error.test.js +0 -44
  149. package/lib/js/tracking/handlers/eventbinding.d.ts +0 -3
  150. package/lib/js/tracking/handlers/eventlogging.d.ts +0 -2
  151. package/lib/js/tracking/handlers/eventlogging.test.js +0 -46
  152. package/lib/js/tracking/handlers/playertrackerinit.d.ts +0 -4
  153. package/lib/js/tracking/handlers/playertrackerinit.test.js +0 -74
  154. package/lib/js/tracking/handlers/playertrackerstart.d.ts +0 -1
  155. package/lib/js/tracking/handlers/playertrackerstart.js +0 -25
  156. package/lib/js/tracking/playertracker.d.ts +0 -4
  157. package/lib/js/tracking/playertracker.js +0 -4
  158. package/lib/src/js/api/getstreamobject.d.ts +0 -3
  159. package/lib/src/js/playeractions/handlers/customerrors.d.ts +0 -50
  160. package/lib/src/js/playeractions/handlers/error.d.ts +0 -3
  161. package/lib/src/js/tracking/handlers/eventbinding.d.ts +0 -3
  162. package/lib/src/js/tracking/handlers/eventlogging.d.ts +0 -2
  163. package/lib/src/js/tracking/handlers/playertrackerinit.d.ts +0 -4
  164. package/lib/src/js/tracking/handlers/playertrackerstart.d.ts +0 -1
  165. package/lib/src/js/tracking/playertracker.d.ts +0 -4
  166. /package/lib/js/{api/getstreamobject.test.d.ts → utilities/utilities.prid.test.d.ts} +0 -0
  167. /package/lib/{js/playeractions/customerrors.test.d.ts → services/errors/errorBackground.test.d.ts} +0 -0
  168. /package/lib/{js/playeractions/handlers/error.test.d.ts → services/errors/errorText.test.d.ts} +0 -0
  169. /package/lib/{js/tracking/handlers/eventlogging.test.d.ts → services/streamFetchHandler/fetchstream.test.d.ts} +0 -0
  170. /package/lib/{js/tracking/handlers/playertrackerinit.test.d.ts → services/trackingHandlers/eventBinding.test.d.ts} +0 -0
  171. /package/lib/{src/js/api/getstreamobject.test.d.ts → services/trackingHandlers/eventLogging.test.d.ts} +0 -0
  172. /package/lib/{src/js/playeractions/customerrors.test.d.ts → services/trackingHandlers/playerTrackerInit.test.d.ts} +0 -0
  173. /package/lib/{src/js/playeractions/handlers/error.test.d.ts → services/trackingHandlers/playerTrackerStart.test.d.ts} +0 -0
  174. /package/lib/{src/js/tracking/handlers/eventlogging.test.d.ts → services/trackingHandlers/streamTrackerInit.test.d.ts} +0 -0
  175. /package/lib/{src/js/tracking/handlers/playertrackerinit.test.d.ts → services/verticalVideoHandlers/handleVerticalVideoSettings.test.d.ts} +0 -0
@@ -0,0 +1,84 @@
1
+ import { initStreamTracker } from './streamTrackerInit';
2
+ import { newStreamTracker } from '@npotag/tag';
3
+ jest.mock('@npotag/tag', () => ({
4
+ newATInternetPlugin: jest.fn(),
5
+ newStreamTracker: jest.fn().mockImplementation(() => {
6
+ return {};
7
+ }),
8
+ newGovoltePlugin: jest.fn(),
9
+ newPageTracker: jest.fn(),
10
+ newTag: jest.fn()
11
+ }));
12
+ jest.mock('../../js/utilities/utilities.stream', () => ({
13
+ validatePrid: jest.fn().mockReturnValue('valid-prid')
14
+ }));
15
+ describe('initStreamTracker', () => {
16
+ let playerContextMock;
17
+ beforeEach(() => {
18
+ jest.clearAllMocks();
19
+ playerContextMock = {
20
+ npoPlayer: {
21
+ streamTracker: undefined,
22
+ npoTag: {
23
+ npoTagInstance: { foo: 'bar' },
24
+ pageTracker: { foo: 'bar' }
25
+ },
26
+ npoPlayerServices: { getAVType: jest.fn().mockReturnValue('video') },
27
+ version: '1.0.0',
28
+ streamObject: { stream: { isLiveStream: true, avType: 'video' } }
29
+ }
30
+ };
31
+ });
32
+ it('should create a new StreamTracker with correct configuration', () => {
33
+ const streamTracker = initStreamTracker({
34
+ playerContext: playerContextMock,
35
+ duration: 100,
36
+ source: 'source'
37
+ });
38
+ expect(streamTracker).toBeDefined();
39
+ expect(newStreamTracker).toHaveBeenCalledWith(playerContextMock.npoPlayer.npoTag.pageTracker, expect.objectContaining({
40
+ stream_length: 100,
41
+ stream_id: 'valid-prid',
42
+ player_id: 'npoplayer-web',
43
+ av_type: 'video',
44
+ player_version: '1.0.0',
45
+ sko_player_version: '1.0.0'
46
+ }), { isLive: true });
47
+ });
48
+ it('should throw an error if npoTagInstance is not available', () => {
49
+ console.error = jest.fn();
50
+ const playerContextWithoutTagInstance = {
51
+ ...playerContextMock,
52
+ npoPlayer: {
53
+ ...playerContextMock.npoPlayer,
54
+ npoTag: { npoTagInstance: undefined, pageTracker: { foo: 'bar' } }
55
+ }
56
+ };
57
+ expect(() => {
58
+ initStreamTracker({
59
+ playerContext: playerContextWithoutTagInstance,
60
+ duration: 100,
61
+ source: 'source'
62
+ });
63
+ }).toThrowError('No npoTagInstance available. Could not create streamtracker.');
64
+ expect(newStreamTracker).not.toHaveBeenCalled();
65
+ });
66
+ it('should throw an error if pageTracker is not available', () => {
67
+ console.error = jest.fn();
68
+ const playerContextWithoutTracker = {
69
+ ...playerContextMock,
70
+ npoPlayer: {
71
+ ...playerContextMock.npoPlayer,
72
+ npoTag: { npoTagInstance: { foo: 'bar' }, pageTracker: undefined }
73
+ }
74
+ };
75
+ expect(() => {
76
+ initStreamTracker({
77
+ playerContext: playerContextWithoutTracker,
78
+ duration: 100,
79
+ source: 'source'
80
+ });
81
+ }).toThrowError('No pageTracker available. Could not create streamtracker.');
82
+ expect(newStreamTracker).not.toHaveBeenCalled();
83
+ });
84
+ });
@@ -1,2 +1,2 @@
1
- import { PlayerContext, NpoPlayerUIVariants } from '../../types/interfaces';
2
- export declare const handleVerticalVideoControls: (playerContext: PlayerContext, variant: NpoPlayerUIVariants) => void;
1
+ import { PlayerContext } from '../../types/interfaces';
2
+ export declare const handleVerticalVideoControls: (playerContext: PlayerContext) => void;
@@ -1,8 +1,6 @@
1
- import { NpoPlayerUIVariants } from '../../types/interfaces';
2
- export const handleVerticalVideoControls = (playerContext, variant) => {
1
+ export const handleVerticalVideoControls = (playerContext) => {
2
+ const { player } = playerContext;
3
3
  const MAX_DURATION_IN_SECONDS = 30;
4
- const isShortVideo = playerContext.player.getDuration() <= MAX_DURATION_IN_SECONDS;
5
- const hasVerticalUI = variant === NpoPlayerUIVariants.VERTICAL;
6
- const isVerticalShortVideo = hasVerticalUI && isShortVideo;
7
- playerContext.player.toggleClassOnNpoPlayerElement('vertical-short-video', isVerticalShortVideo);
4
+ const isShortVideo = player.getDuration() <= MAX_DURATION_IN_SECONDS;
5
+ player.toggleClassOnNpoPlayerElement('vertical-short-video', isShortVideo);
8
6
  };
@@ -1,4 +1,3 @@
1
- import { NpoPlayerUIVariants } from '../../types/interfaces';
2
1
  import { handleVerticalVideoControls } from './handleVerticalVideoControls';
3
2
  import createPlayerContextMock from '../../../tests/mocks/playerContextMock';
4
3
  describe('handleVerticalVideoControls', () => {
@@ -9,28 +8,16 @@ describe('handleVerticalVideoControls', () => {
9
8
  beforeEach(() => {
10
9
  jest.clearAllMocks();
11
10
  });
12
- test('should add vertical-short-video class for vertical UI and short video', () => {
11
+ test('should add vertical-short-video class for short video', () => {
13
12
  ;
14
13
  playerContextMock.player.getDuration.mockReturnValue(shortVideoDuration);
15
- handleVerticalVideoControls(playerContextMock, NpoPlayerUIVariants.VERTICAL);
14
+ handleVerticalVideoControls(playerContextMock);
16
15
  expect(playerContextMock.player.toggleClassOnNpoPlayerElement).toHaveBeenCalledWith(shortVideoClass, true);
17
16
  });
18
- test('should not add vertical-short-video class for vertical UI and long video', () => {
17
+ test('should not add vertical-short-video class for long video', () => {
19
18
  ;
20
19
  playerContextMock.player.getDuration.mockReturnValue(longVideoDuration);
21
- handleVerticalVideoControls(playerContextMock, NpoPlayerUIVariants.VERTICAL);
22
- expect(playerContextMock.player.toggleClassOnNpoPlayerElement).toHaveBeenCalledWith(shortVideoClass, false);
23
- });
24
- test('should not add vertical-short-video class for non-vertical UI and short video', () => {
25
- ;
26
- playerContextMock.player.getDuration.mockReturnValue(shortVideoDuration);
27
- handleVerticalVideoControls(playerContextMock, NpoPlayerUIVariants.DEFAULT);
28
- expect(playerContextMock.player.toggleClassOnNpoPlayerElement).toHaveBeenCalledWith(shortVideoClass, false);
29
- });
30
- test('should not add vertical-short-video class for non-vertical UI and long video', () => {
31
- ;
32
- playerContextMock.player.getDuration.mockReturnValue(longVideoDuration);
33
- handleVerticalVideoControls(playerContextMock, NpoPlayerUIVariants.DEFAULT);
20
+ handleVerticalVideoControls(playerContextMock);
34
21
  expect(playerContextMock.player.toggleClassOnNpoPlayerElement).toHaveBeenCalledWith(shortVideoClass, false);
35
22
  });
36
23
  });
@@ -0,0 +1,2 @@
1
+ import { PlayerContext } from '../../types/interfaces';
2
+ export declare function handleVerticalVideoSettings(playerContext: PlayerContext): void;
@@ -0,0 +1,26 @@
1
+ import { NpoPlayerEvent } from '../../types/events';
2
+ export function handleVerticalVideoSettings(playerContext) {
3
+ const { npoPlayer, player } = playerContext;
4
+ const { settingsPanel, settingsToggleButton } = npoPlayer.uiComponents;
5
+ if (!player || !settingsPanel || !settingsToggleButton)
6
+ return;
7
+ const hideSettingsElements = () => {
8
+ hideSettingsPanel();
9
+ settingsToggleButton.hide();
10
+ };
11
+ const checkSubtitles = () => {
12
+ const subtitles = npoPlayer.player?.subtitles?.list() || [];
13
+ subtitles.length > 0 ? settingsToggleButton.show() : hideSettingsElements();
14
+ };
15
+ const hideSettingsPanel = () => settingsPanel.hide();
16
+ player.off(NpoPlayerEvent.Ready, checkSubtitles);
17
+ player.off(NpoPlayerEvent.SourceLoaded, checkSubtitles);
18
+ player.off(NpoPlayerEvent.SourceUnloaded, hideSettingsElements);
19
+ player.off(NpoPlayerEvent.SubtitleDisable, hideSettingsPanel);
20
+ player.off(NpoPlayerEvent.SubtitleEnable, hideSettingsPanel);
21
+ player.on(NpoPlayerEvent.Ready, checkSubtitles);
22
+ player.on(NpoPlayerEvent.SourceLoaded, checkSubtitles);
23
+ player.on(NpoPlayerEvent.SourceUnloaded, hideSettingsElements);
24
+ player.on(NpoPlayerEvent.SubtitleDisable, hideSettingsPanel);
25
+ player.on(NpoPlayerEvent.SubtitleEnable, hideSettingsPanel);
26
+ }
@@ -0,0 +1,82 @@
1
+ import { handleVerticalVideoSettings } from './handleVerticalVideoSettings';
2
+ import { NpoPlayerEvent } from '../../types/events';
3
+ import { createMockNpoPlayer, createPlayerContextMock } from '../../../tests/mocks/playerContextMock';
4
+ jest.mock('bitmovin-player', () => ({
5
+ PlayerEvent: {
6
+ Ready: 'ready',
7
+ SourceLoaded: 'sourceLoaded',
8
+ SourceUnloaded: 'sourceUnloaded',
9
+ SubtitleDisable: 'subtitleDisable',
10
+ SubtitleEnable: 'subtitleEnable'
11
+ }
12
+ }));
13
+ describe('handleVerticalVideoSettings', () => {
14
+ let playerContextMock;
15
+ let mockAddEventListener;
16
+ let mockRemoveEventListener;
17
+ beforeEach(() => {
18
+ mockAddEventListener = jest.fn();
19
+ mockRemoveEventListener = jest.fn();
20
+ playerContextMock = createPlayerContextMock({
21
+ npoPlayer: createMockNpoPlayer({
22
+ uiComponents: {
23
+ settingsPanel: {
24
+ hide: jest.fn()
25
+ },
26
+ settingsToggleButton: {
27
+ show: jest.fn(),
28
+ hide: jest.fn()
29
+ }
30
+ },
31
+ player: {
32
+ subtitles: {
33
+ list: jest.fn().mockReturnValue([{ id: 'en', language: 'English', enabled: false }])
34
+ }
35
+ }
36
+ }),
37
+ player: {
38
+ on: mockAddEventListener,
39
+ off: mockRemoveEventListener
40
+ }
41
+ });
42
+ });
43
+ afterEach(() => {
44
+ jest.clearAllMocks();
45
+ });
46
+ it('should register event listeners on the player', () => {
47
+ handleVerticalVideoSettings(playerContextMock);
48
+ expect(mockAddEventListener).toHaveBeenCalledTimes(5);
49
+ expect(mockAddEventListener).toHaveBeenCalledWith(NpoPlayerEvent.Ready, expect.any(Function));
50
+ expect(mockAddEventListener).toHaveBeenCalledWith(NpoPlayerEvent.SourceLoaded, expect.any(Function));
51
+ expect(mockAddEventListener).toHaveBeenCalledWith(NpoPlayerEvent.SourceUnloaded, expect.any(Function));
52
+ expect(mockAddEventListener).toHaveBeenCalledWith(NpoPlayerEvent.SubtitleDisable, expect.any(Function));
53
+ expect(mockAddEventListener).toHaveBeenCalledWith(NpoPlayerEvent.SubtitleEnable, expect.any(Function));
54
+ });
55
+ it('should show the settingsToggleButton if subtitles are available', () => {
56
+ handleVerticalVideoSettings(playerContextMock);
57
+ const checkSubtitles = mockAddEventListener.mock.calls.find(([event]) => event === NpoPlayerEvent.Ready)[1];
58
+ checkSubtitles();
59
+ expect(playerContextMock.npoPlayer.uiComponents.settingsToggleButton?.show).toHaveBeenCalled();
60
+ expect(playerContextMock.npoPlayer.uiComponents.settingsToggleButton?.hide).not.toHaveBeenCalled();
61
+ });
62
+ it('should hide settings elements if no subtitles are available', () => {
63
+ expect(playerContextMock.npoPlayer.player).toBeDefined();
64
+ if (!playerContextMock.npoPlayer.player)
65
+ return;
66
+ playerContextMock.npoPlayer.player.subtitles.list = jest.fn().mockReturnValue([]);
67
+ handleVerticalVideoSettings(playerContextMock);
68
+ const checkSubtitles = mockAddEventListener.mock.calls.find(([event]) => event === NpoPlayerEvent.Ready)[1];
69
+ checkSubtitles();
70
+ expect(playerContextMock.npoPlayer.uiComponents.settingsToggleButton?.hide).toHaveBeenCalled();
71
+ expect(playerContextMock.npoPlayer.uiComponents.settingsPanel?.hide).toHaveBeenCalled();
72
+ });
73
+ it('should hide settingsPanel on SubtitleDisable or SubtitleEnable', () => {
74
+ handleVerticalVideoSettings(playerContextMock);
75
+ const handleSubtitleDisable = mockAddEventListener.mock.calls.find(([event]) => event === NpoPlayerEvent.SubtitleDisable)[1];
76
+ handleSubtitleDisable();
77
+ expect(playerContextMock.npoPlayer.uiComponents.settingsPanel?.hide).toHaveBeenCalled();
78
+ const handleSubtitleEnable = mockAddEventListener.mock.calls.find(([event]) => event === NpoPlayerEvent.SubtitleEnable)[1];
79
+ handleSubtitleEnable();
80
+ expect(playerContextMock.npoPlayer.uiComponents.settingsPanel?.hide).toHaveBeenCalledTimes(2);
81
+ });
82
+ });
@@ -1,4 +1,3 @@
1
1
  export { handleStartOffset, handleLiveOffsetLogic, shiftToProgramStart } from './handlers/handleoffsets';
2
- export { handlePlayerError } from './handlers/error';
3
2
  export { processPlayerConfig } from './handlers/processplayerconfig';
4
3
  export { processSourceConfig } from './handlers/processsourceconfig';
@@ -0,0 +1,6 @@
1
+ import { SourceConfig, StreamObject } from 'types/interfaces';
2
+ export declare function getAnalyticsPrid(params: {
3
+ source: string;
4
+ sourceConfig?: SourceConfig;
5
+ streamObject?: StreamObject;
6
+ }): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -41,9 +41,9 @@ export default class NpoPlayer {
41
41
  variant?: NpoPlayerUIVariants;
42
42
  npoTagPageTracker?: PageTracker | undefined;
43
43
  }, playerConfig?: PlayerConfig | undefined, npoTag?: InitialisationProps | undefined, npoTagInstance?: NPOTag | undefined, variant?: NpoPlayerUIVariants, npoTagPageTracker?: PageTracker | undefined);
44
+ keydownHandler: (e: KeyboardEvent) => void;
44
45
  initPlayer(_container: HTMLElement, playerConfig: PlayerConfig): void;
45
46
  loadStream(source: string, options?: StreamOptions): Promise<void>;
46
- doError(input: any, status?: number): void;
47
47
  play(): Promise<void>;
48
48
  pause(): void;
49
49
  setVolume(volume: number): void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import { PlayerContext } from '../../types/interfaces';
2
+ export declare function handlePlayerError(playerContext: PlayerContext, status: number): Promise<void>;
3
+ export declare function setErrorBackground(playerContext: PlayerContext): void;
@@ -0,0 +1,2 @@
1
+ export declare const customSpecificErrorMessageOverlayConfig: Record<number, string>;
2
+ export declare const npoBusinessErrors: Record<number, string>;
@@ -0,0 +1 @@
1
+ export {};
@@ -3,3 +3,23 @@ export declare const PREVENT_UI_DELAY = -1;
3
3
  export declare const VOLUME_STEP = 10;
4
4
  export declare const VOLUME_MIN = 0;
5
5
  export declare const VOLUME_MAX = 100;
6
+ export declare const emptyStreamObject: {
7
+ stream: {
8
+ drmType: string;
9
+ streamProfile: string;
10
+ streamURL: string;
11
+ avType: string;
12
+ sourceProfile: string;
13
+ };
14
+ metadata: {
15
+ title: string;
16
+ description: string;
17
+ };
18
+ assets: {
19
+ scrubbingThumbnail: string;
20
+ subtitles: never[];
21
+ };
22
+ user: {
23
+ type: "anonymous" | "plus";
24
+ };
25
+ };
@@ -6,6 +6,7 @@ export declare class NpoPlayerAPI {
6
6
  playerAPI: PlayerAPI;
7
7
  constructor(playerAPI: PlayerAPI);
8
8
  load(sourceConfig: SourceConfig): Promise<void>;
9
+ unload(): Promise<void>;
9
10
  play(): Promise<void>;
10
11
  pause(): void;
11
12
  mute(): void;
@@ -27,6 +28,7 @@ export declare class NpoPlayerAPI {
27
28
  off(eventType: NpoPlayerEvent, callback: NpoPlayerEventCallback): void;
28
29
  on(eventType: NpoPlayerEvent, callback: NpoPlayerEventCallback): void;
29
30
  isCastAvailable(): boolean;
31
+ isCasting(): boolean;
30
32
  seek(time: number): void;
31
33
  timeShift(time: number): void;
32
34
  getContainer(): HTMLElement;
@@ -38,7 +40,8 @@ export declare class NpoPlayerAPI {
38
40
  getDuration(): number;
39
41
  getTimeShift(): number;
40
42
  scheduleAds(adConfig: AdConfig): Promise<AdBreak[]>;
43
+ handleErrorRetry(playerContext: PlayerContext): void;
41
44
  getActiveAdBreak(): AdBreak | null;
42
45
  getConfig(mergedConfig?: boolean): PlayerConfig;
43
- createUIManager(playerContext: PlayerContext, variant: NpoPlayerUIVariants): Promise<void | UIManager>;
46
+ createUIManager(playerContext: PlayerContext, variant: NpoPlayerUIVariants): void | UIManager;
44
47
  }
@@ -1,4 +1,4 @@
1
- import { ApiPayload, Fragment, PlayerContext, Profile, Segment, TimeLineMarker, LocalStorageData, LocalStorageValues, NpoPlayerUIVariants } from '../types/interfaces';
1
+ import { ApiPayload, Fragment, PlayerContext, Profile, Segment, TimeLineMarker, LocalStorageData, LocalStorageValues, StreamObject, PlayerTrackerParams, LogEventParams } from '../types/interfaces';
2
2
  import { AVType } from '@npotag/tag/dist/types/src/streamTracker';
3
3
  export declare class NpoPlayerServices {
4
4
  getAVType(avType: string): AVType;
@@ -13,11 +13,17 @@ export declare class NpoPlayerServices {
13
13
  setAccessibilityAttributes(playerContext: PlayerContext): void;
14
14
  schedulePreRolls(playerContext: PlayerContext): Promise<void>;
15
15
  discardAdBreak(playerContext: PlayerContext): void;
16
- handleVerticalVideoControls(playerContext: PlayerContext, variant: NpoPlayerUIVariants): void;
16
+ handleVerticalVideoControls(playerContext: PlayerContext): void;
17
+ handleVerticalVideoSettings(playerContext: PlayerContext): void;
17
18
  showNicamAfterUiDelay(playerContext: PlayerContext | undefined): void;
18
19
  setupNicamKijkwijzerIcons(playerContext: PlayerContext): void;
19
20
  handlePreferences(playerContext: PlayerContext): void;
20
21
  addUivisiblityHandlers(playerContext: PlayerContext): void;
21
22
  removeUivisiblityHandlers(playerContext: PlayerContext): void;
22
23
  handleStreamOptions(playerContext: PlayerContext): void;
24
+ handleError(playerContext: PlayerContext, input: number): Promise<void>;
25
+ fetchStream(playerContext: PlayerContext, payload: ApiPayload): Promise<StreamObject>;
26
+ startPlayerTracker({ playerContext, source, duration }: PlayerTrackerParams): void;
27
+ initPlayerTracker(playerContext: PlayerContext): void;
28
+ logEvent({ playerContext, event, data }: LogEventParams): void;
23
29
  }
@@ -0,0 +1,2 @@
1
+ import { type ApiPayload, PlayerContext, StreamObject } from '../../types/interfaces';
2
+ export declare function fetchStream(playerContext: PlayerContext, payload: ApiPayload): Promise<StreamObject>;
@@ -0,0 +1,2 @@
1
+ import { PlayerContext } from 'types/interfaces';
2
+ export declare function bindPlayerEvents(playerContext: PlayerContext): void;
@@ -0,0 +1,2 @@
1
+ import { LogEventParams } from 'types/interfaces';
2
+ export declare function logEvent({ playerContext, event, data }: LogEventParams): void;
@@ -0,0 +1,3 @@
1
+ export { startPlayerTracker } from './playerTrackerStart';
2
+ export { initPlayerTracker } from './playerTrackerInit';
3
+ export { logEvent } from './eventLogging';
@@ -0,0 +1,2 @@
1
+ import { PlayerContext } from 'types/interfaces';
2
+ export declare function initPlayerTracker(playerContext: PlayerContext): void;
@@ -0,0 +1,2 @@
1
+ import { PlayerTrackerParams } from 'types/interfaces';
2
+ export declare const startPlayerTracker: ({ playerContext, source, duration }: PlayerTrackerParams) => void;
@@ -0,0 +1,3 @@
1
+ import { StreamTracker } from '@npotag/tag';
2
+ import { PlayerTrackerParams } from 'types/interfaces';
3
+ export declare function initStreamTracker({ playerContext, duration, source }: PlayerTrackerParams): StreamTracker;
@@ -1,2 +1,2 @@
1
- import { PlayerContext, NpoPlayerUIVariants } from '../../types/interfaces';
2
- export declare const handleVerticalVideoControls: (playerContext: PlayerContext, variant: NpoPlayerUIVariants) => void;
1
+ import { PlayerContext } from '../../types/interfaces';
2
+ export declare const handleVerticalVideoControls: (playerContext: PlayerContext) => void;
@@ -0,0 +1,2 @@
1
+ import { PlayerContext } from '../../types/interfaces';
2
+ export declare function handleVerticalVideoSettings(playerContext: PlayerContext): void;
@@ -1,4 +1,4 @@
1
- import { type ErrorMessageOverlay, type Label, ControlBar, SettingsPanelItem, Button, SeekBar, CastToggleButton, SettingsPanel } from 'bitmovin-player-ui';
1
+ import { type ErrorMessageOverlay, type Label, ControlBar, SettingsPanelItem, Button, SeekBar, CastToggleButton, SettingsPanel, SettingsToggleButton } from 'bitmovin-player-ui';
2
2
  import { type NPOTag, type PageTracker } from '@npotag/tag';
3
3
  import { ButtonConfig } from 'bitmovin-player-ui/dist/js/framework/components/button';
4
4
  import NpoPlayer from '../npoplayer';
@@ -132,6 +132,8 @@ export interface StreamOptions {
132
132
  customFallbackPoster?: string;
133
133
  autoFillTimeLineMarkerDuration?: boolean;
134
134
  autoplay?: boolean;
135
+ npoTagPageTracker?: PageTracker;
136
+ retryCallback?: () => void;
135
137
  }
136
138
  export interface UIComponents {
137
139
  errorMessageOverlay?: ErrorMessageOverlay;
@@ -151,6 +153,8 @@ export interface UIComponents {
151
153
  seekBar?: SeekBar | undefined;
152
154
  chromeCastButton?: CastToggleButton | undefined;
153
155
  settingsPanels?: SettingsPanel[] | undefined;
156
+ settingsPanel?: SettingsPanel | undefined;
157
+ settingsToggleButton?: SettingsToggleButton | undefined;
154
158
  }
155
159
  export interface CustomMessageHandlerInterface {
156
160
  defaultActionRequired?: boolean;
@@ -222,3 +226,13 @@ export declare enum LocalStorageValues {
222
226
  }
223
227
  export type LocalStorageData = Partial<Record<LocalStorageValues, string | number>>;
224
228
  export type NPOGoogleCastRemoteControlConfig = GoogleCastRemoteControlConfig;
229
+ export interface PlayerTrackerParams {
230
+ playerContext: PlayerContext;
231
+ duration: number | undefined;
232
+ source: string | undefined;
233
+ }
234
+ export interface LogEventParams {
235
+ playerContext: PlayerContext;
236
+ event: string;
237
+ data?: any;
238
+ }
@@ -1,6 +1,7 @@
1
1
  import { Container, PlaybackTimeLabel, SeekBar } from 'bitmovin-player-ui';
2
2
  import type NpoPlayer from '../../npoplayer';
3
- export declare function createSeekBar(npoPlayer: NpoPlayer): Container<{
3
+ import { NpoPlayerUIVariants } from '../../npoplayer';
4
+ export declare function createSeekBar(npoPlayer: NpoPlayer, variant: NpoPlayerUIVariants): Container<{
4
5
  components: (SeekBar | PlaybackTimeLabel)[];
5
6
  cssClasses: string[];
6
7
  }>;
@@ -1,3 +1,3 @@
1
- import { ControlBar } from 'bitmovin-player-ui';
2
- import { PlayerContext } from 'types/interfaces';
3
- export declare function createVerticalVideoControlBar(playerContext: PlayerContext): ControlBar;
1
+ import { ControlBar, SettingsPanel } from 'bitmovin-player-ui';
2
+ import { PlayerContext } from '../../../types/interfaces';
3
+ export declare function createVerticalVideoControlBar(playerContext: PlayerContext, settingsPanel: SettingsPanel): ControlBar;
@@ -0,0 +1,2 @@
1
+ import { SettingsPanel } from 'bitmovin-player-ui';
2
+ export declare function createVerticalVideoSettingsPanel(): SettingsPanel;
@@ -40,7 +40,7 @@ export const mockNpoPlayer = {
40
40
  container: document.createElement('div'),
41
41
  initPlayer: jest.fn(),
42
42
  loadStream: jest.fn(),
43
- doError: jest.fn(),
43
+ keydownHandler: jest.fn(),
44
44
  player: {
45
45
  getCurrentTime: jest.fn().mockReturnValue(10)
46
46
  },
@@ -0,0 +1,2 @@
1
+ import { StreamObject } from '../../src/types/interfaces';
2
+ export declare const mockStreamObject: StreamObject;
@@ -0,0 +1,21 @@
1
+ export const mockStreamObject = {
2
+ stream: {
3
+ isLiveStream: false,
4
+ hasDvrWindow: true,
5
+ avType: '',
6
+ drmType: '',
7
+ streamProfile: '',
8
+ sourceProfile: '',
9
+ streamURL: ''
10
+ },
11
+ metadata: {
12
+ description: '',
13
+ title: ''
14
+ },
15
+ assets: {
16
+ scrubbingThumbnail: '',
17
+ subtitles: undefined,
18
+ preroll: ''
19
+ },
20
+ user: { type: 'anonymous' }
21
+ };
@@ -42,6 +42,7 @@ export declare const createMockNpoPlayer: (overrides?: {}) => {
42
42
  keyboardHandler: jest.Mock<any, any, any>;
43
43
  decideProfile: jest.Mock<any, any, any>;
44
44
  verifyDRM: jest.Mock<any, any, any>;
45
+ handleError: jest.Mock<any, any, any>;
45
46
  };
46
47
  eventListeners: undefined;
47
48
  mockNpoPlayer: undefined;
@@ -7,6 +7,7 @@ const setVolume = jest.fn((level) => {
7
7
  export const createMockNpoPlayerAPI = (overrides = {}) => ({
8
8
  playerAPI: mockPlayerAPI,
9
9
  load: jest.fn(),
10
+ unload: jest.fn(),
10
11
  play: jest.fn(),
11
12
  pause: jest.fn(),
12
13
  mute: jest.fn(),
@@ -34,6 +35,7 @@ export const createMockNpoPlayerAPI = (overrides = {}) => ({
34
35
  off: jest.fn(),
35
36
  on: jest.fn(),
36
37
  isCastAvailable: jest.fn(),
38
+ isCasting: jest.fn().mockReturnValue(false),
37
39
  seek: jest.fn(),
38
40
  timeShift: jest.fn(),
39
41
  getContainer: jest.fn(),
@@ -48,6 +50,7 @@ export const createMockNpoPlayerAPI = (overrides = {}) => ({
48
50
  getActiveAdBreak: jest.fn().mockReturnValue(undefined),
49
51
  getConfig: jest.fn().mockReturnValue({}),
50
52
  createUIManager: jest.fn(),
53
+ handleErrorRetry: jest.fn(),
51
54
  ...overrides
52
55
  });
53
56
  export const createMockNpoPlayer = (overrides = {}) => ({
@@ -88,7 +91,8 @@ export const createMockNpoPlayer = (overrides = {}) => ({
88
91
  setAccessibilityAttributes: jest.fn(),
89
92
  keyboardHandler: jest.fn(),
90
93
  decideProfile: jest.fn(),
91
- verifyDRM: jest.fn()
94
+ verifyDRM: jest.fn(),
95
+ handleError: jest.fn()
92
96
  },
93
97
  eventListeners: undefined,
94
98
  mockNpoPlayer: undefined,
@@ -1,4 +1,4 @@
1
- import { type ErrorMessageOverlay, type Label, ControlBar, SettingsPanelItem, Button, SeekBar, CastToggleButton, SettingsPanel } from 'bitmovin-player-ui';
1
+ import { type ErrorMessageOverlay, type Label, ControlBar, SettingsPanelItem, Button, SeekBar, CastToggleButton, SettingsPanel, SettingsToggleButton } from 'bitmovin-player-ui';
2
2
  import { type NPOTag, type PageTracker } from '@npotag/tag';
3
3
  import { ButtonConfig } from 'bitmovin-player-ui/dist/js/framework/components/button';
4
4
  import NpoPlayer from '../npoplayer';
@@ -132,6 +132,8 @@ export interface StreamOptions {
132
132
  customFallbackPoster?: string;
133
133
  autoFillTimeLineMarkerDuration?: boolean;
134
134
  autoplay?: boolean;
135
+ npoTagPageTracker?: PageTracker;
136
+ retryCallback?: () => void;
135
137
  }
136
138
  export interface UIComponents {
137
139
  errorMessageOverlay?: ErrorMessageOverlay;
@@ -151,6 +153,8 @@ export interface UIComponents {
151
153
  seekBar?: SeekBar | undefined;
152
154
  chromeCastButton?: CastToggleButton | undefined;
153
155
  settingsPanels?: SettingsPanel[] | undefined;
156
+ settingsPanel?: SettingsPanel | undefined;
157
+ settingsToggleButton?: SettingsToggleButton | undefined;
154
158
  }
155
159
  export interface CustomMessageHandlerInterface {
156
160
  defaultActionRequired?: boolean;
@@ -222,3 +226,13 @@ export declare enum LocalStorageValues {
222
226
  }
223
227
  export type LocalStorageData = Partial<Record<LocalStorageValues, string | number>>;
224
228
  export type NPOGoogleCastRemoteControlConfig = GoogleCastRemoteControlConfig;
229
+ export interface PlayerTrackerParams {
230
+ playerContext: PlayerContext;
231
+ duration: number | undefined;
232
+ source: string | undefined;
233
+ }
234
+ export interface LogEventParams {
235
+ playerContext: PlayerContext;
236
+ event: string;
237
+ data?: any;
238
+ }
@@ -1,11 +1,12 @@
1
1
  import { ControlBar, Container, SeekBar, SeekBarLabel, VolumeControlButton } from 'bitmovin-player-ui';
2
2
  import { createSeekBar } from '../seekbar';
3
+ import { NpoPlayerUIVariants } from '../../../npoplayer';
3
4
  export function createAudioControlBar(npoPlayer) {
4
5
  const seekBar = new SeekBar({ label: new SeekBarLabel() });
5
6
  npoPlayer.uiComponents.seekBar = seekBar;
6
7
  const controlBar = new ControlBar({
7
8
  components: [
8
- createSeekBar(npoPlayer),
9
+ createSeekBar(npoPlayer, NpoPlayerUIVariants.AUDIO),
9
10
  new Container({
10
11
  components: [
11
12
  new VolumeControlButton({