@npo/player 1.18.4 → 1.20.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 +4 -1
- package/lib/js/ads/ster.js +2 -0
- package/lib/js/drm/handlers/decideprofile.js +17 -17
- package/lib/js/drm/handlers/decideprofile.test.d.ts +1 -0
- package/lib/js/drm/handlers/decideprofile.test.js +33 -0
- package/lib/js/fragments/removefragments.d.ts +1 -2
- package/lib/js/fragments/removefragments.js +1 -5
- package/lib/js/fragments/removefragments.test.d.ts +1 -0
- package/lib/js/fragments/removefragments.test.js +26 -0
- package/lib/js/fragments/setfragments.d.ts +1 -1
- package/lib/js/fragments/setfragments.js +19 -13
- package/lib/js/fragments/setfragments.test.d.ts +1 -0
- package/lib/js/fragments/setfragments.test.js +72 -0
- package/lib/js/playeractions/handlers/handleoffsets.js +8 -5
- package/lib/js/playeractions/handlers/processsourceconfig.js +13 -7
- package/lib/js/playeractions/handlers/removereplayclass.d.ts +2 -0
- package/lib/js/playeractions/handlers/removereplayclass.js +11 -0
- package/lib/js/playeractions/handlers/removereplayclass.test.d.ts +1 -0
- package/lib/js/playeractions/handlers/removereplayclass.test.js +28 -0
- package/lib/js/playeractions/handlers/resolvekeypress.test.d.ts +1 -0
- package/lib/js/playeractions/handlers/resolvekeypress.test.js +80 -0
- package/lib/js/tracking/handlers/eventlogging.test.d.ts +1 -0
- package/lib/js/tracking/handlers/eventlogging.test.js +46 -0
- package/lib/js/ui/components/controlbar.js +2 -1
- package/lib/js/ui/components/nativemobile/buttons.js +0 -1
- package/lib/js/ui/components/settingspanel.js +4 -0
- package/lib/js/ui/handlers/listboxhandlers.js +1 -0
- package/lib/js/ui/handlers/nicamhandler.d.ts +3 -0
- package/lib/js/ui/handlers/nicamhandler.js +16 -0
- package/lib/js/ui/handlers/streamhandler.js +1 -1
- package/lib/js/ui/nativemobileuicontainer.js +2 -2
- package/lib/js/ui/nativemobileuifactory.js +18 -26
- package/lib/js/ui/uicontainer.d.ts +1 -0
- package/lib/js/ui/uicontainer.js +8 -0
- package/lib/js/utilities/utilities.js +3 -4
- package/lib/npoplayer.d.ts +4 -2
- package/lib/npoplayer.js +117 -36
- package/lib/package.json +7 -7
- package/lib/src/js/drm/handlers/decideprofile.test.d.ts +1 -0
- package/lib/src/js/fragments/removefragments.d.ts +1 -2
- package/lib/src/js/fragments/removefragments.test.d.ts +1 -0
- package/lib/src/js/fragments/setfragments.d.ts +1 -1
- package/lib/src/js/fragments/setfragments.test.d.ts +1 -0
- package/lib/src/js/playeractions/handlers/removereplayclass.d.ts +2 -0
- package/lib/src/js/playeractions/handlers/removereplayclass.test.d.ts +1 -0
- package/lib/src/js/playeractions/handlers/resolvekeypress.test.d.ts +1 -0
- package/lib/src/js/tracking/handlers/eventlogging.test.d.ts +1 -0
- package/lib/src/js/ui/handlers/nicamhandler.d.ts +3 -0
- package/lib/src/js/ui/uicontainer.d.ts +1 -0
- package/lib/src/npoplayer.d.ts +4 -2
- package/lib/src/types/interfaces.d.ts +10 -0
- package/lib/tests/mocks/mockNpoplayer.d.ts +2 -0
- package/lib/tests/mocks/mockNpoplayer.js +115 -0
- package/lib/types/interfaces.d.ts +10 -0
- package/package.json +7 -7
- package/src/scss/components/_advert.scss +5 -5
- package/src/scss/components/_hugeplaybacktogglebutton.scss +1 -0
- package/src/scss/components/_metadata.scss +17 -0
- package/src/scss/components/_nicam.scss +20 -0
- package/src/scss/components/_replay.scss +2 -2
- package/src/scss/components/_seekbarthumbnail.scss +0 -1
- package/src/scss/components/_subtitles.scss +1 -1
- package/src/scss/npoplayer.css +39 -34
- package/src/scss/variants/_player-base.scss +7 -2
- package/lib/js/ui/handlers/playnexthandlers.d.ts +0 -0
- package/lib/js/ui/handlers/playnexthandlers.js +0 -1
- package/lib/src/js/ui/handlers/playnexthandlers.d.ts +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PlayerEvent } from 'bitmovin-player';
|
|
1
2
|
export function processNicam(streamObject, nicamElement, streamOptions) {
|
|
2
3
|
const effectiveMetadata = streamOptions ? { ...streamObject.metadata, ...streamOptions } : streamObject.metadata;
|
|
3
4
|
if (nicamElement) {
|
|
@@ -24,3 +25,18 @@ export function addNicamIcon(character, nicamElement) {
|
|
|
24
25
|
span.classList.add('nicam-icon', iconClass);
|
|
25
26
|
nicamElement.appendChild(span);
|
|
26
27
|
}
|
|
28
|
+
export function showNicamAfterUiDelay(player, uiManager) {
|
|
29
|
+
player.off(PlayerEvent.Play, () => { showNicamAfterUiDelay(player, uiManager); });
|
|
30
|
+
if (uiManager === null)
|
|
31
|
+
return;
|
|
32
|
+
const playerContainer = player.getContainer().querySelector('.bmpui-npo-player.bmpui-layout-max-width-400') || player.getContainer().querySelector('.bmpui-npo-player.bmpui-layout-max-width-600');
|
|
33
|
+
if (!playerContainer)
|
|
34
|
+
return;
|
|
35
|
+
uiManager.activeUi.onControlsHide.subscribeOnce(() => {
|
|
36
|
+
const className = 'show-nicam';
|
|
37
|
+
playerContainer.classList.add(className);
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
playerContainer.classList.remove(className);
|
|
40
|
+
}, 3000);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -10,7 +10,7 @@ export function processStream(streamObject, container, streamOptions, player, ui
|
|
|
10
10
|
const section = {
|
|
11
11
|
start: seg.inpoint,
|
|
12
12
|
end: seg.outpoint,
|
|
13
|
-
title: sourceConfig.title || '',
|
|
13
|
+
title: sourceConfig.title || streamObject.metadata.title || '',
|
|
14
14
|
};
|
|
15
15
|
setFragments(player, uiManager, { sections: [section] });
|
|
16
16
|
}
|
|
@@ -10,6 +10,7 @@ const defaultData = {
|
|
|
10
10
|
defaultActionRequired: true,
|
|
11
11
|
};
|
|
12
12
|
export function sendCustomMessage(message, data) {
|
|
13
|
+
console.log('sendCustomMessage', message, data);
|
|
13
14
|
try {
|
|
14
15
|
if (data !== undefined) {
|
|
15
16
|
return JSON.parse(window.bitmovin.customMessageHandler.sendSynchronous(message, JSON.stringify(data)));
|
|
@@ -18,8 +19,7 @@ export function sendCustomMessage(message, data) {
|
|
|
18
19
|
return JSON.parse(window.bitmovin.customMessageHandler.sendSynchronous(message));
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
|
-
catch
|
|
22
|
-
console.warn(`Custom message ${message} may not be send, as it returned no valid data (JSON as a string)`, e);
|
|
22
|
+
catch {
|
|
23
23
|
return defaultData;
|
|
24
24
|
}
|
|
25
25
|
}
|
|
@@ -17,30 +17,31 @@ export function nativeMobileUiFactory(player, config = {}) {
|
|
|
17
17
|
const mobileUIManager = new UIManager(player, nativeMobileUIContainer(player), uiConfig);
|
|
18
18
|
let _streamObject = {};
|
|
19
19
|
const removeFinishedClass = () => {
|
|
20
|
-
|
|
20
|
+
player.off(PlayerEvent.Seeked, removeFinishedClass);
|
|
21
|
+
const playerFinishedElement = player.getContainer().querySelector('.bmpui-npo-player.bmpui-player-state-finished');
|
|
21
22
|
if (playerFinishedElement) {
|
|
22
23
|
playerFinishedElement.classList.remove('bmpui-player-state-finished');
|
|
23
24
|
}
|
|
24
25
|
};
|
|
25
26
|
const clearUI = () => {
|
|
26
|
-
const nicamElement =
|
|
27
|
+
const nicamElement = player.getContainer().querySelector('.bmpui-nicam');
|
|
27
28
|
if (nicamElement) {
|
|
28
29
|
nicamElement.innerHTML = '';
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
const element =
|
|
31
|
+
player.getContainer().querySelector('.bmpui-npo-player')?.classList.remove('livestream-dvr');
|
|
32
|
+
const element = player.getContainer().querySelector('.bmpui-seekbar-label-title');
|
|
32
33
|
if (element) {
|
|
33
34
|
element.textContent = '';
|
|
34
35
|
}
|
|
35
|
-
removeFragments(
|
|
36
|
+
removeFragments(mobileUIManager);
|
|
36
37
|
};
|
|
37
38
|
const updateUI = () => {
|
|
38
39
|
if (_streamObject.metadata?.ageRating) {
|
|
39
|
-
processNicam(_streamObject,
|
|
40
|
+
processNicam(_streamObject, player.getContainer().querySelector('.bmpui-nicam'), null);
|
|
40
41
|
}
|
|
41
42
|
const isLiveStream = _streamObject.stream?.isLiveStream && _streamObject.stream?.hasDvrWindow;
|
|
42
43
|
if (isLiveStream) {
|
|
43
|
-
|
|
44
|
+
player.getContainer().querySelector('.bmpui-npo-player')?.classList.add('livestream-dvr');
|
|
44
45
|
}
|
|
45
46
|
if (_streamObject.segment) {
|
|
46
47
|
const seg = _streamObject.segment;
|
|
@@ -54,7 +55,7 @@ export function nativeMobileUiFactory(player, config = {}) {
|
|
|
54
55
|
else {
|
|
55
56
|
addFragments(player, mobileUIManager, null);
|
|
56
57
|
}
|
|
57
|
-
const element =
|
|
58
|
+
const element = player.getContainer().querySelector('.bmpui-seekbar-label-title');
|
|
58
59
|
if (element) {
|
|
59
60
|
element.textContent = _streamObject.title || '';
|
|
60
61
|
}
|
|
@@ -69,27 +70,18 @@ export function nativeMobileUiFactory(player, config = {}) {
|
|
|
69
70
|
});
|
|
70
71
|
}
|
|
71
72
|
const addEventListeners = () => {
|
|
72
|
-
|
|
73
|
+
player.off(PlayerEvent.Ready, addEventListeners);
|
|
74
|
+
sendCustomMessage(CustomMessages.JAVASCRIPT_READY);
|
|
75
|
+
const playbackToggleElement = player.getContainer().querySelector('#native-mobile-playbacktoggleoverlay');
|
|
73
76
|
if (playbackToggleElement) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
sendCustomMessage(CustomMessages.TOGGLE_PLAY_PAUSE, { isChecked:
|
|
77
|
+
playbackToggleElement.addEventListener('touchend', (event) => {
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
player?.play();
|
|
80
|
+
sendCustomMessage(CustomMessages.TOGGLE_PLAY_PAUSE, { isChecked: true });
|
|
78
81
|
});
|
|
79
82
|
}
|
|
80
83
|
};
|
|
81
|
-
player.
|
|
82
|
-
|
|
83
|
-
});
|
|
84
|
-
player.on(PlayerEvent.Seeked, () => {
|
|
85
|
-
removeFinishedClass();
|
|
86
|
-
});
|
|
87
|
-
player.off(PlayerEvent.Ready, () => {
|
|
88
|
-
sendCustomMessage(CustomMessages.JAVASCRIPT_READY);
|
|
89
|
-
});
|
|
90
|
-
player.on(PlayerEvent.Ready, () => {
|
|
91
|
-
addEventListeners();
|
|
92
|
-
sendCustomMessage(CustomMessages.JAVASCRIPT_READY);
|
|
93
|
-
});
|
|
84
|
+
player.on(PlayerEvent.Seeked, removeFinishedClass);
|
|
85
|
+
player.on(PlayerEvent.Ready, addEventListeners);
|
|
94
86
|
return mobileUIManager;
|
|
95
87
|
}
|
|
@@ -3,3 +3,4 @@ import { UIContainer } from 'bitmovin-player-ui';
|
|
|
3
3
|
import { PlayerAPI } from 'bitmovin-player';
|
|
4
4
|
import { NpoPlayerUIVariants } from '../../types/interfaces';
|
|
5
5
|
export declare function createUIContainer(npoplayer: NpoPlayer, player: PlayerAPI, variant: NpoPlayerUIVariants, container: HTMLElement): UIContainer;
|
|
6
|
+
export declare function removeUIContainer(container: HTMLElement): void;
|
package/lib/js/ui/uicontainer.js
CHANGED
|
@@ -77,3 +77,11 @@ export function createUIContainer(npoplayer, player, variant, container) {
|
|
|
77
77
|
hideDelay: uiDelay
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
|
+
export function removeUIContainer(container) {
|
|
81
|
+
for (let i = 0; i < container.attributes.length; i += 1) {
|
|
82
|
+
const attributeName = container.attributes[i].name;
|
|
83
|
+
if (attributeName.startsWith('data-')) {
|
|
84
|
+
container.removeAttribute(attributeName);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -22,10 +22,9 @@ export function localize(key) {
|
|
|
22
22
|
return i18n.getLocalizer(key);
|
|
23
23
|
}
|
|
24
24
|
export function validateStreamLength(duration, seconds = false) {
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
return duration !== undefined ? msToSeconds(Number(duration)) : -1;
|
|
25
|
+
if (duration === undefined || duration === Infinity)
|
|
26
|
+
return -1;
|
|
27
|
+
return seconds ? (isFinite(+duration) ? Number(duration) : -1) : msToSeconds(Number(duration));
|
|
29
28
|
}
|
|
30
29
|
export function msToSeconds(ms) {
|
|
31
30
|
return ms / 1000;
|
package/lib/npoplayer.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export default class NpoPlayer {
|
|
|
32
32
|
createUIManager(player: PlayerAPI, variant: NpoPlayerUIVariants): Promise<void>;
|
|
33
33
|
doError(input: any, status?: number): void;
|
|
34
34
|
keyPress(e: KeyboardEvent): void;
|
|
35
|
+
play(): void;
|
|
36
|
+
pause(): void;
|
|
35
37
|
setVolume(volume: number): void;
|
|
36
38
|
increaseVolume(): void;
|
|
37
39
|
decreaseVolume(): void;
|
|
@@ -42,7 +44,7 @@ export default class NpoPlayer {
|
|
|
42
44
|
cancelPlayNextScreen(): void;
|
|
43
45
|
hidePlayNextScreen(): void;
|
|
44
46
|
doPlayNext(): void;
|
|
45
|
-
destroy(): boolean;
|
|
46
|
-
unload(): boolean;
|
|
47
|
+
destroy(asyncMode?: boolean): Promise<boolean> | boolean;
|
|
48
|
+
unload(asyncMode?: boolean): Promise<boolean> | boolean;
|
|
47
49
|
printVersion(): void;
|
|
48
50
|
}
|
package/lib/npoplayer.js
CHANGED
|
@@ -9,7 +9,7 @@ import { getStreamObject } from './js/api/getstreamobject';
|
|
|
9
9
|
import { printVersion } from './js/utilities/printversion';
|
|
10
10
|
import { UIManager } from 'bitmovin-player-ui';
|
|
11
11
|
import { customSpecificErrorMessageOverlayConfig } from './js/playeractions/handlers/customerrors';
|
|
12
|
-
import { createUIContainer } from './js/ui/uicontainer';
|
|
12
|
+
import { createUIContainer, removeUIContainer } from './js/ui/uicontainer';
|
|
13
13
|
import { addAccessibilityAttributes } from './js/ui/handlers/accessibilityhandler';
|
|
14
14
|
import { LogEmitter } from './types/classes';
|
|
15
15
|
import { handlePreRolls } from './js/ads/ster';
|
|
@@ -18,6 +18,8 @@ import { NpoPlayerUIVariants } from './types/interfaces';
|
|
|
18
18
|
import { nativeMobileUiFactory } from './js/ui/nativemobileuifactory';
|
|
19
19
|
import { setupMediaSessionActionHandlers } from './js/playeractions/handlers/mediasessionactions';
|
|
20
20
|
import { processStream } from './js/ui/handlers/streamhandler';
|
|
21
|
+
import { removeReplayClass } from './js/playeractions/handlers/removereplayclass';
|
|
22
|
+
import { showNicamAfterUiDelay } from './js/ui/handlers/nicamhandler';
|
|
21
23
|
export { NpoPlayerUIVariants, };
|
|
22
24
|
export default class NpoPlayer {
|
|
23
25
|
constructor(_container, _playerConfig, _npotag, _npotaginstance, _variant) {
|
|
@@ -55,6 +57,13 @@ export default class NpoPlayer {
|
|
|
55
57
|
this.container.addEventListener('keydown', e => {
|
|
56
58
|
this.keyPress(e);
|
|
57
59
|
}, true);
|
|
60
|
+
const playbackToggleElement = this.container.querySelector('.bmpui-ui-playbacktoggle-overlay');
|
|
61
|
+
if (playbackToggleElement) {
|
|
62
|
+
playbackToggleElement.addEventListener('touchend', (event) => {
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
this.player?.play();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
58
67
|
}
|
|
59
68
|
async loadStream(source, options = {}) {
|
|
60
69
|
this.streamOptions = options;
|
|
@@ -70,13 +79,21 @@ export default class NpoPlayer {
|
|
|
70
79
|
const isUrl = utility.isUrl(source);
|
|
71
80
|
const isMedia = await utility.isMediaUrl(source);
|
|
72
81
|
const isJWTToken = utility.isJWTToken(source);
|
|
82
|
+
const getDurationAndStartPlayerTracker = function () {
|
|
83
|
+
if (this.player === null)
|
|
84
|
+
return;
|
|
85
|
+
let prid = (utility.isJWTToken(source) ? this.streamObject?.metadata.prid : source) || 'unknown';
|
|
86
|
+
this.player.off(PlayerEvent.SourceLoaded, getDurationAndStartPlayerTracker);
|
|
87
|
+
let duration = this.player ? this.player.getDuration() : undefined;
|
|
88
|
+
startPlayerTracker(this, utility.validateStreamLength(duration, true), this.version, prid);
|
|
89
|
+
}.bind(this);
|
|
73
90
|
if (isUrl && isMedia) {
|
|
74
91
|
this.sourceConfig = {
|
|
75
92
|
...options.sourceConfig,
|
|
76
93
|
'progressive': source
|
|
77
94
|
};
|
|
78
95
|
this.player?.load(this.sourceConfig);
|
|
79
|
-
|
|
96
|
+
getDurationAndStartPlayerTracker();
|
|
80
97
|
}
|
|
81
98
|
else if (isJWTToken) {
|
|
82
99
|
this.jwt = source;
|
|
@@ -86,7 +103,17 @@ export default class NpoPlayer {
|
|
|
86
103
|
const payload = {
|
|
87
104
|
baseURL: endpoint,
|
|
88
105
|
jwt: source,
|
|
89
|
-
data: {
|
|
106
|
+
data: {
|
|
107
|
+
profileName: profile.profileName,
|
|
108
|
+
drmType: profile.drm,
|
|
109
|
+
referrerUrl: window.location.href,
|
|
110
|
+
ster: {
|
|
111
|
+
identifier: options?.ster?.identifier ?? 'npo-app-desktop',
|
|
112
|
+
deviceType: options?.ster?.deviceType ?? 4,
|
|
113
|
+
site: options?.ster?.site ?? 'npo',
|
|
114
|
+
player: 'web'
|
|
115
|
+
}
|
|
116
|
+
}
|
|
90
117
|
};
|
|
91
118
|
try {
|
|
92
119
|
_streamObject = await getStreamObject(this, payload);
|
|
@@ -107,7 +134,14 @@ export default class NpoPlayer {
|
|
|
107
134
|
await drm.verifyDRM(this, this.player, payload);
|
|
108
135
|
setupMediaSessionActionHandlers(this.player, this.sourceConfig, _streamObject);
|
|
109
136
|
logEvent(this, 'load');
|
|
110
|
-
|
|
137
|
+
let streamDuration = _streamObject.metadata.duration;
|
|
138
|
+
let streamPrid = this.streamObject.metadata.prid || _streamObject.metadata.prid;
|
|
139
|
+
streamDuration = streamDuration == null
|
|
140
|
+
? this.player.on(PlayerEvent.SourceLoaded, getDurationAndStartPlayerTracker)
|
|
141
|
+
: startPlayerTracker(this, utility.validateStreamLength(streamDuration, false), this.version, streamPrid);
|
|
142
|
+
if (this.isShowingPlayNextScreen) {
|
|
143
|
+
this.hidePlayNextScreen();
|
|
144
|
+
}
|
|
111
145
|
if (this.variant !== NpoPlayerUIVariants.AUDIO) {
|
|
112
146
|
await handlePreRolls(this.player, _streamObject, this);
|
|
113
147
|
}
|
|
@@ -115,15 +149,23 @@ export default class NpoPlayer {
|
|
|
115
149
|
else {
|
|
116
150
|
this.doError(`Het is niet gelukt de stream op te halen: \n Input is geen valide token of media object.`, 500);
|
|
117
151
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
152
|
+
const triggerAddAccessibilityAttributes = () => {
|
|
153
|
+
this.player?.off(PlayerEvent.SourceLoaded, triggerAddAccessibilityAttributes);
|
|
154
|
+
this.player?.off(PlayerEvent.AdBreakFinished, triggerAddAccessibilityAttributes);
|
|
155
|
+
this.player?.off(PlayerEvent.AdError, triggerAddAccessibilityAttributes);
|
|
156
|
+
void addAccessibilityAttributes(this.container, this.streamObject.metadata);
|
|
157
|
+
};
|
|
158
|
+
this.player.on(PlayerEvent.SourceLoaded, triggerAddAccessibilityAttributes);
|
|
159
|
+
this.player.on(PlayerEvent.AdBreakFinished, triggerAddAccessibilityAttributes);
|
|
160
|
+
this.player.on(PlayerEvent.AdError, triggerAddAccessibilityAttributes);
|
|
122
161
|
if (this.sourceConfig?.metadata) {
|
|
123
162
|
this.sourceConfig.metadata.jwt = source;
|
|
124
163
|
this.sourceConfig.metadata.streamLinkAsJsonString = JSON.stringify(this.streamObject);
|
|
125
164
|
this.sourceConfig.metadata.npoTagSession = String(this.npoTag?.npoTagInstance?.getSerializedSessionInfo());
|
|
126
165
|
}
|
|
166
|
+
this.player.on(PlayerEvent.Seek, () => {
|
|
167
|
+
removeReplayClass(this.player);
|
|
168
|
+
});
|
|
127
169
|
if (options?.playNext?.showPlayNext === true) {
|
|
128
170
|
this.player.on(PlayerEvent.TimeChanged, () => {
|
|
129
171
|
this.showPlayNextScreen();
|
|
@@ -132,6 +174,7 @@ export default class NpoPlayer {
|
|
|
132
174
|
this.hidePlayNextScreen();
|
|
133
175
|
});
|
|
134
176
|
}
|
|
177
|
+
this.player.on(PlayerEvent.Play, () => { showNicamAfterUiDelay(this.player, this.uiManager); });
|
|
135
178
|
if (options?.startOffset != null)
|
|
136
179
|
playerAction.handleStartOffset(this.player, options.startOffset);
|
|
137
180
|
const setLiveOffsetListener = function () {
|
|
@@ -143,15 +186,15 @@ export default class NpoPlayer {
|
|
|
143
186
|
this.player.on(PlayerEvent.SourceLoaded, setLiveOffsetListener);
|
|
144
187
|
}
|
|
145
188
|
async createUIManager(player, variant) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
189
|
+
if (this.uiManager === null || variant !== this.variant) {
|
|
190
|
+
const uiConfig = {
|
|
191
|
+
errorMessages: customSpecificErrorMessageOverlayConfig,
|
|
192
|
+
disableAutoHideWhenHovered: true
|
|
193
|
+
};
|
|
151
194
|
this.uiManager = new UIManager(player, createUIContainer(this, player, variant, this.container), uiConfig);
|
|
152
195
|
this.variant = variant;
|
|
153
196
|
}
|
|
154
|
-
|
|
197
|
+
else {
|
|
155
198
|
processStream(this.streamObject, this.container, this.streamOptions, player, this.uiManager, this.sourceConfig);
|
|
156
199
|
}
|
|
157
200
|
}
|
|
@@ -170,6 +213,16 @@ export default class NpoPlayer {
|
|
|
170
213
|
return;
|
|
171
214
|
playerAction.resolveKeyPress(this.player, this, e);
|
|
172
215
|
}
|
|
216
|
+
play() {
|
|
217
|
+
if (this.player == null)
|
|
218
|
+
return;
|
|
219
|
+
this.player.play();
|
|
220
|
+
}
|
|
221
|
+
pause() {
|
|
222
|
+
if (this.player == null)
|
|
223
|
+
return;
|
|
224
|
+
this.player.pause();
|
|
225
|
+
}
|
|
173
226
|
setVolume(volume) {
|
|
174
227
|
if (this.player == null)
|
|
175
228
|
return;
|
|
@@ -211,7 +264,7 @@ export default class NpoPlayer {
|
|
|
211
264
|
playerAction.shiftToProgramStart(this.player, this.streamOptions.liveProgramTime);
|
|
212
265
|
}
|
|
213
266
|
showPlayNextScreen() {
|
|
214
|
-
if (this.player == null || !this.streamOptions.playNext?.showPlayNext)
|
|
267
|
+
if (this.player == null || !this.streamOptions.playNext?.showPlayNext || this.adBreakActive)
|
|
215
268
|
return;
|
|
216
269
|
this.player.off(PlayerEvent.TimeChanged, () => {
|
|
217
270
|
this.showPlayNextScreen();
|
|
@@ -245,33 +298,61 @@ export default class NpoPlayer {
|
|
|
245
298
|
this.hidePlayNextScreen();
|
|
246
299
|
void this.streamOptions.playNext?.proceedCallback?.();
|
|
247
300
|
}
|
|
248
|
-
destroy() {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
301
|
+
destroy(asyncMode = false) {
|
|
302
|
+
const destroyLogic = async () => {
|
|
303
|
+
try {
|
|
304
|
+
if (this.npoTag != null) {
|
|
305
|
+
clearInterval(this.npoTag.heartbeatInterval);
|
|
306
|
+
}
|
|
307
|
+
logEvent(this, 'stop');
|
|
308
|
+
const playerContainer = this.player?.getContainer();
|
|
309
|
+
if (playerContainer)
|
|
310
|
+
removeUIContainer(playerContainer);
|
|
311
|
+
this.uiManager?.release();
|
|
312
|
+
this.uiManager = null;
|
|
313
|
+
await this.player?.destroy();
|
|
314
|
+
return true;
|
|
252
315
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
316
|
+
catch (e) {
|
|
317
|
+
console.error('Error destroying player:', e);
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
if (asyncMode) {
|
|
322
|
+
return destroyLogic().then(() => true).catch(() => false);
|
|
258
323
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return false;
|
|
324
|
+
else {
|
|
325
|
+
return destroyLogic();
|
|
262
326
|
}
|
|
263
327
|
}
|
|
264
|
-
unload() {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
328
|
+
unload(asyncMode = false) {
|
|
329
|
+
const unloadLogic = async () => {
|
|
330
|
+
try {
|
|
331
|
+
if (this.npoTag != null) {
|
|
332
|
+
clearInterval(this.npoTag.heartbeatInterval);
|
|
333
|
+
}
|
|
334
|
+
const playerContainer = this.player?.getContainer();
|
|
335
|
+
if (playerContainer)
|
|
336
|
+
removeUIContainer(playerContainer);
|
|
337
|
+
this.hidePlayNextScreen();
|
|
338
|
+
await this.player?.unload();
|
|
339
|
+
return true;
|
|
268
340
|
}
|
|
269
|
-
|
|
270
|
-
|
|
341
|
+
catch (e) {
|
|
342
|
+
console.error('Error unloading player:', e);
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
if (asyncMode) {
|
|
347
|
+
return unloadLogic();
|
|
271
348
|
}
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
349
|
+
else {
|
|
350
|
+
try {
|
|
351
|
+
return unloadLogic();
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
275
356
|
}
|
|
276
357
|
}
|
|
277
358
|
printVersion() {
|
package/lib/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npo/player",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
4
4
|
"description": "NPO Player",
|
|
5
5
|
"author": "Publieke Omroep <player@npo.nl>",
|
|
6
6
|
"contributors": [
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"Arjan Kruithof"
|
|
10
10
|
],
|
|
11
11
|
"engines": {
|
|
12
|
-
"node": "^18
|
|
12
|
+
"node": "^18 || ^20"
|
|
13
13
|
},
|
|
14
14
|
"license": "ISC",
|
|
15
15
|
"main": "./lib/npoplayer",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"bundle": "npm run lint && bash build-lib.sh && npm run build:scss && npm run build:cdn",
|
|
25
25
|
"build:ts": "bash build-lib.sh",
|
|
26
26
|
"test": "jest",
|
|
27
|
-
"test:ci": "
|
|
27
|
+
"test:ci": "jest --collectCoverage --testResultsProcessor=jest-sonar-reporter",
|
|
28
28
|
"version:dev": "npm version prerelease --preid=dev --no-git-tag-version"
|
|
29
29
|
},
|
|
30
30
|
"files": [
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"eslint-plugin-import": "^2.27.5",
|
|
56
56
|
"eslint-plugin-n": "^15.7.0",
|
|
57
57
|
"eslint-plugin-promise": "^6.1.1",
|
|
58
|
-
"eslint-plugin-sonarjs": "^0.
|
|
58
|
+
"eslint-plugin-sonarjs": "^0.23.0",
|
|
59
59
|
"fs-extra": "^11.1.1",
|
|
60
60
|
"jest": "^28.1.3",
|
|
61
61
|
"jest-environment-jsdom": "^29.4.1",
|
|
@@ -81,9 +81,9 @@
|
|
|
81
81
|
"webpack-dev-server": "^4.11.1"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@npotag/tag": "^3.0.
|
|
85
|
-
"bitmovin-player": "8.
|
|
86
|
-
"bitmovin-player-ui": "
|
|
84
|
+
"@npotag/tag": "^3.0.1",
|
|
85
|
+
"bitmovin-player": "8.151.0",
|
|
86
|
+
"bitmovin-player-ui": "3.54.0"
|
|
87
87
|
},
|
|
88
88
|
"browserslist": [
|
|
89
89
|
"defaults",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,4 +3,4 @@ import { type Fragments } from '../../types/interfaces';
|
|
|
3
3
|
import { UIManager } from 'bitmovin-player-ui';
|
|
4
4
|
export declare const checkFunction: () => (e: any) => void;
|
|
5
5
|
export declare const seekFunction: () => (e: any) => void;
|
|
6
|
-
export declare function setFragments(player: PlayerAPI, uiManager: UIManager, fragments: Fragments):
|
|
6
|
+
export declare function setFragments(player: PlayerAPI, uiManager: UIManager, fragments: Fragments): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { PlayerAPI } from 'bitmovin-player';
|
|
2
|
+
import { UIManager } from 'bitmovin-player-ui';
|
|
1
3
|
import { StreamObject, StreamOptions } from 'types/interfaces';
|
|
2
4
|
export declare function processNicam(streamObject: StreamObject, nicamElement: HTMLElement | null, streamOptions: StreamOptions | null): void;
|
|
3
5
|
export declare function addNicamIcon(character: string, nicamElement: Element): void;
|
|
6
|
+
export declare function showNicamAfterUiDelay(player: PlayerAPI, uiManager: UIManager | null): void;
|
|
@@ -3,3 +3,4 @@ import { UIContainer } from 'bitmovin-player-ui';
|
|
|
3
3
|
import { PlayerAPI } from 'bitmovin-player';
|
|
4
4
|
import { NpoPlayerUIVariants } from '../../types/interfaces';
|
|
5
5
|
export declare function createUIContainer(npoplayer: NpoPlayer, player: PlayerAPI, variant: NpoPlayerUIVariants, container: HTMLElement): UIContainer;
|
|
6
|
+
export declare function removeUIContainer(container: HTMLElement): void;
|
package/lib/src/npoplayer.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export default class NpoPlayer {
|
|
|
32
32
|
createUIManager(player: PlayerAPI, variant: NpoPlayerUIVariants): Promise<void>;
|
|
33
33
|
doError(input: any, status?: number): void;
|
|
34
34
|
keyPress(e: KeyboardEvent): void;
|
|
35
|
+
play(): void;
|
|
36
|
+
pause(): void;
|
|
35
37
|
setVolume(volume: number): void;
|
|
36
38
|
increaseVolume(): void;
|
|
37
39
|
decreaseVolume(): void;
|
|
@@ -42,7 +44,7 @@ export default class NpoPlayer {
|
|
|
42
44
|
cancelPlayNextScreen(): void;
|
|
43
45
|
hidePlayNextScreen(): void;
|
|
44
46
|
doPlayNext(): void;
|
|
45
|
-
destroy(): boolean;
|
|
46
|
-
unload(): boolean;
|
|
47
|
+
destroy(asyncMode?: boolean): Promise<boolean> | boolean;
|
|
48
|
+
unload(asyncMode?: boolean): Promise<boolean> | boolean;
|
|
47
49
|
printVersion(): void;
|
|
48
50
|
}
|
|
@@ -15,6 +15,15 @@ export interface ApiPayload {
|
|
|
15
15
|
baseURL: string;
|
|
16
16
|
jwt: string;
|
|
17
17
|
data: Record<string, unknown>;
|
|
18
|
+
ster?: SterData;
|
|
19
|
+
}
|
|
20
|
+
interface SterData {
|
|
21
|
+
identifier: string;
|
|
22
|
+
site?: string;
|
|
23
|
+
deviceType?: number;
|
|
24
|
+
os?: string;
|
|
25
|
+
osVersion?: string;
|
|
26
|
+
player?: string;
|
|
18
27
|
}
|
|
19
28
|
export interface DRMProfile {
|
|
20
29
|
profileName: string;
|
|
@@ -86,6 +95,7 @@ export interface StreamOptions {
|
|
|
86
95
|
ageRating?: string;
|
|
87
96
|
nicam?: string[] | null;
|
|
88
97
|
playNext?: PlayNext;
|
|
98
|
+
ster?: SterData;
|
|
89
99
|
}
|
|
90
100
|
export interface UIComponents {
|
|
91
101
|
errorMessageOverlay?: ErrorMessageOverlay;
|