@npo/player 1.25.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.
- package/README.md +1 -1
- package/lib/js/playeractions/handlers/handleoffsets.js +9 -7
- package/lib/js/playeractions/handlers/handleoffsets.test.js +1 -1
- package/lib/js/playeractions/handlers/mediasessionactions.js +2 -2
- package/lib/js/playeractions/handlers/processplayerconfig.d.ts +1 -1
- package/lib/js/playeractions/handlers/processplayerconfig.js +4 -4
- package/lib/js/playeractions/handlers/processsourceconfig.d.ts +1 -0
- package/lib/js/playeractions/handlers/processsourceconfig.js +4 -5
- package/lib/js/playeractions/handlers/processsourceconfig.test.js +25 -0
- package/lib/js/playeractions/playeractions.d.ts +0 -1
- package/lib/js/playeractions/playeractions.js +0 -1
- package/lib/js/utilities/utilities.prid.d.ts +6 -0
- package/lib/js/utilities/utilities.prid.js +8 -0
- package/lib/js/utilities/utilities.prid.test.js +46 -0
- package/lib/lang/nl.json +1 -1
- package/lib/lang/subtitleLabels/nl.json +14 -0
- package/lib/npoplayer.d.ts +3 -4
- package/lib/npoplayer.js +66 -83
- package/lib/npoplayer.test.js +3 -3
- package/lib/package.json +2 -2
- package/lib/services/a11y/setup.js +2 -5
- package/lib/services/a11y/setup.test.js +2 -20
- package/lib/services/advertHandlers/discardAdBreak.js +6 -4
- package/lib/services/advertHandlers/discardAdBreak.test.js +31 -14
- package/lib/services/advertHandlers/handlePreRolls.js +19 -21
- package/lib/services/advertHandlers/handlePrerolls.test.js +66 -5
- package/lib/services/drmHandlers/decideprofile.js +8 -2
- package/lib/services/drmHandlers/decideprofile.test.js +5 -1
- package/lib/services/drmHandlers/verifydrm.js +7 -8
- package/lib/services/drmHandlers/verifydrm.test.js +32 -9
- package/lib/services/errors/errorBackground.test.js +48 -0
- package/lib/services/errors/errorHandler.d.ts +3 -0
- package/lib/services/errors/errorHandler.js +45 -0
- package/lib/services/errors/errorText.d.ts +2 -0
- package/lib/services/errors/errorText.js +59 -0
- package/lib/services/errors/errorText.test.js +66 -0
- package/lib/services/eventListenerHandlers/removeEventListeners.js +2 -2
- package/lib/services/eventListenerHandlers/removeEventListeners.test.js +9 -9
- package/lib/services/keyboardHandlers/resolvekeypress.js +21 -17
- package/lib/services/keyboardHandlers/resolvekeypress.test.js +1 -1
- package/lib/services/liveStreamHandlers/handleLiveStreamControls.js +2 -2
- package/lib/services/liveStreamHandlers/handleLiveStreamControls.test.js +2 -2
- package/lib/services/localStorageHandlers/localStorageHandlers.js +6 -3
- package/lib/services/localStorageHandlers/localStorageHandlers.test.js +2 -6
- package/lib/services/nicamHandlers/nicamhandler.d.ts +1 -2
- package/lib/services/nicamHandlers/nicamhandler.js +15 -18
- package/lib/services/nicamHandlers/nicamhandler.test.js +67 -9
- package/lib/services/npoPlayerAPI/contants.d.ts +20 -0
- package/lib/services/npoPlayerAPI/contants.js +6 -0
- package/lib/services/npoPlayerAPI/npoPlayerAPI.d.ts +6 -3
- package/lib/services/npoPlayerAPI/npoPlayerAPI.js +43 -26
- package/lib/services/npoPlayerAPI/npoPlayerAPI.test.js +11 -0
- package/lib/services/preferences/handlePreferences.d.ts +2 -0
- package/lib/services/preferences/handlePreferences.js +42 -0
- package/lib/services/preferences/handlePreferences.test.js +102 -0
- package/lib/services/segmentHandlers/addSegmentEventListeners.js +2 -2
- package/lib/services/segmentHandlers/addSegmentEventListeners.test.js +1 -1
- package/lib/services/services.d.ts +14 -4
- package/lib/services/services.js +49 -4
- package/lib/services/streamFetchHandler/fetchStream.d.ts +2 -0
- package/lib/services/streamFetchHandler/fetchStream.js +48 -0
- package/lib/services/streamFetchHandler/fetchstream.test.js +70 -0
- package/lib/services/streamoptionsHandlers/{steamOptionsHandler.js → streamOptionsHandler.js} +11 -11
- package/lib/services/streamoptionsHandlers/streamOptionsHandler.test.js +20 -20
- package/lib/services/trackingHandlers/eventBinding.d.ts +2 -0
- package/lib/{js/tracking/handlers/eventbinding.js → services/trackingHandlers/eventBinding.js} +16 -14
- package/lib/services/trackingHandlers/eventBinding.test.js +89 -0
- package/lib/services/trackingHandlers/eventLogging.d.ts +2 -0
- package/lib/{js/tracking/handlers/eventlogging.js → services/trackingHandlers/eventLogging.js} +18 -7
- package/lib/services/trackingHandlers/eventLogging.test.js +63 -0
- package/lib/services/trackingHandlers/index.d.ts +3 -0
- package/lib/services/trackingHandlers/index.js +3 -0
- package/lib/services/trackingHandlers/playerTrackerInit.d.ts +2 -0
- package/lib/{js/tracking/handlers/playertrackerinit.js → services/trackingHandlers/playerTrackerInit.js} +6 -3
- package/lib/services/trackingHandlers/playerTrackerInit.test.js +75 -0
- package/lib/services/trackingHandlers/playerTrackerStart.d.ts +2 -0
- package/lib/services/trackingHandlers/playerTrackerStart.js +25 -0
- package/lib/services/trackingHandlers/playerTrackerStart.test.js +59 -0
- package/lib/services/trackingHandlers/streamTrackerInit.d.ts +3 -0
- package/lib/services/trackingHandlers/streamTrackerInit.js +27 -0
- package/lib/services/trackingHandlers/streamTrackerInit.test.js +84 -0
- package/lib/services/uiHandlers/uiVisiblityHandler.d.ts +3 -0
- package/lib/services/uiHandlers/uiVisiblityHandler.js +26 -0
- package/lib/services/uiHandlers/uiVisiblityHandler.test.js +62 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.d.ts +2 -2
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.js +4 -6
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.test.js +4 -17
- package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.d.ts +2 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.js +26 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.test.d.ts +1 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.test.js +82 -0
- package/lib/src/js/playeractions/handlers/processplayerconfig.d.ts +1 -1
- package/lib/src/js/playeractions/handlers/processsourceconfig.d.ts +1 -0
- package/lib/src/js/playeractions/handlers/processsourceconfig.test.d.ts +1 -0
- package/lib/src/js/playeractions/playeractions.d.ts +0 -1
- package/lib/src/js/utilities/utilities.prid.d.ts +6 -0
- package/lib/src/js/utilities/utilities.prid.test.d.ts +1 -0
- package/lib/src/npoplayer.d.ts +3 -4
- package/lib/src/services/errors/errorBackground.test.d.ts +1 -0
- package/lib/src/services/errors/errorHandler.d.ts +3 -0
- package/lib/src/services/errors/errorText.d.ts +2 -0
- package/lib/src/services/errors/errorText.test.d.ts +1 -0
- package/lib/src/services/nicamHandlers/nicamhandler.d.ts +1 -2
- package/lib/src/services/npoPlayerAPI/contants.d.ts +20 -0
- package/lib/src/services/npoPlayerAPI/npoPlayerAPI.d.ts +6 -3
- package/lib/src/services/preferences/handlePreferences.d.ts +2 -0
- package/lib/src/services/preferences/handlePreferences.test.d.ts +1 -0
- package/lib/src/services/services.d.ts +14 -4
- package/lib/src/services/streamFetchHandler/fetchStream.d.ts +2 -0
- package/lib/src/services/streamFetchHandler/fetchstream.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/eventBinding.d.ts +2 -0
- package/lib/src/services/trackingHandlers/eventBinding.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/eventLogging.d.ts +2 -0
- package/lib/src/services/trackingHandlers/eventLogging.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/index.d.ts +3 -0
- package/lib/src/services/trackingHandlers/playerTrackerInit.d.ts +2 -0
- package/lib/src/services/trackingHandlers/playerTrackerInit.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/playerTrackerStart.d.ts +2 -0
- package/lib/src/services/trackingHandlers/playerTrackerStart.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/streamTrackerInit.d.ts +3 -0
- package/lib/src/services/trackingHandlers/streamTrackerInit.test.d.ts +1 -0
- package/lib/src/services/uiHandlers/uiVisiblityHandler.d.ts +3 -0
- package/lib/src/services/uiHandlers/uiVisiblityHandler.test.d.ts +1 -0
- package/lib/src/services/verticalVideoHandlers/handleVerticalVideoControls.d.ts +2 -2
- package/lib/src/services/verticalVideoHandlers/handleVerticalVideoSettings.d.ts +2 -0
- package/lib/src/services/verticalVideoHandlers/handleVerticalVideoSettings.test.d.ts +1 -0
- package/lib/src/types/classes.d.ts +6 -0
- package/lib/src/types/interfaces.d.ts +39 -4
- package/lib/src/ui/components/adbutton.d.ts +1 -1
- package/lib/src/ui/components/adlabel.d.ts +1 -1
- package/lib/src/ui/components/buttons.d.ts +6 -16
- package/lib/src/ui/components/controlbar.d.ts +2 -2
- package/lib/src/ui/components/ctabar.d.ts +1 -1
- package/lib/src/ui/components/playnext.d.ts +1 -4
- package/lib/src/ui/components/seekbar.d.ts +2 -1
- package/lib/src/ui/components/titlebar.d.ts +1 -1
- package/lib/src/ui/components/verticalvideo/controlbar.d.ts +3 -3
- package/lib/src/ui/components/verticalvideo/settingspanel.d.ts +2 -0
- package/lib/src/ui/handlers/playnextscreen.test.d.ts +1 -0
- package/lib/src/ui/uicontainer.test.d.ts +1 -0
- package/lib/tests/mocks/mockLogEmitter.d.ts +2 -0
- package/lib/tests/mocks/mockLogEmitter.js +20 -0
- package/lib/tests/mocks/mockNpoplayer.js +2 -3
- package/lib/tests/mocks/mockStreamObject.d.ts +2 -0
- package/lib/tests/mocks/mockStreamObject.js +21 -0
- package/lib/tests/mocks/playerContextMock.d.ts +6 -3
- package/lib/tests/mocks/playerContextMock.js +12 -6
- package/lib/types/classes.d.ts +6 -0
- package/lib/types/classes.js +12 -0
- package/lib/types/interfaces.d.ts +39 -4
- package/lib/types/interfaces.js +1 -0
- package/lib/ui/components/adbutton.d.ts +1 -1
- package/lib/ui/components/adbutton.js +3 -3
- package/lib/ui/components/adlabel.d.ts +1 -1
- package/lib/ui/components/adlabel.js +3 -3
- package/lib/ui/components/audio/controlbar.js +2 -1
- package/lib/ui/components/buttons.d.ts +6 -16
- package/lib/ui/components/buttons.js +27 -10
- package/lib/ui/components/controlbar.d.ts +2 -2
- package/lib/ui/components/controlbar.js +21 -38
- package/lib/ui/components/ctabar.d.ts +1 -1
- package/lib/ui/components/ctabar.js +4 -4
- package/lib/ui/components/nativemobile/topbar.js +2 -2
- package/lib/ui/components/playnext.d.ts +1 -4
- package/lib/ui/components/playnext.js +3 -3
- package/lib/ui/components/seekbar.d.ts +2 -1
- package/lib/ui/components/seekbar.js +5 -3
- package/lib/ui/components/settingspanel.js +7 -9
- package/lib/ui/components/titlebar.d.ts +1 -1
- package/lib/ui/components/titlebar.js +2 -2
- package/lib/ui/components/topbar.js +6 -20
- package/lib/ui/components/verticalvideo/controlbar.d.ts +3 -3
- package/lib/ui/components/verticalvideo/controlbar.js +15 -12
- package/lib/ui/components/verticalvideo/settingspanel.d.ts +2 -0
- package/lib/ui/components/verticalvideo/settingspanel.js +21 -0
- package/lib/ui/handlers/domhandlers.test.js +6 -26
- package/lib/ui/handlers/playnextscreen.test.d.ts +1 -0
- package/lib/ui/nativemobileuifactory.js +2 -2
- package/lib/ui/nativemobileuifactory.test.js +2 -1
- package/lib/ui/uicontainer.js +14 -30
- package/lib/ui/uicontainer.test.d.ts +1 -0
- package/lib/ui/uicontainer.test.js +83 -0
- package/package.json +2 -2
- package/src/style/components/_advert.scss +3 -12
- package/src/style/components/_buffering.scss +14 -8
- package/src/style/components/_error.scss +44 -1
- package/src/style/components/_hugeplaybacktogglebutton.scss +1 -0
- package/src/style/components/_metadata.scss +13 -12
- package/src/style/components/_nicam.scss +16 -10
- package/src/style/components/_playnext.scss +1 -1
- package/src/style/components/_replay.scss +1 -6
- package/src/style/components/_settingspanel.scss +121 -95
- package/src/style/components/audio/_errors.scss +1 -1
- package/src/style/components/audio/_metadata.scss +14 -8
- package/src/style/components/audio/_playbutton.scss +1 -0
- package/src/style/components/audio/_topbar.scss +10 -2
- package/src/style/components/audio/_volumeslider.scss +3 -3
- package/src/style/components/vertical-video/_bottombar.scss +42 -1
- package/src/style/components/vertical-video/_hugeplaybacktogglebutton.scss +24 -4
- package/src/style/components/vertical-video/_settingspanel.scss +21 -4
- package/src/style/components/vertical-video/_topbar.scss +47 -6
- package/src/style/npoplayer.css +108 -70
- package/src/style/npoplayer.scss +4 -7
- package/src/style/variants/_player-base.scss +14 -2
- package/src/style/variants/_player-large.scss +5 -1
- package/src/style/variants/_player-small.scss +26 -9
- package/src/style/vars/_fonts.scss +13 -7
- package/src/style/vars/_z-index.scss +1 -0
- package/lib/js/api/getstreamobject.d.ts +0 -3
- package/lib/js/api/getstreamobject.js +0 -38
- package/lib/js/api/getstreamobject.test.js +0 -48
- package/lib/js/playeractions/customerrors.test.js +0 -51
- package/lib/js/playeractions/handlers/customerrors.d.ts +0 -50
- package/lib/js/playeractions/handlers/customerrors.js +0 -56
- package/lib/js/playeractions/handlers/error.d.ts +0 -3
- package/lib/js/playeractions/handlers/error.js +0 -14
- package/lib/js/playeractions/handlers/error.test.js +0 -44
- package/lib/js/tracking/handlers/eventbinding.d.ts +0 -3
- package/lib/js/tracking/handlers/eventlogging.d.ts +0 -2
- package/lib/js/tracking/handlers/eventlogging.test.js +0 -46
- package/lib/js/tracking/handlers/playertrackerinit.d.ts +0 -4
- package/lib/js/tracking/handlers/playertrackerinit.test.js +0 -74
- package/lib/js/tracking/handlers/playertrackerstart.d.ts +0 -1
- package/lib/js/tracking/handlers/playertrackerstart.js +0 -25
- package/lib/js/tracking/playertracker.d.ts +0 -4
- package/lib/js/tracking/playertracker.js +0 -4
- package/lib/src/js/api/getstreamobject.d.ts +0 -3
- package/lib/src/js/playeractions/handlers/customerrors.d.ts +0 -50
- package/lib/src/js/playeractions/handlers/error.d.ts +0 -3
- package/lib/src/js/tracking/handlers/eventbinding.d.ts +0 -3
- package/lib/src/js/tracking/handlers/eventlogging.d.ts +0 -2
- package/lib/src/js/tracking/handlers/playertrackerinit.d.ts +0 -4
- package/lib/src/js/tracking/handlers/playertrackerstart.d.ts +0 -1
- package/lib/src/js/tracking/playertracker.d.ts +0 -4
- /package/lib/js/{api/getstreamobject.test.d.ts → playeractions/handlers/processsourceconfig.test.d.ts} +0 -0
- /package/lib/js/{playeractions/customerrors.test.d.ts → utilities/utilities.prid.test.d.ts} +0 -0
- /package/lib/{js/playeractions/handlers/error.test.d.ts → services/errors/errorBackground.test.d.ts} +0 -0
- /package/lib/{js/tracking/handlers/eventlogging.test.d.ts → services/errors/errorText.test.d.ts} +0 -0
- /package/lib/{js/tracking/handlers/playertrackerinit.test.d.ts → services/preferences/handlePreferences.test.d.ts} +0 -0
- /package/lib/{src/js/api/getstreamobject.test.d.ts → services/streamFetchHandler/fetchstream.test.d.ts} +0 -0
- /package/lib/services/streamoptionsHandlers/{steamOptionsHandler.d.ts → streamOptionsHandler.d.ts} +0 -0
- /package/lib/{src/js/playeractions/customerrors.test.d.ts → services/trackingHandlers/eventBinding.test.d.ts} +0 -0
- /package/lib/{src/js/playeractions/handlers/error.test.d.ts → services/trackingHandlers/eventLogging.test.d.ts} +0 -0
- /package/lib/{src/js/tracking/handlers/eventlogging.test.d.ts → services/trackingHandlers/playerTrackerInit.test.d.ts} +0 -0
- /package/lib/{src/js/tracking/handlers/playertrackerinit.test.d.ts → services/trackingHandlers/playerTrackerStart.test.d.ts} +0 -0
- /package/lib/{src/ui/handlers/playnextstreen.test.d.ts → services/trackingHandlers/streamTrackerInit.test.d.ts} +0 -0
- /package/lib/{ui/handlers/playnextstreen.test.d.ts → services/uiHandlers/uiVisiblityHandler.test.d.ts} +0 -0
- /package/lib/src/services/streamoptionsHandlers/{steamOptionsHandler.d.ts → streamOptionsHandler.d.ts} +0 -0
- /package/lib/ui/handlers/{playnextstreen.test.js → playnextscreen.test.js} +0 -0
|
@@ -31,20 +31,16 @@ describe('setupAccessibilityAttributes', () => {
|
|
|
31
31
|
};
|
|
32
32
|
playerContext = {
|
|
33
33
|
player: mockPlayerAPI,
|
|
34
|
-
|
|
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: {},
|
|
45
42
|
initPlayer: () => { },
|
|
46
43
|
loadStream: () => Promise.resolve(),
|
|
47
|
-
doError: () => { },
|
|
48
44
|
play: async () => { },
|
|
49
45
|
pause: () => { },
|
|
50
46
|
setVolume: () => { },
|
|
@@ -69,20 +65,6 @@ describe('setupAccessibilityAttributes', () => {
|
|
|
69
65
|
afterEach(() => {
|
|
70
66
|
jest.clearAllMocks();
|
|
71
67
|
});
|
|
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
68
|
it('should set up event listeners for specified events', () => {
|
|
87
69
|
setupAccessibilityAttributes(playerContext);
|
|
88
70
|
expect(mockAddEventListener).toHaveBeenCalledTimes(3);
|
|
@@ -103,6 +85,6 @@ describe('setupAccessibilityAttributes', () => {
|
|
|
103
85
|
setupAccessibilityAttributes(playerContext);
|
|
104
86
|
const triggerFunction = mockAddEventListener.mock.calls[0][1];
|
|
105
87
|
triggerFunction();
|
|
106
|
-
expect(addAccessibilityAttributes).toHaveBeenCalledWith(playerContext.
|
|
88
|
+
expect(addAccessibilityAttributes).toHaveBeenCalledWith(playerContext.npoPlayer.container, playerContext.npoPlayer.streamObject.metadata);
|
|
107
89
|
});
|
|
108
90
|
});
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { NpoPlayerUIVariants } from '../../types/interfaces';
|
|
1
2
|
export function discardAdBreak(playerContext) {
|
|
2
|
-
const {
|
|
3
|
-
const { adBreakActive } =
|
|
3
|
+
const { npoPlayer, player } = playerContext;
|
|
4
|
+
const { adBreakActive } = npoPlayer;
|
|
4
5
|
if (!player || adBreakActive === false)
|
|
5
6
|
return;
|
|
7
|
+
void playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.DEFAULT);
|
|
6
8
|
const activeAdBreak = player.getActiveAdBreak();
|
|
7
9
|
if (activeAdBreak?.id) {
|
|
8
|
-
player.discardAdBreak(activeAdBreak.id);
|
|
10
|
+
player.playerAPI.ads.discardAdBreak(activeAdBreak.id);
|
|
9
11
|
}
|
|
10
|
-
|
|
12
|
+
npoPlayer.adBreakActive = false;
|
|
11
13
|
}
|
|
@@ -1,60 +1,77 @@
|
|
|
1
1
|
import createPlayerContextMock, { createMockNpoPlayer, createMockNpoPlayerAPI } from '../../../tests/mocks/playerContextMock';
|
|
2
|
+
import { NpoPlayerUIVariants } from '../../types/interfaces';
|
|
2
3
|
import { discardAdBreak } from './discardAdBreak';
|
|
3
4
|
describe('discardAdBreak', () => {
|
|
4
5
|
let mockNpoPlayerAPI;
|
|
5
|
-
let
|
|
6
|
+
let npoPlayerMock;
|
|
6
7
|
const activeAdBreakMock = { id: 'ad-break-id' };
|
|
7
8
|
afterEach(() => {
|
|
8
9
|
jest.resetAllMocks();
|
|
9
10
|
});
|
|
11
|
+
it('should not discard ad break if player is undefined', () => {
|
|
12
|
+
npoPlayerMock = createMockNpoPlayer({
|
|
13
|
+
adBreakActive: true
|
|
14
|
+
});
|
|
15
|
+
const playerContextMock = createPlayerContextMock({
|
|
16
|
+
player: undefined,
|
|
17
|
+
npoPlayer: npoPlayerMock
|
|
18
|
+
});
|
|
19
|
+
discardAdBreak(playerContextMock);
|
|
20
|
+
expect(npoPlayerMock.adBreakActive).toBe(true);
|
|
21
|
+
});
|
|
10
22
|
it('should not discard ad break if adBreakActive is false', () => {
|
|
11
23
|
mockNpoPlayerAPI = createMockNpoPlayerAPI({
|
|
12
|
-
getActiveAdBreak: jest.fn().mockReturnValue(
|
|
24
|
+
getActiveAdBreak: jest.fn().mockReturnValue(activeAdBreakMock),
|
|
13
25
|
discardAdBreak: jest.fn()
|
|
14
26
|
});
|
|
15
|
-
|
|
27
|
+
npoPlayerMock = createMockNpoPlayer({
|
|
16
28
|
adBreakActive: false
|
|
17
29
|
});
|
|
18
30
|
const playerContextMock = createPlayerContextMock({
|
|
19
31
|
player: mockNpoPlayerAPI,
|
|
20
|
-
|
|
32
|
+
npoPlayer: npoPlayerMock
|
|
21
33
|
});
|
|
22
34
|
discardAdBreak(playerContextMock);
|
|
23
35
|
expect(mockNpoPlayerAPI.getActiveAdBreak).not.toHaveBeenCalled();
|
|
24
|
-
expect(mockNpoPlayerAPI.discardAdBreak).not.toHaveBeenCalled();
|
|
36
|
+
expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).not.toHaveBeenCalled();
|
|
37
|
+
expect(npoPlayerMock.adBreakActive).toBe(false);
|
|
38
|
+
expect(playerContextMock.player.createUIManager).not.toHaveBeenCalled();
|
|
25
39
|
});
|
|
26
40
|
it('should discard active ad break if adBreakActive is true and ad break exists', () => {
|
|
27
41
|
mockNpoPlayerAPI = createMockNpoPlayerAPI({
|
|
28
42
|
getActiveAdBreak: jest.fn().mockReturnValue(activeAdBreakMock),
|
|
29
|
-
discardAdBreak: jest.fn()
|
|
43
|
+
discardAdBreak: jest.fn(),
|
|
44
|
+
variant: NpoPlayerUIVariants.AD
|
|
30
45
|
});
|
|
31
|
-
|
|
46
|
+
npoPlayerMock = createMockNpoPlayer({
|
|
32
47
|
adBreakActive: true
|
|
33
48
|
});
|
|
34
49
|
const playerContextMock = createPlayerContextMock({
|
|
35
50
|
player: mockNpoPlayerAPI,
|
|
36
|
-
|
|
51
|
+
npoPlayer: npoPlayerMock
|
|
37
52
|
});
|
|
38
53
|
discardAdBreak(playerContextMock);
|
|
39
54
|
expect(mockNpoPlayerAPI.getActiveAdBreak).toHaveBeenCalled();
|
|
40
|
-
expect(mockNpoPlayerAPI.discardAdBreak).toHaveBeenCalledWith(activeAdBreakMock.id);
|
|
41
|
-
expect(
|
|
55
|
+
expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).toHaveBeenCalledWith(activeAdBreakMock.id);
|
|
56
|
+
expect(npoPlayerMock.adBreakActive).toBe(false);
|
|
57
|
+
expect(playerContextMock.player.createUIManager).toHaveBeenCalledWith(playerContextMock, NpoPlayerUIVariants.DEFAULT);
|
|
42
58
|
});
|
|
43
59
|
it('should not discard ad break if active ad break does not exist', () => {
|
|
44
60
|
mockNpoPlayerAPI = createMockNpoPlayerAPI({
|
|
45
61
|
getActiveAdBreak: jest.fn().mockReturnValue(undefined),
|
|
46
62
|
discardAdBreak: jest.fn()
|
|
47
63
|
});
|
|
48
|
-
|
|
64
|
+
npoPlayerMock = createMockNpoPlayer({
|
|
49
65
|
adBreakActive: true
|
|
50
66
|
});
|
|
51
67
|
const playerContextMock = createPlayerContextMock({
|
|
52
68
|
player: mockNpoPlayerAPI,
|
|
53
|
-
|
|
69
|
+
npoPlayer: npoPlayerMock
|
|
54
70
|
});
|
|
55
71
|
discardAdBreak(playerContextMock);
|
|
56
72
|
expect(mockNpoPlayerAPI.getActiveAdBreak).toHaveBeenCalled();
|
|
57
|
-
expect(mockNpoPlayerAPI.discardAdBreak).not.toHaveBeenCalled();
|
|
58
|
-
expect(
|
|
73
|
+
expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).not.toHaveBeenCalled();
|
|
74
|
+
expect(npoPlayerMock.adBreakActive).toBe(false);
|
|
75
|
+
expect(playerContextMock.player.createUIManager).toHaveBeenCalledWith(playerContextMock, NpoPlayerUIVariants.DEFAULT);
|
|
59
76
|
});
|
|
60
77
|
});
|
|
@@ -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.
|
|
7
|
-
playerContext.
|
|
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.
|
|
11
|
+
const prerollUrl = playerContext.npoPlayer.streamObject.assets.preroll;
|
|
12
12
|
let adIndex = 0;
|
|
13
13
|
let totalAds = 0;
|
|
14
14
|
let currentClickListener;
|
|
@@ -26,7 +26,7 @@ export async function handlePreRolls(playerContext) {
|
|
|
26
26
|
await playerContext.player.scheduleAds(advertConfig);
|
|
27
27
|
}
|
|
28
28
|
playerContext.player.on(NpoPlayerEvent.Ready, handleReady);
|
|
29
|
-
|
|
29
|
+
function handlePlay() {
|
|
30
30
|
playerContext.player.off(NpoPlayerEvent.Play, handlePlay);
|
|
31
31
|
attemptSetAdUi();
|
|
32
32
|
}
|
|
@@ -35,13 +35,11 @@ export async function handlePreRolls(playerContext) {
|
|
|
35
35
|
const activeAdBreak = playerContext.player.getActiveAdBreak();
|
|
36
36
|
if (!activeAdBreak || !activeAdBreak.ads)
|
|
37
37
|
return false;
|
|
38
|
-
playerContext.
|
|
39
|
-
playerContext.
|
|
40
|
-
|
|
41
|
-
playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.AD);
|
|
42
|
-
}
|
|
38
|
+
playerContext.npoPlayer.uiManager?.release();
|
|
39
|
+
playerContext.npoPlayer.uiManager = undefined;
|
|
40
|
+
void playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.AD);
|
|
43
41
|
adUiSet = true;
|
|
44
|
-
const adButton = playerContext.
|
|
42
|
+
const adButton = playerContext.npoPlayer.uiComponents.adbutton;
|
|
45
43
|
const currentAd = activeAdBreak.ads[0];
|
|
46
44
|
adIndex = 1;
|
|
47
45
|
totalAds = activeAdBreak.ads.length;
|
|
@@ -49,7 +47,7 @@ export async function handlePreRolls(playerContext) {
|
|
|
49
47
|
adButton.show();
|
|
50
48
|
adClickHandler(currentAd, adButton);
|
|
51
49
|
}
|
|
52
|
-
playerContext.
|
|
50
|
+
playerContext.npoPlayer.uiComponents.adlabel?.setText(`Advertentie 1 van ${activeAdBreak.ads.length}`);
|
|
53
51
|
return true;
|
|
54
52
|
}
|
|
55
53
|
function attemptSetAdUi(attemptsLeft = 10) {
|
|
@@ -71,7 +69,7 @@ export async function handlePreRolls(playerContext) {
|
|
|
71
69
|
}
|
|
72
70
|
if (!adUiSet)
|
|
73
71
|
attemptSetAdUi();
|
|
74
|
-
playerContext.
|
|
72
|
+
playerContext.npoPlayer.adBreakActive = true;
|
|
75
73
|
}
|
|
76
74
|
playerContext.player.on(NpoPlayerEvent.AdStarted, handleAdStarted);
|
|
77
75
|
function adClickHandler(ad, button) {
|
|
@@ -102,26 +100,26 @@ export async function handlePreRolls(playerContext) {
|
|
|
102
100
|
handleAdBreakFinished();
|
|
103
101
|
return;
|
|
104
102
|
}
|
|
105
|
-
const adButton = playerContext.
|
|
103
|
+
const adButton = playerContext.npoPlayer.uiComponents.adbutton;
|
|
106
104
|
const nextAd = activeAdBreak.ads[adIndex];
|
|
107
105
|
adIndex += 1;
|
|
108
106
|
if (adButton) {
|
|
109
107
|
adButton.show();
|
|
110
108
|
adClickHandler(nextAd, adButton);
|
|
111
109
|
}
|
|
112
|
-
playerContext.
|
|
110
|
+
playerContext.npoPlayer.uiComponents.adlabel?.setText(`Advertentie ${adIndex} van ${activeAdBreak.ads.length}`);
|
|
113
111
|
}
|
|
114
112
|
playerContext.player.on(NpoPlayerEvent.AdFinished, handleAdFinished);
|
|
115
113
|
function handleAdBreakFinished() {
|
|
116
114
|
playerContext.player.off(NpoPlayerEvent.AdBreakFinished, handleAdBreakFinished);
|
|
117
115
|
playerContext.player.off(NpoPlayerEvent.AdError, handleAdBreakFinished);
|
|
118
|
-
playerContext.
|
|
119
|
-
playerContext.
|
|
120
|
-
playerContext.
|
|
121
|
-
playerContext.
|
|
122
|
-
playerContext.
|
|
123
|
-
if (playerContext.
|
|
124
|
-
playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.DEFAULT);
|
|
116
|
+
playerContext.npoPlayer.adBreakActive = false;
|
|
117
|
+
playerContext.npoPlayer.uiComponents.adbutton?.hide();
|
|
118
|
+
playerContext.npoPlayer.uiComponents.adlabel?.hide();
|
|
119
|
+
playerContext.npoPlayer.uiManager?.release();
|
|
120
|
+
playerContext.npoPlayer.uiManager = undefined;
|
|
121
|
+
if (playerContext.npoPlayer.playerContext) {
|
|
122
|
+
void playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.DEFAULT);
|
|
125
123
|
}
|
|
126
124
|
adUiSet = false;
|
|
127
125
|
resolve();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { handlePreRolls } from './handlePreRolls';
|
|
2
|
+
import { PlayerEvent } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
3
|
import { createMockNpoPlayer, createPlayerContextMock } from '../../../tests/mocks/playerContextMock';
|
|
3
4
|
jest.mock('bitmovin-player');
|
|
4
5
|
jest.mock('../../npoplayer');
|
|
@@ -11,11 +12,12 @@ describe('handlePreRolls', () => {
|
|
|
11
12
|
getActiveAdBreak: jest.fn()
|
|
12
13
|
},
|
|
13
14
|
on: jest.fn(),
|
|
14
|
-
off: jest.fn()
|
|
15
|
+
off: jest.fn(),
|
|
16
|
+
scheduleAds: jest.fn()
|
|
15
17
|
};
|
|
16
18
|
});
|
|
17
19
|
it('should not schedule ads when hasPreroll is false', async () => {
|
|
18
|
-
const
|
|
20
|
+
const npoPlayerMock = createMockNpoPlayer({
|
|
19
21
|
streamObject: {
|
|
20
22
|
metadata: {
|
|
21
23
|
hasPreroll: 'false'
|
|
@@ -26,13 +28,13 @@ describe('handlePreRolls', () => {
|
|
|
26
28
|
}
|
|
27
29
|
});
|
|
28
30
|
const playerContextMock = createPlayerContextMock({
|
|
29
|
-
|
|
31
|
+
npoPlayer: npoPlayerMock
|
|
30
32
|
});
|
|
31
33
|
await handlePreRolls(playerContextMock);
|
|
32
34
|
expect(mockPlayerAPI.ads.schedule).not.toHaveBeenCalled();
|
|
33
35
|
});
|
|
34
36
|
it('should not schedule ads if preroll URL is missing', async () => {
|
|
35
|
-
const
|
|
37
|
+
const npoPlayerMock = createMockNpoPlayer({
|
|
36
38
|
streamObject: {
|
|
37
39
|
metadata: {
|
|
38
40
|
hasPreroll: 'true'
|
|
@@ -41,7 +43,7 @@ describe('handlePreRolls', () => {
|
|
|
41
43
|
}
|
|
42
44
|
});
|
|
43
45
|
const playerContextMock = createPlayerContextMock({
|
|
44
|
-
|
|
46
|
+
npoPlayer: npoPlayerMock
|
|
45
47
|
});
|
|
46
48
|
await handlePreRolls(playerContextMock);
|
|
47
49
|
expect(mockPlayerAPI.ads.schedule).not.toHaveBeenCalled();
|
|
@@ -49,4 +51,63 @@ describe('handlePreRolls', () => {
|
|
|
49
51
|
afterEach(() => {
|
|
50
52
|
jest.clearAllMocks();
|
|
51
53
|
});
|
|
54
|
+
it('should schedule ads when hasPreroll is true and preroll URL exists', async () => {
|
|
55
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
56
|
+
const npoPlayerMock = createMockNpoPlayer({
|
|
57
|
+
streamObject: {
|
|
58
|
+
metadata: {
|
|
59
|
+
hasPreroll: 'true'
|
|
60
|
+
},
|
|
61
|
+
assets: {
|
|
62
|
+
preroll: 'sample_url'
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
const playerContextMock = createPlayerContextMock({
|
|
67
|
+
npoPlayer: npoPlayerMock,
|
|
68
|
+
player: mockPlayerAPI
|
|
69
|
+
});
|
|
70
|
+
const readyCallback = jest.fn();
|
|
71
|
+
mockPlayerAPI.on.mockImplementation((event, callback) => {
|
|
72
|
+
if (event === PlayerEvent.Ready) {
|
|
73
|
+
readyCallback.mockImplementation(callback);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
void handlePreRolls(playerContextMock);
|
|
77
|
+
readyCallback();
|
|
78
|
+
expect(playerContextMock.player.scheduleAds).toHaveBeenCalledWith({
|
|
79
|
+
tag: {
|
|
80
|
+
url: 'sample_url',
|
|
81
|
+
type: 'vast'
|
|
82
|
+
},
|
|
83
|
+
id: 'Ad',
|
|
84
|
+
position: 'pre'
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
it('should cleanup UI and resolve when AdBreakFinished event occurs', async () => {
|
|
88
|
+
const npoPlayerMock = createMockNpoPlayer({
|
|
89
|
+
streamObject: {
|
|
90
|
+
metadata: {
|
|
91
|
+
hasPreroll: 'true'
|
|
92
|
+
},
|
|
93
|
+
assets: {
|
|
94
|
+
preroll: 'sample_url'
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
const playerContextMock = createPlayerContextMock({
|
|
99
|
+
npoPlayer: npoPlayerMock,
|
|
100
|
+
player: mockPlayerAPI
|
|
101
|
+
});
|
|
102
|
+
const adBreakFinishedHandler = jest.fn();
|
|
103
|
+
mockPlayerAPI.on.mockImplementation((event, handler) => {
|
|
104
|
+
if (event === PlayerEvent.AdBreakFinished) {
|
|
105
|
+
adBreakFinishedHandler.mockImplementation(handler);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
const handlePromise = handlePreRolls(playerContextMock);
|
|
109
|
+
adBreakFinishedHandler();
|
|
110
|
+
await handlePromise;
|
|
111
|
+
expect(playerContextMock.npoPlayer.uiManager).toBeUndefined();
|
|
112
|
+
});
|
|
52
113
|
});
|
|
@@ -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
|
|
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);
|
|
@@ -15,7 +15,7 @@ export async function decideProfile(playerContext, preferredDRM = '') {
|
|
|
15
15
|
}
|
|
16
16
|
const { bestWithDRM, bestDRM } = determineBestWithDRM(supportedTech, { supportedDRM, preferredDRM });
|
|
17
17
|
const bestWithoutDRM = determineBestWithoutDRM(supportedTech);
|
|
18
|
-
return bestWithDRM ? { profileName: bestWithDRM, drm: bestDRM } : { profileName: bestWithoutDRM, drm:
|
|
18
|
+
return bestWithDRM ? { profileName: bestWithDRM, drm: bestDRM } : { profileName: bestWithoutDRM, drm: '' };
|
|
19
19
|
}
|
|
20
20
|
function determineBestWithDRM(supportedTech, drmInfo) {
|
|
21
21
|
let bestWithDRM = '';
|
|
@@ -33,6 +33,12 @@ function determineBestWithDRM(supportedTech, drmInfo) {
|
|
|
33
33
|
continue;
|
|
34
34
|
if (techMap[tech.streaming]) {
|
|
35
35
|
const { drm, stream } = techMap[tech.streaming];
|
|
36
|
+
if ((drmInfo.preferredDRM === DRM_TYPES.PLAYREADY || drmInfo.supportedDRM.includes(DRM_TYPES.PLAYREADY)) &&
|
|
37
|
+
tech.streaming === STREAM_TYPES.DASH) {
|
|
38
|
+
bestWithDRM = STREAM_TYPES.DASH;
|
|
39
|
+
bestDRM = DRM_TYPES.PLAYREADY;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
36
42
|
if (drmInfo.preferredDRM !== drm) {
|
|
37
43
|
bestDRM =
|
|
38
44
|
tech.streaming === STREAM_TYPES.DASH ? getBestDRMForDash(drmInfo) : getBestDRMForHls(drmInfo);
|
|
@@ -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,
|
|
16
|
+
mockPlayerContext = { player: mockPlayer, npoPlayer: mockNpoplayer };
|
|
17
17
|
});
|
|
18
18
|
afterEach(() => {
|
|
19
19
|
jest.clearAllMocks();
|
|
@@ -31,4 +31,8 @@ describe('decideProfile', () => {
|
|
|
31
31
|
const result = await decideProfile(mockPlayerContext, DRM_TYPES.FAIRPLAY);
|
|
32
32
|
expect(result).toEqual({ profileName: STREAM_TYPES.HLS, drm: DRM_TYPES.FAIRPLAY });
|
|
33
33
|
});
|
|
34
|
+
it('should return profile with dash streaming and playready DRM when preferred DRM is PlayReady', async () => {
|
|
35
|
+
const result = await decideProfile(mockPlayerContext, DRM_TYPES.PLAYREADY);
|
|
36
|
+
expect(result).toEqual({ profileName: STREAM_TYPES.DASH, drm: DRM_TYPES.PLAYREADY });
|
|
37
|
+
});
|
|
34
38
|
});
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { convertJwtToBase64, convertBase64ToObject } from '../../js/utilities/utilities.jwt';
|
|
2
|
-
import { getStreamObject } from '../../js/api/getstreamobject';
|
|
3
2
|
export async function verifyDRM(playerContext, payload) {
|
|
4
3
|
try {
|
|
5
|
-
const { player,
|
|
4
|
+
const { player, npoPlayer: { streamObject, sourceConfig } } = playerContext;
|
|
6
5
|
const { stream } = streamObject;
|
|
7
6
|
if (stream.drmToken) {
|
|
8
7
|
const drmJsonTimestamp = getDRMTokenTimestamp(stream.drmToken);
|
|
@@ -29,12 +28,12 @@ function getDRMTokenTimestamp(drmToken) {
|
|
|
29
28
|
return convertBase64ToObject(drmBase64).iat;
|
|
30
29
|
}
|
|
31
30
|
async function refreshDRMToken(playerContext, payload) {
|
|
32
|
-
const
|
|
33
|
-
const newDrmToken =
|
|
31
|
+
const { npoPlayer: { npoPlayerServices, streamObject, sourceConfig } } = playerContext;
|
|
32
|
+
const { stream: { drmToken: newDrmToken } } = await npoPlayerServices.fetchStream(playerContext, payload);
|
|
34
33
|
const clonedStreamObject = {
|
|
35
|
-
...
|
|
36
|
-
stream: { ...
|
|
34
|
+
...streamObject,
|
|
35
|
+
stream: { ...streamObject.stream, drmToken: newDrmToken }
|
|
37
36
|
};
|
|
38
|
-
playerContext.
|
|
39
|
-
await loadPlayer(playerContext,
|
|
37
|
+
playerContext.npoPlayer.streamObject = clonedStreamObject;
|
|
38
|
+
await loadPlayer(playerContext, sourceConfig);
|
|
40
39
|
}
|
|
@@ -1,24 +1,42 @@
|
|
|
1
1
|
import { verifyDRM } from './verifydrm';
|
|
2
2
|
import { mockNpoPlayer } from '../../../tests/mocks/mockNpoplayer';
|
|
3
3
|
import { convertBase64ToObject, convertJwtToBase64 } from '../../js/utilities/utilities.jwt';
|
|
4
|
-
import { getStreamObject } from '../../js/api/getstreamobject';
|
|
5
4
|
jest.mock('../../js/utilities/utilities.jwt', () => ({
|
|
6
5
|
convertBase64ToObject: jest.fn(),
|
|
7
6
|
convertJwtToBase64: jest.fn()
|
|
8
7
|
}));
|
|
9
|
-
jest.mock('
|
|
10
|
-
|
|
8
|
+
jest.mock('../streamFetchHandler/fetchStream', () => ({
|
|
9
|
+
fetchStream: jest.fn()
|
|
11
10
|
}));
|
|
12
11
|
let mockPlayer;
|
|
13
12
|
const mockNpoplayer = mockNpoPlayer;
|
|
14
13
|
let mockPlayerContext;
|
|
14
|
+
function createMockStreamObject(overrides = {}) {
|
|
15
|
+
return {
|
|
16
|
+
stream: {
|
|
17
|
+
avType: '',
|
|
18
|
+
drmType: '',
|
|
19
|
+
streamProfile: '',
|
|
20
|
+
sourceProfile: '',
|
|
21
|
+
streamURL: '',
|
|
22
|
+
drmToken: 'newToken'
|
|
23
|
+
},
|
|
24
|
+
metadata: { description: 'default description', title: 'default title' },
|
|
25
|
+
assets: { scrubbingThumbnail: 'thumbnail.jpg', subtitles: [] },
|
|
26
|
+
user: { type: 'anonymous' },
|
|
27
|
+
...overrides
|
|
28
|
+
};
|
|
29
|
+
}
|
|
15
30
|
beforeEach(() => {
|
|
16
31
|
jest.clearAllMocks();
|
|
17
32
|
mockPlayer = {
|
|
18
33
|
streamObject: { stream: { drmToken: undefined } },
|
|
19
34
|
load: jest.fn()
|
|
20
35
|
};
|
|
21
|
-
|
|
36
|
+
mockNpoplayer.npoPlayerServices = {
|
|
37
|
+
fetchStream: jest.fn()
|
|
38
|
+
};
|
|
39
|
+
mockPlayerContext = { player: mockPlayer, npoPlayer: mockNpoplayer };
|
|
22
40
|
});
|
|
23
41
|
afterEach(() => {
|
|
24
42
|
jest.clearAllMocks();
|
|
@@ -42,7 +60,7 @@ describe('Test DRM verification', () => {
|
|
|
42
60
|
streamURL: '',
|
|
43
61
|
drmToken: drmToken
|
|
44
62
|
};
|
|
45
|
-
mockPlayerContext.
|
|
63
|
+
mockPlayerContext.npoPlayer.sourceConfig = sourceConfig;
|
|
46
64
|
jest.spyOn(global.Date, 'now').mockImplementation(() => currentTime * 1000);
|
|
47
65
|
convertJwtToBase64.mockReturnValue(JSON.stringify({ iat: drmJsonTimestamp }));
|
|
48
66
|
convertBase64ToObject.mockReturnValue({ iat: drmJsonTimestamp });
|
|
@@ -62,14 +80,19 @@ describe('Test DRM verification', () => {
|
|
|
62
80
|
streamURL: '',
|
|
63
81
|
drmToken: drmToken
|
|
64
82
|
};
|
|
65
|
-
mockPlayerContext.
|
|
83
|
+
mockPlayerContext.npoPlayer.sourceConfig = sourceConfig;
|
|
66
84
|
jest.spyOn(global.Date, 'now').mockImplementation(() => currentTime * 1000);
|
|
67
85
|
convertJwtToBase64.mockReturnValue(JSON.stringify({ iat: drmJsonTimestamp }));
|
|
68
86
|
convertBase64ToObject.mockReturnValue({ iat: drmJsonTimestamp });
|
|
69
|
-
|
|
87
|
+
jest.spyOn(mockNpoplayer.npoPlayerServices, 'fetchStream').mockResolvedValue(createMockStreamObject({
|
|
88
|
+
stream: {
|
|
89
|
+
...createMockStreamObject().stream,
|
|
90
|
+
drmToken: 'overriddenToken'
|
|
91
|
+
}
|
|
92
|
+
}));
|
|
70
93
|
jest.spyOn(mockPlayerContext.player, 'load').mockResolvedValue(undefined);
|
|
71
94
|
await verifyDRM(mockPlayerContext, payload);
|
|
72
|
-
expect(
|
|
95
|
+
expect(mockNpoplayer.npoPlayerServices.fetchStream).toHaveBeenCalledWith(mockPlayerContext, payload);
|
|
73
96
|
expect(mockPlayerContext.player.load).toHaveBeenCalledWith(sourceConfig);
|
|
74
97
|
});
|
|
75
98
|
it('should call loadPlayer when the drmToken is null', async () => {
|
|
@@ -82,7 +105,7 @@ describe('Test DRM verification', () => {
|
|
|
82
105
|
streamURL: '',
|
|
83
106
|
drmToken: undefined
|
|
84
107
|
};
|
|
85
|
-
mockPlayerContext.
|
|
108
|
+
mockPlayerContext.npoPlayer.sourceConfig = sourceConfig;
|
|
86
109
|
await verifyDRM(mockPlayerContext, payload);
|
|
87
110
|
expect(mockPlayerContext.player.load).toHaveBeenCalledWith(sourceConfig);
|
|
88
111
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { setErrorBackground } from './errorHandler';
|
|
2
|
+
const posterUrl = 'https://example.com/poster.jpg';
|
|
3
|
+
describe('setErrorBackground', () => {
|
|
4
|
+
it('sets the error background image correctly', () => {
|
|
5
|
+
const mockPlayerContainer = document.createElement('div');
|
|
6
|
+
const mockPlayerContext = {
|
|
7
|
+
player: {
|
|
8
|
+
getNpoPlayerElement: jest.fn(() => mockPlayerContainer)
|
|
9
|
+
},
|
|
10
|
+
npoPlayer: {
|
|
11
|
+
sourceConfig: {
|
|
12
|
+
poster: posterUrl
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
setErrorBackground(mockPlayerContext);
|
|
17
|
+
expect(mockPlayerContainer.style.getPropertyValue('--npo-player-errormessage-background-image')).toBe(posterUrl);
|
|
18
|
+
});
|
|
19
|
+
it('sets the error background image to "none" if poster is not provided', () => {
|
|
20
|
+
const mockPlayerContainer = document.createElement('div');
|
|
21
|
+
const mockPlayerContext = {
|
|
22
|
+
player: {
|
|
23
|
+
getNpoPlayerElement: jest.fn(() => mockPlayerContainer)
|
|
24
|
+
},
|
|
25
|
+
npoPlayer: {
|
|
26
|
+
sourceConfig: {
|
|
27
|
+
poster: undefined
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
setErrorBackground(mockPlayerContext);
|
|
32
|
+
expect(mockPlayerContainer.style.getPropertyValue('--npo-player-errormessage-background-image')).toBe('none');
|
|
33
|
+
});
|
|
34
|
+
it('does nothing if getNpoPlayerElement returns undefined', () => {
|
|
35
|
+
const mockPlayerContext = {
|
|
36
|
+
player: {
|
|
37
|
+
getNpoPlayerElement: jest.fn(() => undefined)
|
|
38
|
+
},
|
|
39
|
+
npoPlayer: {
|
|
40
|
+
sourceConfig: {
|
|
41
|
+
poster: posterUrl
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
setErrorBackground(mockPlayerContext);
|
|
46
|
+
expect(() => setErrorBackground(mockPlayerContext)).not.toThrow();
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { customSpecificErrorMessageOverlayConfig, npoBusinessErrors } from './errorText';
|
|
2
|
+
export async function handlePlayerError(playerContext, status) {
|
|
3
|
+
const { player, npoPlayer } = playerContext;
|
|
4
|
+
const uiComponents = npoPlayer.uiComponents;
|
|
5
|
+
const errorContainerClass = 'npo-player-error';
|
|
6
|
+
const shouldRetry = status >= 1000 && npoPlayer.streamOptions.retryCallback !== undefined;
|
|
7
|
+
const message = generateErrorMessage(status, shouldRetry);
|
|
8
|
+
await player.unload();
|
|
9
|
+
uiComponents.controlBar?.hide();
|
|
10
|
+
const errorMessageOverlay = uiComponents.errorMessageOverlay;
|
|
11
|
+
if (!errorMessageOverlay)
|
|
12
|
+
return;
|
|
13
|
+
player.addClassToNpoPlayerElement(errorContainerClass);
|
|
14
|
+
setErrorBackground(playerContext);
|
|
15
|
+
errorMessageOverlay.display(message);
|
|
16
|
+
if (shouldRetry) {
|
|
17
|
+
setupRetryHandler(playerContext, errorContainerClass);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function generateErrorMessage(status, shouldRetry) {
|
|
21
|
+
const baseMessage = npoBusinessErrors[status] ?? customSpecificErrorMessageOverlayConfig[status] ?? 'De video kan niet worden geladen';
|
|
22
|
+
const retryMessage = shouldRetry
|
|
23
|
+
? '<br>Klik om het opnieuw te proberen.<br><br><button class="retry-button">Opnieuw proberen</button>'
|
|
24
|
+
: '';
|
|
25
|
+
return `<span class="errorcode">Foutcode ${status}</span>\n${baseMessage}${retryMessage}`;
|
|
26
|
+
}
|
|
27
|
+
function setupRetryHandler(playerContext, errorContainerClass) {
|
|
28
|
+
const playerContainer = playerContext.player.getNpoPlayerElement();
|
|
29
|
+
playerContainer.addEventListener('click', (event) => {
|
|
30
|
+
const target = event.target;
|
|
31
|
+
if (target.classList.contains('retry-button') && playerContainer.classList.contains(errorContainerClass)) {
|
|
32
|
+
target.style.visibility = 'hidden';
|
|
33
|
+
playerContext.player.handleErrorRetry(playerContext);
|
|
34
|
+
playerContext.player.removeClassFromNpoPlayerElement(errorContainerClass);
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
target.style.visibility = 'visible';
|
|
37
|
+
}, 200);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
export function setErrorBackground(playerContext) {
|
|
42
|
+
const playerContainer = playerContext.player.getNpoPlayerElement();
|
|
43
|
+
const posterImage = playerContext.npoPlayer.sourceConfig.poster;
|
|
44
|
+
playerContainer?.style.setProperty('--npo-player-errormessage-background-image', posterImage || 'none');
|
|
45
|
+
}
|