@npo/player 1.27.7 → 1.28.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 -7
- package/lib/js/markers/updateLiveMarkers.d.ts +7 -2
- package/lib/js/markers/updateLiveMarkers.js +11 -4
- package/lib/js/markers/updateLiveMarkers.test.js +13 -3
- package/lib/js/playeractions/handlers/handleoffsets.test.js +1 -1
- package/lib/js/playeractions/handlers/mediasessionactions.d.ts +7 -2
- package/lib/js/playeractions/handlers/mediasessionactions.js +7 -7
- package/lib/js/playeractions/handlers/processplayerconfig.d.ts +1 -1
- package/lib/js/playeractions/handlers/processplayerconfig.js +1 -1
- package/lib/js/playeractions/handlers/processplayerconfig.test.js +1 -1
- package/lib/js/playeractions/handlers/processsourceconfig.d.ts +11 -2
- package/lib/js/playeractions/handlers/processsourceconfig.js +35 -18
- package/lib/js/playeractions/handlers/removereplayclass.d.ts +1 -1
- package/lib/js/playeractions/handlers/removereplayclass.js +1 -1
- package/lib/js/playeractions/handlers/removereplayclass.test.js +1 -1
- package/lib/js/settings/localization.d.ts +1 -0
- package/lib/js/utilities/utilities.jwt.d.ts +2 -0
- package/lib/js/utilities/utilities.jwt.js +22 -0
- package/lib/js/utilities/utilities.stream.js +11 -2
- package/lib/js/utilities/utilities.url.js +2 -2
- package/lib/js/utilities/utilities.version.js +1 -1
- package/lib/js/utilities/utilities.version.test.js +1 -1
- package/lib/lang/nl.json +2 -1
- package/lib/npoplayer.d.ts +6 -5
- package/lib/npoplayer.js +81 -28
- package/lib/package.json +7 -9
- package/lib/services/a11y/setup.test.js +2 -4
- package/lib/services/advertHandlers/handlePreRolls.js +3 -4
- package/lib/services/advertHandlers/handlePrerolls.test.js +2 -3
- package/lib/services/chapterHandlers/chapterHandler.d.ts +35 -0
- package/lib/services/chapterHandlers/chapterHandler.js +230 -0
- package/lib/services/errors/errorBackground.test.js +1 -1
- package/lib/services/errors/errorHandler.d.ts +4 -2
- package/lib/services/errors/errorHandler.js +27 -14
- package/lib/services/errors/errorHandler.test.js +148 -0
- package/lib/services/errors/errorRetryHandler.d.ts +2 -0
- package/lib/services/errors/errorRetryHandler.js +14 -0
- package/lib/services/errors/errorRetryHandler.test.d.ts +1 -0
- package/lib/services/errors/errorRetryHandler.test.js +62 -0
- package/lib/services/errors/errorText.js +8 -5
- package/lib/services/errors/errorText.test.js +3 -3
- package/lib/services/infoPanel/infoPanel.d.ts +3 -0
- package/lib/services/infoPanel/infoPanel.js +35 -0
- package/lib/services/infoPanel/infoPanel.test.d.ts +1 -0
- package/lib/services/infoPanel/infoPanel.test.js +70 -0
- package/lib/services/keyboardHandlers/resolvekeypress.js +11 -1
- package/lib/services/keyboardHandlers/resolvekeypress.test.js +6 -2
- package/lib/services/nicamHandlers/nicamhandler.d.ts +1 -0
- package/lib/services/nicamHandlers/nicamhandler.js +2 -1
- package/lib/services/nicamHandlers/nicamhandler.test.js +2 -2
- package/lib/services/npoPlayerAPI/npoPlayerAPI.d.ts +8 -2
- package/lib/services/npoPlayerAPI/npoPlayerAPI.js +25 -12
- package/lib/services/npoPlayerAPI/playerModules.d.ts +1 -0
- package/lib/services/npoPlayerAPI/playerModules.js +46 -0
- package/lib/services/preferences/handlePreferences.js +9 -4
- package/lib/services/preferences/handlePreferences.test.js +53 -17
- package/lib/services/segmentHandlers/addSegmentEventListeners.test.js +1 -1
- package/lib/services/segmentHandlers/isSegmentInBounds.d.ts +2 -0
- package/lib/services/segmentHandlers/isSegmentInBounds.js +5 -0
- package/lib/services/segmentHandlers/isSegmentInBounds.test.d.ts +1 -0
- package/lib/services/segmentHandlers/isSegmentInBounds.test.js +27 -0
- package/lib/services/services.d.ts +5 -2
- package/lib/services/services.js +15 -2
- package/lib/services/streamFetchHandler/fetchStream.js +5 -4
- package/lib/services/streamFetchHandler/fetchstream.test.js +25 -3
- package/lib/services/streamoptionsHandlers/streamOptionsHandler.js +11 -9
- package/lib/services/streamoptionsHandlers/streamOptionsHandler.test.js +14 -2
- package/lib/services/trackingHandlers/eventBinding.js +48 -33
- package/lib/services/trackingHandlers/eventBinding.test.js +57 -1
- package/lib/services/trackingHandlers/playerTrackerStart.js +1 -1
- package/lib/services/uiHandlers/uiVisiblityHandler.js +6 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.test.js +0 -9
- package/lib/src/js/markers/updateLiveMarkers.d.ts +7 -2
- package/lib/src/js/playeractions/handlers/mediasessionactions.d.ts +7 -2
- package/lib/src/js/playeractions/handlers/processplayerconfig.d.ts +1 -1
- package/lib/src/js/playeractions/handlers/processsourceconfig.d.ts +11 -2
- package/lib/src/js/playeractions/handlers/removereplayclass.d.ts +1 -1
- package/lib/src/js/settings/localization.d.ts +1 -0
- package/lib/src/js/utilities/utilities.jwt.d.ts +2 -0
- package/lib/src/npoplayer.d.ts +6 -5
- package/lib/src/services/chapterHandlers/chapterHandler.d.ts +35 -0
- package/lib/src/services/errors/errorHandler.d.ts +4 -2
- package/lib/src/services/errors/errorRetryHandler.d.ts +2 -0
- package/lib/src/services/errors/errorRetryHandler.test.d.ts +1 -0
- package/lib/src/services/infoPanel/infoPanel.d.ts +3 -0
- package/lib/src/services/infoPanel/infoPanel.test.d.ts +1 -0
- package/lib/src/services/nicamHandlers/nicamhandler.d.ts +1 -0
- package/lib/src/services/npoPlayerAPI/npoPlayerAPI.d.ts +8 -2
- package/lib/src/services/npoPlayerAPI/playerModules.d.ts +1 -0
- package/lib/src/services/segmentHandlers/isSegmentInBounds.d.ts +2 -0
- package/lib/src/services/segmentHandlers/isSegmentInBounds.test.d.ts +1 -0
- package/lib/src/services/services.d.ts +5 -2
- package/lib/src/types/events.d.ts +1 -1
- package/lib/src/types/interfaces.d.ts +39 -43
- package/lib/src/ui/components/adbutton.d.ts +3 -6
- package/lib/src/ui/components/adlabel.d.ts +3 -6
- package/lib/src/ui/components/audio/controlbar.d.ts +2 -2
- package/lib/src/ui/components/buttons.d.ts +18 -11
- package/lib/src/ui/components/ctabar.d.ts +4 -10
- package/lib/src/ui/components/infopanel/infopanel.d.ts +3 -0
- package/lib/src/ui/components/infopanel/togglebutton.d.ts +3 -0
- package/lib/src/ui/components/playnext.d.ts +3 -9
- package/lib/src/ui/components/seekbar.d.ts +2 -3
- package/lib/src/ui/components/settingspanel.d.ts +2 -3
- package/lib/src/ui/components/titlebar.d.ts +2 -2
- package/lib/src/ui/handlers/domhandlers.d.ts +2 -2
- package/lib/src/ui/handlers/listboxhandlers.d.ts +18 -4
- package/lib/src/ui/handlers/playnextscreen.d.ts +6 -2
- package/lib/src/ui/uicontainer.d.ts +1 -2
- package/lib/tests/jest.setup-files-after-env.d.ts +0 -0
- package/lib/tests/jest.setup-files-after-env.js +6 -0
- package/lib/tests/jest.setup-tests.d.ts +1 -0
- package/lib/tests/jest.setup-tests.js +2 -0
- package/lib/tests/mocks/mockNpoplayer.js +27 -44
- package/lib/tests/mocks/mockPlayerAPI.d.ts +1 -1
- package/lib/tests/mocks/mockPlayerAPI.js +15 -1
- package/lib/tests/mocks/mockPlayerUi.d.ts +64 -0
- package/lib/tests/mocks/mockPlayerUi.js +251 -0
- package/lib/tests/mocks/playerContextMock.d.ts +3 -66
- package/lib/tests/mocks/playerContextMock.js +34 -7
- package/lib/types/events.d.ts +1 -1
- package/lib/types/events.js +1 -1
- package/lib/types/interfaces.d.ts +39 -43
- package/lib/types/interfaces.js +0 -27
- package/lib/ui/components/adbutton.d.ts +3 -6
- package/lib/ui/components/adbutton.js +2 -1
- package/lib/ui/components/adlabel.d.ts +3 -6
- package/lib/ui/components/adlabel.js +2 -1
- package/lib/ui/components/audio/controlbar.d.ts +2 -2
- package/lib/ui/components/audio/controlbar.js +6 -6
- package/lib/ui/components/buttons.d.ts +18 -11
- package/lib/ui/components/buttons.js +44 -26
- package/lib/ui/components/controlbar.js +13 -9
- package/lib/ui/components/ctabar.d.ts +4 -10
- package/lib/ui/components/ctabar.js +8 -7
- package/lib/ui/components/infopanel/infopanel.d.ts +3 -0
- package/lib/ui/components/infopanel/infopanel.js +40 -0
- package/lib/ui/components/infopanel/togglebutton.d.ts +3 -0
- package/lib/ui/components/infopanel/togglebutton.js +18 -0
- package/lib/ui/components/playnext.d.ts +3 -9
- package/lib/ui/components/playnext.js +3 -3
- package/lib/ui/components/seekbar.d.ts +2 -3
- package/lib/ui/components/seekbar.js +7 -3
- package/lib/ui/components/settingspanel.d.ts +2 -3
- package/lib/ui/components/settingspanel.js +79 -53
- package/lib/ui/components/titlebar.d.ts +2 -2
- package/lib/ui/components/titlebar.js +2 -1
- package/lib/ui/components/topbar.js +8 -5
- package/lib/ui/components/verticalvideo/controlbar.js +5 -2
- package/lib/ui/components/verticalvideo/settingspanel.js +9 -5
- package/lib/ui/handlers/accessibilityhandler.js +11 -22
- package/lib/ui/handlers/accessibilityhandler.test.js +25 -34
- package/lib/ui/handlers/domhandlers.d.ts +2 -2
- package/lib/ui/handlers/listboxhandlers.d.ts +18 -4
- package/lib/ui/handlers/listboxhandlers.js +5 -3
- package/lib/ui/handlers/playnextscreen.d.ts +6 -2
- package/lib/ui/handlers/playnextscreen.js +4 -4
- package/lib/ui/handlers/playnextscreen.test.js +15 -3
- package/lib/ui/uicontainer.d.ts +1 -2
- package/lib/ui/uicontainer.js +24 -8
- package/lib/ui/uicontainer.test.js +6 -5
- package/package.json +7 -9
- package/src/style/components/_advert.scss +0 -4
- package/src/style/components/_buffering.scss +18 -22
- package/src/style/components/_controlbars.scss +0 -4
- package/src/style/components/_icons.scss +18 -4
- package/src/style/components/_infopanel.scss +99 -0
- package/src/style/components/_nicam.scss +6 -2
- package/src/style/components/_seekbarthumbnail.scss +5 -0
- package/src/style/components/_settingspanel.scss +1 -1
- package/src/style/components/_subtitles.scss +0 -1
- package/src/style/components/_textbuttons.scss +30 -1
- package/src/style/components/_volumeslider.scss +0 -1
- package/src/style/components/audio/_bottombar.scss +6 -0
- package/src/style/components/audio/_metadata.scss +25 -9
- package/src/style/components/audio/_topbar.scss +6 -1
- package/src/style/npoplayer.css +166 -83
- package/src/style/npoplayer.scss +10 -2
- package/src/style/variants/_player-audio-only.scss +32 -0
- package/src/style/variants/_player-base.scss +5 -1
- package/src/style/variants/_player-large.scss +3 -3
- package/src/style/variants/_player-medium.scss +5 -1
- package/src/style/variants/_player-small.scss +6 -1
- package/src/style/vars/_colors.scss +1 -1
- package/src/style/vars/_icons.scss +5 -4
- package/src/style/vars/_z-index.scss +1 -1
- package/lib/npoplayer-bridge.test.js +0 -24
- package/lib/src/ui/components/nativemobile/buttons.d.ts +0 -30
- package/lib/src/ui/components/nativemobile/controlbar.d.ts +0 -3
- package/lib/src/ui/components/nativemobile/ctabar.d.ts +0 -11
- package/lib/src/ui/components/nativemobile/titlebar.d.ts +0 -2
- package/lib/src/ui/components/nativemobile/topbar.d.ts +0 -3
- package/lib/src/ui/nativemobileuicontainer.d.ts +0 -5
- package/lib/src/ui/nativemobileuifactory.d.ts +0 -3
- package/lib/src/ui/nativemobileuifactory.test.d.ts +0 -1
- package/lib/ui/components/nativemobile/buttons.d.ts +0 -30
- package/lib/ui/components/nativemobile/buttons.js +0 -233
- package/lib/ui/components/nativemobile/controlbar.d.ts +0 -3
- package/lib/ui/components/nativemobile/controlbar.js +0 -43
- package/lib/ui/components/nativemobile/ctabar.d.ts +0 -11
- package/lib/ui/components/nativemobile/ctabar.js +0 -10
- package/lib/ui/components/nativemobile/titlebar.d.ts +0 -2
- package/lib/ui/components/nativemobile/titlebar.js +0 -7
- package/lib/ui/components/nativemobile/topbar.d.ts +0 -3
- package/lib/ui/components/nativemobile/topbar.js +0 -23
- package/lib/ui/nativemobileuicontainer.d.ts +0 -5
- package/lib/ui/nativemobileuicontainer.js +0 -42
- package/lib/ui/nativemobileuifactory.d.ts +0 -3
- package/lib/ui/nativemobileuifactory.js +0 -112
- package/lib/ui/nativemobileuifactory.test.d.ts +0 -1
- package/lib/ui/nativemobileuifactory.test.js +0 -64
- package/src/style/variants/_player-native-mobile.scss +0 -13
- /package/lib/{npoplayer-bridge.test.d.ts → services/errors/errorHandler.test.d.ts} +0 -0
- /package/lib/src/{npoplayer-bridge.test.d.ts → services/errors/errorHandler.test.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+

|
|
2
3
|
|
|
3
4
|
# NPO Player
|
|
4
5
|
|
|
@@ -11,7 +12,7 @@ Extensive and up-to-date documentation is available at https://docs.npoplayer.nl
|
|
|
11
12
|
Code quality is analysed by SonarCloud. The project can be found at https://sonarcloud.io/project/overview?id=NPOstart_npo-player
|
|
12
13
|
|
|
13
14
|
# Changelog
|
|
14
|
-
Current version: v1.
|
|
15
|
+
Current version: v1.28.0
|
|
15
16
|
|
|
16
17
|
The changelog is available at https://docs.npoplayer.nl/implementation/web/changelog/
|
|
17
18
|
|
|
@@ -20,8 +21,4 @@ The changelog is available at https://docs.npoplayer.nl/implementation/web/chang
|
|
|
20
21
|
MIT
|
|
21
22
|
|
|
22
23
|
[JWT.IO - JSON Web Tokens Introduction]: https://jwt.io/introduction
|
|
23
|
-
[self generated JWT]: https://www.npmjs.com/package/jsonwebtoken
|
|
24
|
-
|
|
25
|
-
## Native mobile development
|
|
26
|
-
|
|
27
|
-
For detailed information on the JavaScript player integration for ios and Android, including custom message handling, UI customization, and interaction with native mobile SDKs, see the [Bitmovin Player Integration for Native Mobile SDKs](src/js/ui/README.md) located in the `src/js/ui` directory.
|
|
24
|
+
[self generated JWT]: https://www.npmjs.com/package/jsonwebtoken
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import { PlayerAPI } from 'bitmovin-player';
|
|
1
|
+
import { PlayerAPI } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
2
|
import { UIManager } from 'bitmovin-player-ui';
|
|
3
3
|
import { TimeLineMarker } from 'types/interfaces';
|
|
4
|
-
export declare function updateLiveMarkers(timeLineMarkers
|
|
4
|
+
export declare function updateLiveMarkers({ timeLineMarkers, player, uiManager, autoFillTimeLineMarkerDuration }: {
|
|
5
|
+
timeLineMarkers: TimeLineMarker[];
|
|
6
|
+
player: PlayerAPI;
|
|
7
|
+
uiManager: UIManager;
|
|
8
|
+
autoFillTimeLineMarkerDuration: boolean;
|
|
9
|
+
}): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function updateLiveMarkers(timeLineMarkers, player, uiManager, autoFillTimeLineMarkerDuration) {
|
|
1
|
+
export function updateLiveMarkers({ timeLineMarkers, player, uiManager, autoFillTimeLineMarkerDuration }) {
|
|
2
2
|
if (!player || !uiManager) {
|
|
3
3
|
console.error('Player or UIManager is null');
|
|
4
4
|
return;
|
|
@@ -6,14 +6,21 @@ export function updateLiveMarkers(timeLineMarkers, player, uiManager, autoFillTi
|
|
|
6
6
|
removeAllMarkers(uiManager);
|
|
7
7
|
const currentTimeEpoch = Math.floor(Date.now() / 1000);
|
|
8
8
|
timeLineMarkers.sort((a, b) => a.time - b.time);
|
|
9
|
-
const relativeTimeMarkers = timeLineMarkers.map((marker, index) => transformMarker(
|
|
9
|
+
const relativeTimeMarkers = timeLineMarkers.map((marker, index) => transformMarker({
|
|
10
|
+
marker,
|
|
11
|
+
index,
|
|
12
|
+
timeLineMarkers,
|
|
13
|
+
currentTimeEpoch,
|
|
14
|
+
player,
|
|
15
|
+
autoFillTimeLineMarkerDuration
|
|
16
|
+
}));
|
|
10
17
|
for (const marker of relativeTimeMarkers) {
|
|
11
18
|
uiManager?.addTimelineMarker(marker);
|
|
12
19
|
}
|
|
13
20
|
}
|
|
14
|
-
function transformMarker(marker, index, timeLineMarkers, currentTimeEpoch, player, autoFillTimeLineMarkerDuration) {
|
|
21
|
+
function transformMarker({ marker, index, timeLineMarkers, currentTimeEpoch, player, autoFillTimeLineMarkerDuration }) {
|
|
15
22
|
const DVR_WINDOW_LENGTH = Math.abs(player.getMaxTimeShift());
|
|
16
|
-
let duration = marker.duration
|
|
23
|
+
let duration = marker.duration ?? 0;
|
|
17
24
|
let startTimeRelativeToCurrent = marker.time - currentTimeEpoch;
|
|
18
25
|
if (autoFillTimeLineMarkerDuration) {
|
|
19
26
|
duration =
|
|
@@ -9,7 +9,7 @@ jest.mock('bitmovin-player-ui', () => {
|
|
|
9
9
|
}))
|
|
10
10
|
};
|
|
11
11
|
});
|
|
12
|
-
jest.mock('bitmovin-player', () => ({
|
|
12
|
+
jest.mock('bitmovin-player/modules/bitmovinplayer-core', () => ({
|
|
13
13
|
PlayerAPI: jest.fn()
|
|
14
14
|
}));
|
|
15
15
|
describe('updateLiveMarkers', () => {
|
|
@@ -27,7 +27,12 @@ describe('updateLiveMarkers', () => {
|
|
|
27
27
|
{ time: 3000, title: 'Marker 2' },
|
|
28
28
|
{ time: 1000, title: 'Marker 1' }
|
|
29
29
|
];
|
|
30
|
-
updateLiveMarkers(
|
|
30
|
+
updateLiveMarkers({
|
|
31
|
+
timeLineMarkers,
|
|
32
|
+
player,
|
|
33
|
+
uiManager,
|
|
34
|
+
autoFillTimeLineMarkerDuration: true
|
|
35
|
+
});
|
|
31
36
|
expect(uiManager.getTimelineMarkers).toHaveBeenCalled();
|
|
32
37
|
expect(uiManager.removeTimelineMarker).toHaveBeenCalledTimes(0);
|
|
33
38
|
expect(uiManager.addTimelineMarker).toHaveBeenCalledTimes(2);
|
|
@@ -46,7 +51,12 @@ describe('updateLiveMarkers', () => {
|
|
|
46
51
|
;
|
|
47
52
|
uiManager.getTimelineMarkers.mockReturnValue([{ time: 2000, title: 'Existing Marker' }]);
|
|
48
53
|
const timeLineMarkers = [{ time: 1000, title: 'New Marker' }];
|
|
49
|
-
updateLiveMarkers(
|
|
54
|
+
updateLiveMarkers({
|
|
55
|
+
timeLineMarkers,
|
|
56
|
+
player,
|
|
57
|
+
uiManager,
|
|
58
|
+
autoFillTimeLineMarkerDuration: true
|
|
59
|
+
});
|
|
50
60
|
expect(uiManager.removeTimelineMarker).toHaveBeenCalledTimes(1);
|
|
51
61
|
expect(uiManager.addTimelineMarker).toHaveBeenCalledTimes(1);
|
|
52
62
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PlayerEvent } from 'bitmovin-player';
|
|
1
|
+
import { PlayerEvent } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
2
|
import { createPlayerContextMock, createMockNpoPlayerAPI } from '../../../../tests/mocks/playerContextMock';
|
|
3
3
|
import { handleStartOffset, shiftToProgramStart } from './handleoffsets';
|
|
4
4
|
describe('Test offset handling', () => {
|
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
import { PlayerAPI, SourceConfig } from 'bitmovin-player';
|
|
2
|
-
|
|
1
|
+
import { PlayerAPI, SourceConfig } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
|
+
import { StreamObject } from 'types/interfaces';
|
|
3
|
+
export declare function setupMediaSessionActionHandlers({ player, sourceConfig, streamObject }: {
|
|
4
|
+
player: PlayerAPI;
|
|
5
|
+
sourceConfig: SourceConfig;
|
|
6
|
+
streamObject: StreamObject;
|
|
7
|
+
}): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PlayerEvent } from 'bitmovin-player';
|
|
2
|
-
export function setupMediaSessionActionHandlers(player, sourceConfig,
|
|
1
|
+
import { PlayerEvent } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
|
+
export function setupMediaSessionActionHandlers({ player, sourceConfig, streamObject }) {
|
|
3
3
|
function handlePlaying() {
|
|
4
4
|
player.off(PlayerEvent.Playing, handlePlaying);
|
|
5
5
|
if (!('mediaSession' in navigator)) {
|
|
@@ -50,12 +50,12 @@ export function setupMediaSessionActionHandlers(player, sourceConfig, _streamObj
|
|
|
50
50
|
function setMediaSessionMetadata() {
|
|
51
51
|
const metadata = {
|
|
52
52
|
title: sourceConfig.title,
|
|
53
|
-
artist:
|
|
53
|
+
artist: streamObject.metadata.broadcaster || ''
|
|
54
54
|
};
|
|
55
|
-
if (sourceConfig.poster ||
|
|
55
|
+
if (sourceConfig.poster || streamObject.metadata.poster) {
|
|
56
56
|
metadata.artwork = [
|
|
57
57
|
{
|
|
58
|
-
src: sourceConfig.poster
|
|
58
|
+
src: sourceConfig.poster ?? streamObject.metadata.poster ?? ''
|
|
59
59
|
}
|
|
60
60
|
];
|
|
61
61
|
}
|
|
@@ -67,7 +67,7 @@ export function setupMediaSessionActionHandlers(player, sourceConfig, _streamObj
|
|
|
67
67
|
{
|
|
68
68
|
action: 'seekbackward',
|
|
69
69
|
handler: (details) => {
|
|
70
|
-
const skipTime = details.seekOffset
|
|
70
|
+
const skipTime = details.seekOffset ?? defaultSkipTime;
|
|
71
71
|
player.seek(Math.max(player.getCurrentTime() - skipTime, 0));
|
|
72
72
|
updatePositionState();
|
|
73
73
|
}
|
|
@@ -75,7 +75,7 @@ export function setupMediaSessionActionHandlers(player, sourceConfig, _streamObj
|
|
|
75
75
|
{
|
|
76
76
|
action: 'seekforward',
|
|
77
77
|
handler: (details) => {
|
|
78
|
-
const skipTime = details.seekOffset
|
|
78
|
+
const skipTime = details.seekOffset ?? defaultSkipTime;
|
|
79
79
|
player.seek(Math.min(player.getCurrentTime() + skipTime, player.getDuration()));
|
|
80
80
|
updatePositionState();
|
|
81
81
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { type PlayerConfig } from 'bitmovin-player';
|
|
1
|
+
import { type PlayerConfig } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
2
|
import NpoPlayer from 'npoplayer';
|
|
3
3
|
export declare function processPlayerConfig(npoPlayer: NpoPlayer, playerConfig: PlayerConfig): PlayerConfig;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LogLevel } from 'bitmovin-player';
|
|
1
|
+
import { LogLevel } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
2
|
import { isSafari } from '../../utilities/utilities.user-agent';
|
|
3
3
|
export function processPlayerConfig(npoPlayer, playerConfig) {
|
|
4
4
|
const processedConfig = playerConfig;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LogLevel } from 'bitmovin-player';
|
|
1
|
+
import { LogLevel } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
2
|
import { isSafari } from '../../utilities/utilities.user-agent';
|
|
3
3
|
import { processPlayerConfig } from './processplayerconfig';
|
|
4
4
|
jest.mock('../../utilities/utilities.user-agent', () => ({
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { StreamObject, StreamOptions } from 'types/interfaces';
|
|
2
|
-
import { SourceConfig } from 'bitmovin-player';
|
|
2
|
+
import { SourceConfig } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
3
3
|
import { NpoPlayerServices } from '../../../services/services';
|
|
4
4
|
import { NPOTag } from '@npotag/tag';
|
|
5
5
|
export declare const getSubtitleLabels: (data: any) => string;
|
|
6
|
-
export declare function processSourceConfig(npoPlayerServices
|
|
6
|
+
export declare function processSourceConfig({ npoPlayerServices, source, _sourceConfig, _streamObject, drm, streamOptions, version, npoTagInstance }: {
|
|
7
|
+
npoPlayerServices: NpoPlayerServices;
|
|
8
|
+
source: string;
|
|
9
|
+
_sourceConfig: SourceConfig;
|
|
10
|
+
_streamObject: StreamObject;
|
|
11
|
+
drm: string | undefined;
|
|
12
|
+
streamOptions: StreamOptions;
|
|
13
|
+
version: string;
|
|
14
|
+
npoTagInstance: NPOTag | undefined;
|
|
15
|
+
}): Promise<SourceConfig>;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { HttpResponseType } from 'bitmovin-player';
|
|
1
|
+
import { HttpResponseType } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
2
|
import { npoCdnProviders } from '../../../services/cdnProviders/cdnProviders';
|
|
3
3
|
import { replaceSpecialCharacters } from '../../utilities/utilities.text';
|
|
4
4
|
import subtitleLabelMap from '../../../lang/subtitleLabels/nl.json';
|
|
5
|
-
async function setDrm(sourceConfig, drm,
|
|
5
|
+
async function setDrm({ sourceConfig, drm, streamObject, useWidevineServerCertificate }) {
|
|
6
6
|
const npoDrmGateway = 'https://npo-drm-gateway.samgcloud.nepworldwide.nl/authentication?custom_data=';
|
|
7
7
|
switch (drm) {
|
|
8
8
|
case 'fairplay': {
|
|
9
9
|
sourceConfig.drm = {
|
|
10
10
|
fairplay: {
|
|
11
11
|
certificateURL: 'https://fairplay.npo.nl/certificate/fairplay.cer',
|
|
12
|
-
LA_URL: npoDrmGateway +
|
|
12
|
+
LA_URL: npoDrmGateway + streamObject.stream.drmToken,
|
|
13
13
|
prepareMessage: (event) => {
|
|
14
14
|
return new Uint8Array(event.message);
|
|
15
15
|
},
|
|
16
16
|
prepareContentId: (url) => {
|
|
17
17
|
const link = document.createElement('a');
|
|
18
|
-
const trimmedUrl = [...url].filter((char) =>
|
|
18
|
+
const trimmedUrl = [...url].filter((char) => char.codePointAt(0) !== undefined).join('');
|
|
19
19
|
link.href = trimmedUrl.replace('T', '');
|
|
20
20
|
return link.hostname;
|
|
21
21
|
},
|
|
@@ -38,7 +38,7 @@ async function setDrm(sourceConfig, drm, _streamObject, useWidevineServerCertifi
|
|
|
38
38
|
try {
|
|
39
39
|
sourceConfig.drm = {
|
|
40
40
|
widevine: {
|
|
41
|
-
LA_URL: npoDrmGateway +
|
|
41
|
+
LA_URL: npoDrmGateway + streamObject.stream.drmToken,
|
|
42
42
|
audioRobustness: 'SW_SECURE_CRYPTO',
|
|
43
43
|
videoRobustness: 'SW_SECURE_CRYPTO',
|
|
44
44
|
serverCertificate: useWidevineServerCertificate
|
|
@@ -55,12 +55,16 @@ async function setDrm(sourceConfig, drm, _streamObject, useWidevineServerCertifi
|
|
|
55
55
|
case 'playready': {
|
|
56
56
|
sourceConfig.drm = {
|
|
57
57
|
playready: {
|
|
58
|
-
LA_URL: npoDrmGateway +
|
|
58
|
+
LA_URL: npoDrmGateway + streamObject.stream.drmToken
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
break;
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
+
sourceConfig.drm = {
|
|
65
|
+
...sourceConfig.drm,
|
|
66
|
+
immediateLicenseRequest: true
|
|
67
|
+
};
|
|
64
68
|
return sourceConfig;
|
|
65
69
|
}
|
|
66
70
|
async function getServerCertificate(url) {
|
|
@@ -74,9 +78,9 @@ export const getSubtitleLabels = function (data) {
|
|
|
74
78
|
const getQualityLabels = function (data) {
|
|
75
79
|
return data.height + 'p';
|
|
76
80
|
};
|
|
77
|
-
function setStreamProfile(sourceConfig, _sourceConfig,
|
|
78
|
-
const streamProfile =
|
|
79
|
-
const streamURL =
|
|
81
|
+
function setStreamProfile({ sourceConfig, _sourceConfig, streamObject }) {
|
|
82
|
+
const streamProfile = streamObject.stream.streamProfile;
|
|
83
|
+
const streamURL = streamObject.stream.streamURL;
|
|
80
84
|
const configMapping = {
|
|
81
85
|
hls: _sourceConfig.hls,
|
|
82
86
|
dash: _sourceConfig.dash,
|
|
@@ -101,7 +105,7 @@ function setStreamProfile(sourceConfig, _sourceConfig, _streamObject) {
|
|
|
101
105
|
}
|
|
102
106
|
return sourceConfig;
|
|
103
107
|
}
|
|
104
|
-
export async function processSourceConfig(npoPlayerServices, source, _sourceConfig
|
|
108
|
+
export async function processSourceConfig({ npoPlayerServices, source, _sourceConfig, _streamObject, drm, streamOptions, version, npoTagInstance }) {
|
|
105
109
|
let sourceConfig = {};
|
|
106
110
|
sourceConfig.title = _sourceConfig.title
|
|
107
111
|
? replacePlaceholders(_sourceConfig.title, _streamObject.metadata)
|
|
@@ -109,7 +113,11 @@ export async function processSourceConfig(npoPlayerServices, source, _sourceConf
|
|
|
109
113
|
sourceConfig.description = _sourceConfig.description
|
|
110
114
|
? replacePlaceholders(_sourceConfig.description, _streamObject.metadata)
|
|
111
115
|
: _streamObject.metadata.description ?? '';
|
|
112
|
-
sourceConfig.poster = decidePoster(
|
|
116
|
+
sourceConfig.poster = decidePoster({
|
|
117
|
+
streamObject: _streamObject,
|
|
118
|
+
sourceConfig: _sourceConfig,
|
|
119
|
+
streamOptions
|
|
120
|
+
});
|
|
113
121
|
sourceConfig.metadata = {
|
|
114
122
|
title: sourceConfig.title,
|
|
115
123
|
description: sourceConfig.description,
|
|
@@ -139,8 +147,13 @@ export async function processSourceConfig(npoPlayerServices, source, _sourceConf
|
|
|
139
147
|
_sourceConfig.thumbnailTrack ?? _streamObject.assets.scrubbingThumbnail
|
|
140
148
|
? { url: _streamObject.assets.scrubbingThumbnail }
|
|
141
149
|
: undefined;
|
|
142
|
-
sourceConfig = setStreamProfile(sourceConfig, _sourceConfig, _streamObject);
|
|
143
|
-
sourceConfig = await setDrm(
|
|
150
|
+
sourceConfig = setStreamProfile({ sourceConfig, _sourceConfig, streamObject: _streamObject });
|
|
151
|
+
sourceConfig = await setDrm({
|
|
152
|
+
sourceConfig,
|
|
153
|
+
drm,
|
|
154
|
+
streamObject: _streamObject,
|
|
155
|
+
useWidevineServerCertificate: streamOptions.useWidevineServerCertificate ?? true
|
|
156
|
+
});
|
|
144
157
|
const streamSource = _streamObject.stream.streamURL;
|
|
145
158
|
let cdnString = streamSource;
|
|
146
159
|
if (streamSource.startsWith('file:///')) {
|
|
@@ -184,15 +197,15 @@ export async function processSourceConfig(npoPlayerServices, source, _sourceConf
|
|
|
184
197
|
sourceConfig.metadata.jwt = source;
|
|
185
198
|
sourceConfig.metadata.streamLinkAsJsonString = JSON.stringify(_streamObject);
|
|
186
199
|
sourceConfig.metadata.npoTagSession = String(npoTagInstance?.getSerializedSessionInfo());
|
|
187
|
-
sourceConfig.metadata.hasPreroll = _streamObject.metadata.hasPreroll
|
|
188
|
-
sourceConfig.metadata.prerollUrl = _streamObject.assets.preroll
|
|
200
|
+
sourceConfig.metadata.hasPreroll = _streamObject.metadata.hasPreroll ?? 'false';
|
|
201
|
+
sourceConfig.metadata.prerollUrl = _streamObject.assets.preroll ?? '';
|
|
189
202
|
sourceConfig.metadata.onScreenDebug = 'false';
|
|
190
203
|
sourceConfig.metadata.frameworkLevelDebug = 'false';
|
|
191
|
-
sourceConfig.metadata.description = sourceConfig.description
|
|
204
|
+
sourceConfig.metadata.description = sourceConfig.description ?? '';
|
|
192
205
|
sourceConfig.metadata.avType = npoPlayerServices.getAVType(_streamObject.stream.avType);
|
|
193
206
|
return sourceConfig;
|
|
194
207
|
}
|
|
195
|
-
function decidePoster(streamObject, sourceConfig, streamOptions) {
|
|
208
|
+
function decidePoster({ streamObject, sourceConfig, streamOptions }) {
|
|
196
209
|
if (sourceConfig.poster) {
|
|
197
210
|
return replaceSpecialCharacters(sourceConfig.poster);
|
|
198
211
|
}
|
|
@@ -208,7 +221,11 @@ function replacePlaceholders(template, metadata) {
|
|
|
208
221
|
return template.replace(/{([^{}]*)}/g, (match, key) => {
|
|
209
222
|
const value = metadata[key];
|
|
210
223
|
if (Array.isArray(value)) {
|
|
211
|
-
return value
|
|
224
|
+
return value
|
|
225
|
+
.map((item) => {
|
|
226
|
+
return typeof item === 'string' ? item.trim() : String(item);
|
|
227
|
+
})
|
|
228
|
+
.join(', ');
|
|
212
229
|
}
|
|
213
230
|
return value === undefined ? '' : String(value);
|
|
214
231
|
});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { PlayerAPI } from 'bitmovin-player';
|
|
1
|
+
import { PlayerAPI } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
2
2
|
export declare function removeReplayClass(player: PlayerAPI | undefined): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import '@testing-library/jest-dom';
|
|
2
2
|
import { removeReplayClass } from './removereplayclass';
|
|
3
|
-
import { PlayerEvent } from 'bitmovin-player';
|
|
3
|
+
import { PlayerEvent } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
4
4
|
describe('removeReplayClass', () => {
|
|
5
5
|
let mockPlayer;
|
|
6
6
|
let mockPlayerContainer;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export declare const convertBase64ToObject: (value: string) => Record<string, any>;
|
|
2
2
|
export declare const convertJwtToBase64: (jwt: string) => string;
|
|
3
3
|
export declare function isJWTToken(token: string): boolean;
|
|
4
|
+
export declare function getJwtIat(jwt: string): number;
|
|
5
|
+
export declare function isJwtFresh(jwt: string, maxAgeSeconds?: number): boolean;
|
|
@@ -20,3 +20,25 @@ export function isJWTToken(token) {
|
|
|
20
20
|
const JWT_REGEX = /^(?:[\w=-]+\.){2}[\w+./=-]+$/;
|
|
21
21
|
return JWT_REGEX.test(token);
|
|
22
22
|
}
|
|
23
|
+
export function getJwtIat(jwt) {
|
|
24
|
+
const parts = jwt.split('.');
|
|
25
|
+
if (parts.length !== 3) {
|
|
26
|
+
throw new Error('Invalid JWT format');
|
|
27
|
+
}
|
|
28
|
+
const payloadJson = Buffer.from(parts[1], 'base64').toString('utf8');
|
|
29
|
+
const payload = JSON.parse(payloadJson);
|
|
30
|
+
if (typeof payload.iat !== 'number') {
|
|
31
|
+
throw new TypeError('JWT `iat` claim missing or not a number');
|
|
32
|
+
}
|
|
33
|
+
return payload.iat;
|
|
34
|
+
}
|
|
35
|
+
export function isJwtFresh(jwt, maxAgeSeconds = 3600) {
|
|
36
|
+
try {
|
|
37
|
+
const issuedAt = getJwtIat(jwt);
|
|
38
|
+
const ageSeconds = Date.now() / 1000 - issuedAt;
|
|
39
|
+
return ageSeconds <= maxAgeSeconds;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { convertMsToSeconds } from './utilities.time';
|
|
2
2
|
export function getStreamDurationInSeconds(params) {
|
|
3
3
|
const { duration, durationIsInMs } = params;
|
|
4
|
-
if (duration === undefined || duration === Number.POSITIVE_INFINITY)
|
|
4
|
+
if (duration === undefined || duration === Number.POSITIVE_INFINITY) {
|
|
5
5
|
return -1;
|
|
6
|
-
|
|
6
|
+
}
|
|
7
|
+
if (durationIsInMs) {
|
|
8
|
+
return convertMsToSeconds(Number(duration));
|
|
9
|
+
}
|
|
10
|
+
else if (Number.isFinite(+duration)) {
|
|
11
|
+
return Number(duration);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return -1;
|
|
15
|
+
}
|
|
7
16
|
}
|
|
8
17
|
export function validatePrid(prid) {
|
|
9
18
|
return prid !== '' && prid !== undefined ? prid : 'unknown';
|
|
@@ -12,7 +12,7 @@ export async function isMediaUrl(url) {
|
|
|
12
12
|
return false;
|
|
13
13
|
try {
|
|
14
14
|
const response = await fetch(url, { method: 'HEAD' });
|
|
15
|
-
const header = response.headers.get('Content-Type')
|
|
15
|
+
const header = response.headers.get('Content-Type') ?? '';
|
|
16
16
|
return supportedMediaTypes.some((mediaType) => header.startsWith(mediaType));
|
|
17
17
|
}
|
|
18
18
|
catch (error) {
|
|
@@ -25,5 +25,5 @@ export function isUrl(url) {
|
|
|
25
25
|
return URL_REGEX.test(url);
|
|
26
26
|
}
|
|
27
27
|
export const removeTrailingSlash = (url) => {
|
|
28
|
-
return url.
|
|
28
|
+
return url.endsWith('/') ? url.slice(0, -1) : url;
|
|
29
29
|
};
|
|
@@ -17,7 +17,7 @@ export function logVersion(version) {
|
|
|
17
17
|
\`╝╠╠╠╠╠╩\`
|
|
18
18
|
\`╙╙╙
|
|
19
19
|
`;
|
|
20
|
-
const COLOR_CODE = '#
|
|
20
|
+
const COLOR_CODE = '#f56A00';
|
|
21
21
|
const TITLE = 'NPO Player';
|
|
22
22
|
const TITLE_STYLE = `font-size: 24px; font-weight: bold; color: ${COLOR_CODE}; padding: 2px 4px;`;
|
|
23
23
|
const VERSION_STRING = 'v' + String(version);
|
|
@@ -21,6 +21,6 @@ describe('logVersion', () => {
|
|
|
21
21
|
\`╝╠╠╠╠╠╩\`
|
|
22
22
|
\`╙╙╙
|
|
23
23
|
`;
|
|
24
|
-
expect(logSpy).toHaveBeenCalledWith(`%c${ASCII_ART}%cNPO Player %cv1.0.0`, 'color: #
|
|
24
|
+
expect(logSpy).toHaveBeenCalledWith(`%c${ASCII_ART}%cNPO Player %cv1.0.0`, 'color: #f56A00; background-color: rgb(11, 28, 54);', 'font-size: 24px; font-weight: bold; color: #f56A00; padding: 2px 4px;', 'font-size: 24px; font-weight: bold; padding: 2px 4px;');
|
|
25
25
|
});
|
|
26
26
|
});
|
package/lib/lang/nl.json
CHANGED
|
@@ -65,12 +65,13 @@
|
|
|
65
65
|
"connectingTo": "Maakt verbinding met <strong>{castDeviceName}</strong>...",
|
|
66
66
|
"watermarkLink": "Link to Homepage",
|
|
67
67
|
"controlBar": "Video speler bedieningselementen",
|
|
68
|
+
"controlBar.bottom": "Tijdlijn en navigatie video speler",
|
|
68
69
|
"player": "Video speler",
|
|
69
70
|
"videoPlayer": "Video speler",
|
|
70
71
|
"audioPlayer": "Audio speler",
|
|
71
72
|
"seekBar": "Video tijdlijn",
|
|
72
73
|
"seekBar.value": "Waarde",
|
|
73
74
|
"seekBar.timeshift": "Timeshift",
|
|
74
|
-
"seekBar.durationText": "
|
|
75
|
+
"seekBar.durationText": "van",
|
|
75
76
|
"segment.unplayableTitle": "Niet beschikbaar"
|
|
76
77
|
}
|
package/lib/npoplayer.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { NpoPlayerServices } from './services/services';
|
|
2
2
|
import { type StreamTracker, type NPOTag, type PageTracker } from '@npotag/tag';
|
|
3
3
|
import { type InitialisationProps } from '@npotag/tag/dist/types/src/npoTag';
|
|
4
|
-
import { type PlayerAPI, type PlayerConfig, type SourceConfig } from 'bitmovin-player';
|
|
4
|
+
import { type PlayerAPI, type PlayerConfig, type SourceConfig } from 'bitmovin-player/modules/bitmovinplayer-core';
|
|
5
5
|
import { UIManager } from 'bitmovin-player-ui';
|
|
6
6
|
import { LogEmitter } from './types/classes';
|
|
7
7
|
import { type DRMProfile, type ApiPayload, type NPOTagObject, type StreamObject, type StreamOptions, type UIComponents, type TimeLineMarker, type PlayerContext, type EventListeners, NpoPlayerUIVariants } from './types/interfaces';
|
|
8
|
+
import { ChapterHandler } from './services/chapterHandlers/chapterHandler';
|
|
8
9
|
export { type PlayerConfig, type InitialisationProps, type NPOTagObject, type StreamOptions, NpoPlayerUIVariants };
|
|
9
10
|
export default class NpoPlayer {
|
|
10
11
|
playerConfig: PlayerConfig | undefined;
|
|
@@ -32,14 +33,14 @@ export default class NpoPlayer {
|
|
|
32
33
|
playerContext: PlayerContext | undefined;
|
|
33
34
|
npoPlayerServices: NpoPlayerServices;
|
|
34
35
|
eventListeners: EventListeners | undefined;
|
|
35
|
-
|
|
36
|
+
chapterHandler: ChapterHandler | undefined;
|
|
36
37
|
constructor(container: HTMLElement | {
|
|
37
38
|
container: HTMLElement;
|
|
38
39
|
playerConfig: PlayerConfig;
|
|
39
|
-
npoTag?: InitialisationProps
|
|
40
|
-
npoTagInstance?: NPOTag
|
|
40
|
+
npoTag?: InitialisationProps;
|
|
41
|
+
npoTagInstance?: NPOTag;
|
|
41
42
|
variant?: NpoPlayerUIVariants;
|
|
42
|
-
npoTagPageTracker?: PageTracker
|
|
43
|
+
npoTagPageTracker?: PageTracker;
|
|
43
44
|
}, playerConfig?: PlayerConfig | undefined, npoTag?: InitialisationProps | undefined, npoTagInstance?: NPOTag | undefined, variant?: NpoPlayerUIVariants, npoTagPageTracker?: PageTracker | undefined);
|
|
44
45
|
keydownHandler: (e: KeyboardEvent) => void;
|
|
45
46
|
initPlayer(_container: HTMLElement, playerConfig: PlayerConfig): void;
|