@npo/player 1.24.6 → 1.25.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/api/getstreamobject.test.js +2 -2
- package/lib/js/playeractions/handlers/processplayerconfig.js +14 -0
- package/lib/js/playeractions/handlers/processplayerconfig.test.d.ts +1 -0
- package/lib/js/playeractions/handlers/processplayerconfig.test.js +116 -0
- package/lib/js/playeractions/handlers/processsourceconfig.d.ts +2 -1
- package/lib/js/playeractions/handlers/processsourceconfig.js +16 -5
- package/lib/js/settings/localization.d.ts +76 -1
- package/lib/js/settings/localization.js +2 -2
- package/lib/js/tracking/handlers/eventbinding.js +25 -17
- package/lib/js/tracking/handlers/eventlogging.js +3 -8
- package/lib/js/tracking/handlers/playertrackerinit.d.ts +2 -2
- package/lib/js/tracking/handlers/playertrackerinit.js +8 -6
- package/lib/js/tracking/handlers/playertrackerinit.test.d.ts +1 -0
- package/lib/js/tracking/handlers/playertrackerinit.test.js +74 -0
- package/lib/js/utilities/utilities.element.d.ts +6 -0
- package/lib/js/utilities/utilities.element.js +10 -0
- package/lib/js/utilities/utilities.element.test.js +18 -5
- package/lib/npoplayer.d.ts +13 -3
- package/lib/npoplayer.js +43 -28
- package/lib/npoplayer.test.js +12 -4
- package/lib/package.json +2 -2
- package/lib/services/cdnProviders/cdnProviders.js +4 -2
- package/lib/services/nicamHandlers/nicamhandler.d.ts +6 -0
- package/lib/{ui/handlers → services/nicamHandlers}/nicamhandler.js +14 -6
- package/lib/services/nicamHandlers/nicamhandler.test.js +69 -0
- package/lib/services/npoPlayerAPI/npoPlayerAPI.d.ts +1 -0
- package/lib/services/npoPlayerAPI/npoPlayerAPI.js +6 -3
- package/lib/services/segmentHandlers/setSegmentMarkers.js +1 -1
- package/lib/services/services.d.ts +3 -0
- package/lib/services/services.js +7 -0
- package/lib/services/streamoptionsHandlers/steamOptionsHandler.d.ts +6 -0
- package/lib/services/streamoptionsHandlers/steamOptionsHandler.js +78 -0
- package/lib/services/streamoptionsHandlers/streamOptionsHandler.test.js +187 -0
- package/lib/src/js/playeractions/handlers/processplayerconfig.test.d.ts +1 -0
- package/lib/src/js/playeractions/handlers/processsourceconfig.d.ts +2 -1
- package/lib/src/js/settings/localization.d.ts +76 -1
- package/lib/src/js/tracking/handlers/playertrackerinit.d.ts +2 -2
- package/lib/src/js/tracking/handlers/playertrackerinit.test.d.ts +1 -0
- package/lib/src/js/utilities/utilities.element.d.ts +6 -0
- package/lib/src/npoplayer.d.ts +13 -3
- package/lib/src/services/nicamHandlers/nicamhandler.d.ts +6 -0
- package/lib/src/services/nicamHandlers/nicamhandler.test.d.ts +1 -0
- package/lib/src/services/npoPlayerAPI/npoPlayerAPI.d.ts +1 -0
- package/lib/src/services/services.d.ts +3 -0
- package/lib/src/services/streamoptionsHandlers/steamOptionsHandler.d.ts +6 -0
- package/lib/src/services/streamoptionsHandlers/streamOptionsHandler.test.d.ts +1 -0
- package/lib/src/types/interfaces.d.ts +2 -1
- package/lib/src/ui/components/buttons.d.ts +6 -3
- package/lib/src/ui/components/controlbar.d.ts +2 -2
- package/lib/src/ui/components/nativemobile/buttons.d.ts +8 -0
- package/lib/src/ui/components/playnext.d.ts +1 -0
- package/lib/src/ui/components/topbar.d.ts +2 -2
- package/lib/src/ui/components/verticalvideo/controlbar.d.ts +2 -2
- package/lib/src/ui/handlers/timecontrolhandlers.d.ts +3 -3
- package/lib/src/ui/uicontainer.d.ts +2 -3
- package/lib/tests/mocks/mockNpoplayer.js +3 -0
- package/lib/tests/mocks/playerContextMock.js +1 -0
- package/lib/types/interfaces.d.ts +2 -1
- package/lib/ui/components/buttons.d.ts +6 -3
- package/lib/ui/components/buttons.js +17 -17
- package/lib/ui/components/controlbar.d.ts +2 -2
- package/lib/ui/components/controlbar.js +15 -10
- package/lib/ui/components/nativemobile/buttons.d.ts +8 -0
- package/lib/ui/components/nativemobile/buttons.js +41 -1
- package/lib/ui/components/nativemobile/controlbar.js +1 -2
- package/lib/ui/components/playnext.d.ts +1 -0
- package/lib/ui/components/topbar.d.ts +2 -2
- package/lib/ui/components/topbar.js +14 -9
- package/lib/ui/components/verticalvideo/controlbar.d.ts +2 -2
- package/lib/ui/components/verticalvideo/controlbar.js +4 -4
- package/lib/ui/handlers/timecontrolhandlers.d.ts +3 -3
- package/lib/ui/nativemobileuifactory.js +20 -24
- package/lib/ui/nativemobileuifactory.test.js +0 -5
- package/lib/ui/uicontainer.d.ts +2 -3
- package/lib/ui/uicontainer.js +7 -5
- package/package.json +2 -2
- package/src/style/components/_icons.scss +5 -0
- package/src/style/npoplayer.css +2 -1
- package/lib/src/ui/handlers/nicamhandler.d.ts +0 -6
- package/lib/src/ui/handlers/streamhandler.d.ts +0 -2
- package/lib/ui/handlers/nicamhandler.d.ts +0 -6
- package/lib/ui/handlers/nicamhandler.test.js +0 -36
- package/lib/ui/handlers/streamhandler.d.ts +0 -2
- package/lib/ui/handlers/streamhandler.js +0 -60
- /package/lib/{src/ui/handlers → services/nicamHandlers}/nicamhandler.test.d.ts +0 -0
- /package/lib/{ui/handlers/nicamhandler.test.d.ts → services/streamoptionsHandlers/streamOptionsHandler.test.d.ts} +0 -0
package/lib/npoplayer.js
CHANGED
|
@@ -11,19 +11,16 @@ import { isMediaUrl, isUrl } from './js/utilities/utilities.url';
|
|
|
11
11
|
import { logVersion } from './js/utilities/utilities.version';
|
|
12
12
|
import { getStreamDurationInSeconds } from './js/utilities/utilities.stream';
|
|
13
13
|
import { LogEmitter } from './types/classes';
|
|
14
|
-
import { handlePreRolls } from './services/advertHandlers/handlePreRolls';
|
|
15
14
|
import pkg from '../package.json';
|
|
16
15
|
import { NpoPlayerUIVariants, LocalStorageValues } from './types/interfaces';
|
|
17
16
|
import { nativeMobileUiFactory } from './ui/nativemobileuifactory';
|
|
18
17
|
import { setupMediaSessionActionHandlers } from './js/playeractions/handlers/mediasessionactions';
|
|
19
18
|
import { removeReplayClass } from './js/playeractions/handlers/removereplayclass';
|
|
20
|
-
import { showNicamAfterUiDelay } from './ui/handlers/nicamhandler';
|
|
21
19
|
import { updateLiveMarkers } from './js/markers/updateLiveMarkers';
|
|
22
20
|
import { NpoPlayerAPI } from './services/npoPlayerAPI/npoPlayerAPI';
|
|
23
|
-
import { discardAdBreak } from './services/advertHandlers/discardAdBreak';
|
|
24
21
|
export { NpoPlayerUIVariants };
|
|
25
22
|
export default class NpoPlayer {
|
|
26
|
-
constructor(
|
|
23
|
+
constructor(container, playerConfig, npoTag, npoTagInstance, variant, npoTagPageTracker) {
|
|
27
24
|
this.sourceConfig = {};
|
|
28
25
|
this.streamObject = {
|
|
29
26
|
stream: { drmType: '', streamProfile: '', streamURL: '', avType: '', sourceProfile: '' },
|
|
@@ -33,6 +30,9 @@ export default class NpoPlayer {
|
|
|
33
30
|
};
|
|
34
31
|
this.player = undefined;
|
|
35
32
|
this.uiManager = undefined;
|
|
33
|
+
this.npoTagInitialisation = undefined;
|
|
34
|
+
this.npoTagInstance = undefined;
|
|
35
|
+
this.npoTagPageTracker = undefined;
|
|
36
36
|
this.streamTracker = undefined;
|
|
37
37
|
this.logEmitter = new LogEmitter();
|
|
38
38
|
this.uiComponents = {};
|
|
@@ -48,11 +48,32 @@ export default class NpoPlayer {
|
|
|
48
48
|
this.npoplayerServices = new NpoPlayerServices();
|
|
49
49
|
this.eventListeners = undefined;
|
|
50
50
|
this.userPreferences = {};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
if (typeof container === 'object' && !(container instanceof HTMLElement)) {
|
|
52
|
+
const params = container;
|
|
53
|
+
this.container = params.container;
|
|
54
|
+
this.playerConfig = params.playerConfig;
|
|
55
|
+
this.npoTagInitialisation = params.npoTag || undefined;
|
|
56
|
+
this.npoTagInstance = params.npoTagInstance;
|
|
57
|
+
this.variant = params.variant || NpoPlayerUIVariants.DEFAULT;
|
|
58
|
+
this.npoTagPageTracker = params.npoTagPageTracker || undefined;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this.container = container;
|
|
62
|
+
this.playerConfig = playerConfig || undefined;
|
|
63
|
+
this.npoTagInitialisation = npoTag || undefined;
|
|
64
|
+
this.npoTagInstance = npoTagInstance;
|
|
65
|
+
this.variant = variant || NpoPlayerUIVariants.DEFAULT;
|
|
66
|
+
this.npoTagPageTracker = npoTagPageTracker || undefined;
|
|
67
|
+
console.warn('As of NPO Player version 1.25, parameter-based initialization has been deprecated in favor of object-based initialization. This feature will be removed in version 2.0. Please update your implementation to ensure compatibility. For more details, refer to the documentation at: https://docs.npoplayer.nl/implementation/web/player.');
|
|
68
|
+
}
|
|
69
|
+
if (!this.playerConfig) {
|
|
70
|
+
console.error('Player configuration is missing. Ensure that playerConfig is properly initialized before using the player.');
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (this.npoTagInstance) {
|
|
74
|
+
initPlayerTracker(this, this.npoTagInitialisation, this.npoTagInstance, this.npoTagPageTracker);
|
|
75
|
+
}
|
|
76
|
+
this.initPlayer(this.container, this.playerConfig);
|
|
56
77
|
}
|
|
57
78
|
initPlayer(_container, playerConfig) {
|
|
58
79
|
const processedPlayerConfig = playerAction.processPlayerConfig(this, playerConfig);
|
|
@@ -84,8 +105,9 @@ export default class NpoPlayer {
|
|
|
84
105
|
console.error('Er is nog geen player geladen.');
|
|
85
106
|
return;
|
|
86
107
|
}
|
|
87
|
-
if (this.
|
|
88
|
-
|
|
108
|
+
if (this.adBreakActive) {
|
|
109
|
+
const currentAd = this.player.ads.getActiveAdBreak().id;
|
|
110
|
+
this.player.ads.discardAdBreak(currentAd);
|
|
89
111
|
}
|
|
90
112
|
let _streamObject;
|
|
91
113
|
const sourceIsUrl = isUrl(source);
|
|
@@ -105,7 +127,7 @@ export default class NpoPlayer {
|
|
|
105
127
|
analytics: {
|
|
106
128
|
customData2: 'other',
|
|
107
129
|
customData3: 'unknown',
|
|
108
|
-
customData4: this.
|
|
130
|
+
customData4: this.npoTagInstance?.getParty(),
|
|
109
131
|
customData5: this.version
|
|
110
132
|
}
|
|
111
133
|
};
|
|
@@ -146,7 +168,7 @@ export default class NpoPlayer {
|
|
|
146
168
|
if (this.streamObject?.stream == undefined)
|
|
147
169
|
return;
|
|
148
170
|
const drmType = this.streamObject.stream.drmType ?? undefined;
|
|
149
|
-
this.sourceConfig = await playerAction.processSourceConfig(this.npoplayerServices, options.sourceConfig ?? {}, this.streamObject, drmType && drmType.length > 0 ? profile.drm : undefined, this.streamOptions, this.version, this.npoTag?.npoTagInstance
|
|
171
|
+
this.sourceConfig = await playerAction.processSourceConfig(this.npoplayerServices, source, options.sourceConfig ?? {}, this.streamObject, drmType && drmType.length > 0 ? profile.drm : undefined, this.streamOptions, this.version, this.npoTag?.npoTagInstance);
|
|
150
172
|
await this.npoplayerServices.verifyDRM(this.playerContext, payload);
|
|
151
173
|
setupMediaSessionActionHandlers(this.player, this.sourceConfig, _streamObject);
|
|
152
174
|
logEvent(this, 'load');
|
|
@@ -170,7 +192,7 @@ export default class NpoPlayer {
|
|
|
170
192
|
this.streamObject.assets.preroll) {
|
|
171
193
|
this.player.on(PlayerEvent.AdBreakFinished, initAndStartTracker);
|
|
172
194
|
this.player.on(PlayerEvent.AdError, initAndStartTracker);
|
|
173
|
-
await
|
|
195
|
+
await this.npoplayerServices.schedulePreRolls(this.playerContext);
|
|
174
196
|
}
|
|
175
197
|
else {
|
|
176
198
|
initAndStartTracker();
|
|
@@ -179,12 +201,11 @@ export default class NpoPlayer {
|
|
|
179
201
|
else {
|
|
180
202
|
this.doError(`Het is niet gelukt de stream op te halen: \n Input is geen valide token of media object.`, 500);
|
|
181
203
|
}
|
|
204
|
+
this.npoplayerServices.setupNicamKijkwijzerIcons(this.playerContext);
|
|
205
|
+
this.player.on(PlayerEvent.Play, () => {
|
|
206
|
+
this.npoplayerServices.showNicamAfterUiDelay(this.playerContext, this.uiManager);
|
|
207
|
+
});
|
|
182
208
|
this.npoplayerServices.handleVerticalVideoControls(this.playerContext, this.variant);
|
|
183
|
-
if (this.sourceConfig?.metadata) {
|
|
184
|
-
this.sourceConfig.metadata.jwt = source;
|
|
185
|
-
this.sourceConfig.metadata.streamLinkAsJsonString = JSON.stringify(this.streamObject);
|
|
186
|
-
this.sourceConfig.metadata.npoTagSession = String(this.npoTag?.npoTagInstance?.getSerializedSessionInfo());
|
|
187
|
-
}
|
|
188
209
|
this.player.on(PlayerEvent.Seek, () => {
|
|
189
210
|
removeReplayClass(this.player);
|
|
190
211
|
});
|
|
@@ -196,16 +217,13 @@ export default class NpoPlayer {
|
|
|
196
217
|
this.hidePlayNextScreen();
|
|
197
218
|
});
|
|
198
219
|
}
|
|
199
|
-
this.player.on(PlayerEvent.Play, () => {
|
|
200
|
-
showNicamAfterUiDelay(this.player, this.uiManager);
|
|
201
|
-
});
|
|
202
220
|
const setLiveOffsetListener = function () {
|
|
203
221
|
if (this.playerContext === undefined)
|
|
204
222
|
return;
|
|
205
|
-
this.player?.off(PlayerEvent.
|
|
223
|
+
this.player?.off(PlayerEvent.Ready, setLiveOffsetListener);
|
|
206
224
|
playerAction.handleLiveOffsetLogic(this.playerContext, options);
|
|
207
225
|
}.bind(this);
|
|
208
|
-
this.player.on(PlayerEvent.
|
|
226
|
+
this.player.on(PlayerEvent.Ready, setLiveOffsetListener);
|
|
209
227
|
}
|
|
210
228
|
doError(input, status) {
|
|
211
229
|
if (this.player == undefined)
|
|
@@ -307,7 +325,7 @@ export default class NpoPlayer {
|
|
|
307
325
|
const destroyLogic = async () => {
|
|
308
326
|
try {
|
|
309
327
|
if (this.npoTag != undefined) {
|
|
310
|
-
clearInterval(this.npoTag
|
|
328
|
+
clearInterval(this.npoTag?.heartbeatInterval);
|
|
311
329
|
}
|
|
312
330
|
logEvent(this, 'stop');
|
|
313
331
|
this.uiManager?.release();
|
|
@@ -332,9 +350,6 @@ export default class NpoPlayer {
|
|
|
332
350
|
if (this.npoTag != undefined) {
|
|
333
351
|
clearInterval(this.npoTag.heartbeatInterval);
|
|
334
352
|
}
|
|
335
|
-
if (this.playerContext) {
|
|
336
|
-
discardAdBreak(this.playerContext);
|
|
337
|
-
}
|
|
338
353
|
this.hidePlayNextScreen();
|
|
339
354
|
await this.player?.unload();
|
|
340
355
|
return true;
|
package/lib/npoplayer.test.js
CHANGED
|
@@ -3,12 +3,20 @@ const div = document.createElement('div');
|
|
|
3
3
|
const testPlayerConfig = {
|
|
4
4
|
key: 'dummy-key'
|
|
5
5
|
};
|
|
6
|
-
jest.mock('./
|
|
7
|
-
|
|
6
|
+
jest.mock('./services/streamoptionsHandlers/steamOptionsHandler', () => ({
|
|
7
|
+
handleStreamOptions: jest.fn()
|
|
8
8
|
}));
|
|
9
9
|
let player;
|
|
10
|
-
test('player init', async () => {
|
|
10
|
+
test('player init with parameters', async () => {
|
|
11
11
|
player = new NpoPlayer(div, testPlayerConfig);
|
|
12
12
|
expect(player).toBeInstanceOf(NpoPlayer);
|
|
13
|
-
expect(player.playerConfig
|
|
13
|
+
expect(player.playerConfig?.key).toBe(testPlayerConfig.key);
|
|
14
|
+
});
|
|
15
|
+
test('player init with parameters', async () => {
|
|
16
|
+
player = new NpoPlayer({
|
|
17
|
+
container: div,
|
|
18
|
+
playerConfig: testPlayerConfig
|
|
19
|
+
});
|
|
20
|
+
expect(player).toBeInstanceOf(NpoPlayer);
|
|
21
|
+
expect(player.playerConfig?.key).toBe(testPlayerConfig.key);
|
|
14
22
|
});
|
package/lib/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npo/player",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"description": "NPO Player",
|
|
5
5
|
"author": "Publieke Omroep <player@npo.nl>",
|
|
6
6
|
"contributors": [
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
92
|
"@npotag/tag": "3.2.1",
|
|
93
|
-
"bitmovin-player": "8.
|
|
93
|
+
"bitmovin-player": "^8.166.0",
|
|
94
94
|
"bitmovin-player-ui": "3.67.0"
|
|
95
95
|
},
|
|
96
96
|
"browserslist": [
|
|
@@ -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',
|
|
7
|
-
['npo-fsly.cdn.streamgate.io',
|
|
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'],
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { UIManager } from 'bitmovin-player-ui';
|
|
2
|
+
import { PlayerContext } from '../../types/interfaces';
|
|
3
|
+
export declare function processNicam(playerContext: PlayerContext, nicamElement: HTMLElement | undefined): void;
|
|
4
|
+
export declare function addNicamIcon(character: string, nicamElement: Element): void;
|
|
5
|
+
export declare function showNicamAfterUiDelay(playerContext: PlayerContext, uiManager: UIManager | undefined): void;
|
|
6
|
+
export declare function setupNicamKijkwijzerIcons(playerContext: PlayerContext): void;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export function processNicam(
|
|
3
|
-
const
|
|
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,9 +45,10 @@ export function addNicamIcon(character, nicamElement) {
|
|
|
43
45
|
span.classList.add('nicam-icon', iconClass);
|
|
44
46
|
nicamElement.appendChild(span);
|
|
45
47
|
}
|
|
46
|
-
export function showNicamAfterUiDelay(
|
|
47
|
-
player
|
|
48
|
-
|
|
48
|
+
export function showNicamAfterUiDelay(playerContext, uiManager) {
|
|
49
|
+
const player = playerContext.player;
|
|
50
|
+
player.off(NpoPlayerEvent.Play, () => {
|
|
51
|
+
showNicamAfterUiDelay(playerContext, uiManager);
|
|
49
52
|
});
|
|
50
53
|
if (uiManager === null)
|
|
51
54
|
return;
|
|
@@ -61,3 +64,8 @@ export function showNicamAfterUiDelay(player, uiManager) {
|
|
|
61
64
|
}, 3000);
|
|
62
65
|
});
|
|
63
66
|
}
|
|
67
|
+
export function setupNicamKijkwijzerIcons(playerContext) {
|
|
68
|
+
const { container } = playerContext.npoplayer;
|
|
69
|
+
const nicamElement = container.querySelector('.bmpui-nicam');
|
|
70
|
+
processNicam(playerContext, nicamElement);
|
|
71
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { processNicam } from './nicamhandler';
|
|
2
|
+
import '@testing-library/jest-dom';
|
|
3
|
+
import { createMockNpoPlayer, createPlayerContextMock } from '../../../tests/mocks/playerContextMock';
|
|
4
|
+
describe('NICAM Processing', () => {
|
|
5
|
+
let mockElement;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
mockElement = { innerHTML: '', appendChild: jest.fn() };
|
|
8
|
+
document.querySelector = jest.fn().mockReturnValue(mockElement);
|
|
9
|
+
});
|
|
10
|
+
it('processes NICAM from the streamObject', () => {
|
|
11
|
+
const mockElement = document.createElement('div');
|
|
12
|
+
const npoplayerMock = createMockNpoPlayer({
|
|
13
|
+
streamObject: {
|
|
14
|
+
metadata: {
|
|
15
|
+
ageRating: '12',
|
|
16
|
+
nicam: ['GEWELD', 'ANGST', 'DRUGS_EN_ALCOHOL', 'GROF_TAALGEBRUIK']
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const playerContextMock = createPlayerContextMock({
|
|
21
|
+
npoplayer: npoplayerMock
|
|
22
|
+
});
|
|
23
|
+
processNicam(playerContextMock, mockElement);
|
|
24
|
+
expect(mockElement.children).toHaveLength(5);
|
|
25
|
+
});
|
|
26
|
+
it('processes NICAM and age rating with streamOptions taking priority', () => {
|
|
27
|
+
const mockElement = document.createElement('div');
|
|
28
|
+
const npoplayerMock = createMockNpoPlayer({
|
|
29
|
+
streamObject: {
|
|
30
|
+
metadata: {
|
|
31
|
+
ageRating: '12',
|
|
32
|
+
nicam: ['GEWELD', 'ANGST', 'GROF_TAALGEBRUIK']
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
streamOptions: {
|
|
36
|
+
ageRating: '16',
|
|
37
|
+
nicam: ['DRUGS_EN_ALCOHOL']
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const playerContextMock = createPlayerContextMock({
|
|
41
|
+
npoplayer: npoplayerMock
|
|
42
|
+
});
|
|
43
|
+
processNicam(playerContextMock, mockElement);
|
|
44
|
+
expect(mockElement.children).toHaveLength(2);
|
|
45
|
+
});
|
|
46
|
+
it('does nothing if no NICAM element found', () => {
|
|
47
|
+
document.querySelector = jest.fn().mockReturnValue(undefined);
|
|
48
|
+
const npoplayerMock = createMockNpoPlayer({
|
|
49
|
+
streamObject: {
|
|
50
|
+
metadata: {
|
|
51
|
+
ageRating: '12',
|
|
52
|
+
nicam: ['GEWELD', 'ANGST', 'GROF_TAALGEBRUIK']
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const playerContextMock = createPlayerContextMock({
|
|
57
|
+
npoplayer: npoplayerMock
|
|
58
|
+
});
|
|
59
|
+
processNicam(playerContextMock, mockElement);
|
|
60
|
+
});
|
|
61
|
+
it('does nothing if no metadata and no streamOptions', () => {
|
|
62
|
+
const npoplayerMock = createMockNpoPlayer({});
|
|
63
|
+
const playerContextMock = createPlayerContextMock({
|
|
64
|
+
npoplayer: npoplayerMock
|
|
65
|
+
});
|
|
66
|
+
processNicam(playerContextMock, mockElement);
|
|
67
|
+
expect(mockElement.appendChild).not.toHaveBeenCalled();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -25,6 +25,7 @@ export declare class NpoPlayerAPI {
|
|
|
25
25
|
getSupportedTech(): Technology[];
|
|
26
26
|
off(eventType: NpoPlayerEvent, callback: NpoPlayerEventCallback): void;
|
|
27
27
|
on(eventType: NpoPlayerEvent, callback: NpoPlayerEventCallback): void;
|
|
28
|
+
isCastAvailable(): boolean;
|
|
28
29
|
seek(time: number): void;
|
|
29
30
|
timeShift(time: number): void;
|
|
30
31
|
getContainer(): HTMLElement;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UIManager } from 'bitmovin-player-ui';
|
|
2
2
|
import { customSpecificErrorMessageOverlayConfig } from '../../js/playeractions/handlers/customerrors';
|
|
3
|
-
import {
|
|
3
|
+
import { handleStreamOptions } from '../streamoptionsHandlers/steamOptionsHandler';
|
|
4
4
|
import { createUIContainer } from '../../ui/uicontainer';
|
|
5
5
|
import { playerEventMap } from '../../types/events';
|
|
6
6
|
import { VOLUME_MAX, VOLUME_MIN, VOLUME_STEP } from './contants';
|
|
@@ -99,6 +99,9 @@ export class NpoPlayerAPI {
|
|
|
99
99
|
}
|
|
100
100
|
this.playerAPI.on(externalEventType, externalCallback);
|
|
101
101
|
}
|
|
102
|
+
isCastAvailable() {
|
|
103
|
+
return this.playerAPI.isCastAvailable();
|
|
104
|
+
}
|
|
102
105
|
seek(time) {
|
|
103
106
|
this.playerAPI.seek(time);
|
|
104
107
|
}
|
|
@@ -148,9 +151,9 @@ export class NpoPlayerAPI {
|
|
|
148
151
|
disableAutoHideWhenHovered: true,
|
|
149
152
|
seekbarSnappingEnabled: false
|
|
150
153
|
};
|
|
151
|
-
playerContext.npoplayer.uiManager = new UIManager(this.playerAPI, createUIContainer(playerContext
|
|
154
|
+
playerContext.npoplayer.uiManager = new UIManager(this.playerAPI, createUIContainer(playerContext, this.playerAPI, variant), uiConfig);
|
|
152
155
|
playerContext.npoplayer.variant = variant;
|
|
153
156
|
}
|
|
154
|
-
|
|
157
|
+
handleStreamOptions(playerContext);
|
|
155
158
|
}
|
|
156
159
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ApiPayload, Fragment, PlayerContext, Profile, Segment, TimeLineMarker, LocalStorageData, LocalStorageValues, NpoPlayerUIVariants } from '../types/interfaces';
|
|
2
2
|
import { AVType } from '@npotag/tag/dist/types/src/streamTracker';
|
|
3
|
+
import { UIManager } from 'bitmovin-player-ui';
|
|
3
4
|
export declare class NpoPlayerServices {
|
|
4
5
|
getAVType(avType: string): AVType;
|
|
5
6
|
keyboardHandler(playerContext: PlayerContext, e: KeyboardEvent): void;
|
|
@@ -13,4 +14,6 @@ export declare class NpoPlayerServices {
|
|
|
13
14
|
setAccessibilityAttributes(playerContext: PlayerContext): void;
|
|
14
15
|
schedulePreRolls(playerContext: PlayerContext): Promise<void>;
|
|
15
16
|
handleVerticalVideoControls(playerContext: PlayerContext, variant: NpoPlayerUIVariants): void;
|
|
17
|
+
showNicamAfterUiDelay(playerContext: PlayerContext | undefined, uiManager: UIManager | undefined): void;
|
|
18
|
+
setupNicamKijkwijzerIcons(playerContext: PlayerContext): void;
|
|
16
19
|
}
|
package/lib/services/services.js
CHANGED
|
@@ -7,6 +7,7 @@ import { getLocalStorage, setLocalStorage, setValuesBasedOnLocalStorage } from '
|
|
|
7
7
|
import { getAVType } from './avTypeHandlers/getAVType';
|
|
8
8
|
import { handlePreRolls } from './advertHandlers/handlePreRolls';
|
|
9
9
|
import { handleVerticalVideoControls } from './verticalVideoHandlers/handleVerticalVideoControls';
|
|
10
|
+
import { setupNicamKijkwijzerIcons, showNicamAfterUiDelay } from './nicamHandlers/nicamhandler';
|
|
10
11
|
export class NpoPlayerServices {
|
|
11
12
|
getAVType(avType) {
|
|
12
13
|
return getAVType(avType);
|
|
@@ -52,4 +53,10 @@ export class NpoPlayerServices {
|
|
|
52
53
|
handleVerticalVideoControls(playerContext, variant) {
|
|
53
54
|
return handleVerticalVideoControls(playerContext, variant);
|
|
54
55
|
}
|
|
56
|
+
showNicamAfterUiDelay(playerContext, uiManager) {
|
|
57
|
+
return showNicamAfterUiDelay(playerContext, uiManager);
|
|
58
|
+
}
|
|
59
|
+
setupNicamKijkwijzerIcons(playerContext) {
|
|
60
|
+
return setupNicamKijkwijzerIcons(playerContext);
|
|
61
|
+
}
|
|
55
62
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { PlayerContext } from '../../types/interfaces';
|
|
2
|
+
export declare function handleStreamOptions(playerContext: PlayerContext): void;
|
|
3
|
+
export declare function initializeFragment(playerContext: PlayerContext): void;
|
|
4
|
+
export declare function handleStartOffset(playerContext: PlayerContext): void;
|
|
5
|
+
export declare function updateStreamClasses(playerContext: PlayerContext): void;
|
|
6
|
+
export declare function setupAutoplay(playerContext: PlayerContext): void;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as playerAction from '../../js/playeractions/playeractions';
|
|
2
|
+
import { initSegment } from '../../services/segmentHandlers/initSegment';
|
|
3
|
+
import { handleLiveStreamControls } from '../../services/liveStreamHandlers/handleLiveStreamControls';
|
|
4
|
+
import { removeEventListeners } from '../../services/eventListenerHandlers/removeEventListeners';
|
|
5
|
+
import { NpoPlayerEvent } from '../../types/events';
|
|
6
|
+
import { updateClassFromElementByQuery } from '../../js/utilities/utilities.element';
|
|
7
|
+
export function handleStreamOptions(playerContext) {
|
|
8
|
+
const { streamObject, uiManager } = playerContext.npoplayer;
|
|
9
|
+
if (!streamObject || !uiManager)
|
|
10
|
+
return;
|
|
11
|
+
removeEventListeners(playerContext);
|
|
12
|
+
initializeFragment(playerContext);
|
|
13
|
+
handleStartOffset(playerContext);
|
|
14
|
+
updateStreamClasses(playerContext);
|
|
15
|
+
const isAutoplayEnabled = getAutoplayStatus(playerContext);
|
|
16
|
+
if (isAutoplayEnabled) {
|
|
17
|
+
setupAutoplay(playerContext);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function initializeFragment(playerContext) {
|
|
21
|
+
const { streamObject, streamOptions } = playerContext.npoplayer;
|
|
22
|
+
initSegment(playerContext, {
|
|
23
|
+
segment: streamObject.segment,
|
|
24
|
+
fragment: streamOptions?.fragments
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
export function handleStartOffset(playerContext) {
|
|
28
|
+
const streamOptions = playerContext.npoplayer.streamOptions;
|
|
29
|
+
if (streamOptions?.startOffset) {
|
|
30
|
+
playerAction.handleStartOffset(playerContext, streamOptions.startOffset);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export function updateStreamClasses(playerContext) {
|
|
34
|
+
const { streamObject, container } = playerContext.npoplayer;
|
|
35
|
+
const containerClassString = '.bmpui-ui-uicontainer';
|
|
36
|
+
const playerContainer = container;
|
|
37
|
+
const queries = [
|
|
38
|
+
{
|
|
39
|
+
container: playerContainer,
|
|
40
|
+
query: containerClassString,
|
|
41
|
+
className: 'livestream-no-dvr',
|
|
42
|
+
condition: !!(streamObject.stream.isLiveStream && !streamObject.stream.hasDvrWindow)
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
container: playerContainer,
|
|
46
|
+
query: containerClassString,
|
|
47
|
+
className: 'audio-only',
|
|
48
|
+
condition: !!(streamObject.stream.avType === 'aod' || streamObject.stream.avType === 'audio')
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
container: playerContainer,
|
|
52
|
+
query: '.bitmovinplayer-poster',
|
|
53
|
+
className: 'audio-only',
|
|
54
|
+
condition: !!(streamObject.stream.avType === 'aod' || streamObject.stream.avType === 'audio')
|
|
55
|
+
}
|
|
56
|
+
];
|
|
57
|
+
for (const query of queries)
|
|
58
|
+
updateClassFromElementByQuery(query);
|
|
59
|
+
if (streamObject.stream.isLiveStream && streamObject.stream.hasDvrWindow) {
|
|
60
|
+
handleLiveStreamControls(playerContext);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function getAutoplayStatus(playerContext) {
|
|
64
|
+
return (playerContext.npoplayer.streamOptions?.autoplay ?? playerContext.player.getConfig()?.playback?.autoplay ?? false);
|
|
65
|
+
}
|
|
66
|
+
export function setupAutoplay(playerContext) {
|
|
67
|
+
const player = playerContext.player;
|
|
68
|
+
const handleAutoPlay = () => {
|
|
69
|
+
doAutoPlay().catch((error) => {
|
|
70
|
+
console.error('Error attempting to autoplay:', error);
|
|
71
|
+
});
|
|
72
|
+
};
|
|
73
|
+
const doAutoPlay = async () => {
|
|
74
|
+
player.off(NpoPlayerEvent.SourceLoaded, handleAutoPlay);
|
|
75
|
+
await player.play();
|
|
76
|
+
};
|
|
77
|
+
player.on(NpoPlayerEvent.SourceLoaded, handleAutoPlay);
|
|
78
|
+
}
|