@npo/player 1.27.5 → 1.27.7
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/lib/js/playeractions/handlers/handleoffsets.js +15 -8
- package/lib/npoplayer.js +3 -3
- package/lib/package.json +1 -1
- package/lib/services/eventListenerHandlers/removeEventListeners.js +6 -2
- package/lib/services/eventListenerHandlers/removeEventListeners.test.js +20 -26
- package/lib/services/npoPlayerAPI/npoPlayerAPI.js +1 -0
- package/lib/services/streamoptionsHandlers/streamOptionsHandler.js +2 -1
- package/lib/services/streamoptionsHandlers/streamOptionsHandler.test.js +1 -1
- package/lib/services/trackingHandlers/playerTrackerStart.js +1 -1
- package/lib/services/trackingHandlers/playerTrackerStart.test.js +29 -12
- package/lib/src/types/interfaces.d.ts +6 -2
- package/lib/types/interfaces.d.ts +6 -2
- package/package.json +1 -1
|
@@ -8,16 +8,23 @@ export function handleStartOffset(playerContext, offset) {
|
|
|
8
8
|
return;
|
|
9
9
|
}
|
|
10
10
|
const seek = () => {
|
|
11
|
-
player.off(NpoPlayerEvent.Ready, seek);
|
|
12
|
-
player.off(NpoPlayerEvent.SourceLoaded, seek);
|
|
13
|
-
player.off(NpoPlayerEvent.AdBreakFinished, seek);
|
|
14
|
-
player.off(NpoPlayerEvent.AdError, seek);
|
|
15
11
|
player.seek(offset);
|
|
16
12
|
};
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
const handleStartOffsetCallbackOnReady = () => seek();
|
|
14
|
+
const handleStartOffsetCallbackOnSourceLoaded = () => seek();
|
|
15
|
+
const handleStartOffsetCallbackOnAdBreakFinished = () => seek();
|
|
16
|
+
const handleStartOffsetCallbackOnAdError = () => seek();
|
|
17
|
+
playerContext.player.on(NpoPlayerEvent.Ready, handleStartOffsetCallbackOnReady);
|
|
18
|
+
playerContext.player.on(NpoPlayerEvent.SourceLoaded, handleStartOffsetCallbackOnSourceLoaded);
|
|
19
|
+
playerContext.player.on(NpoPlayerEvent.AdBreakFinished, handleStartOffsetCallbackOnAdBreakFinished);
|
|
20
|
+
playerContext.player.on(NpoPlayerEvent.AdError, handleStartOffsetCallbackOnAdError);
|
|
21
|
+
playerContext.npoPlayer.eventListeners = {
|
|
22
|
+
...playerContext.npoPlayer.eventListeners,
|
|
23
|
+
handleStartOffsetCallbackOnReady,
|
|
24
|
+
handleStartOffsetCallbackOnSourceLoaded,
|
|
25
|
+
handleStartOffsetCallbackOnAdBreakFinished,
|
|
26
|
+
handleStartOffsetCallbackOnAdError
|
|
27
|
+
};
|
|
21
28
|
}
|
|
22
29
|
export function shiftToProgramStart(playerContext, timestamp) {
|
|
23
30
|
const { player } = playerContext;
|
package/lib/npoplayer.js
CHANGED
|
@@ -114,12 +114,12 @@ export default class NpoPlayer {
|
|
|
114
114
|
customData5: this.version
|
|
115
115
|
}
|
|
116
116
|
};
|
|
117
|
+
this.npoPlayerServices.handleStreamOptions(this.playerContext);
|
|
117
118
|
void this.playerContext.player.createUIManager(this.playerContext, this.variant);
|
|
118
119
|
await this.playerContext.player?.load(this.sourceConfig);
|
|
119
120
|
this.npoPlayerServices.startPlayerTracker({
|
|
120
121
|
playerContext: this.playerContext,
|
|
121
|
-
source: source
|
|
122
|
-
duration: undefined
|
|
122
|
+
source: source
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
else if (sourceIsJWTToken) {
|
|
@@ -158,6 +158,7 @@ export default class NpoPlayer {
|
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
160
|
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);
|
|
161
|
+
this.npoPlayerServices.handleStreamOptions(this.playerContext);
|
|
161
162
|
await this.npoPlayerServices.verifyDRM(this.playerContext, payload);
|
|
162
163
|
const streamDuration = _streamObject.metadata.duration;
|
|
163
164
|
this.npoPlayerServices.startPlayerTracker({
|
|
@@ -169,7 +170,6 @@ export default class NpoPlayer {
|
|
|
169
170
|
else {
|
|
170
171
|
await this.npoPlayerServices.handleError(this.playerContext, 500);
|
|
171
172
|
}
|
|
172
|
-
this.npoPlayerServices.handleStreamOptions(this.playerContext);
|
|
173
173
|
this.npoPlayerServices.setupNicamKijkwijzerIcons(this.playerContext);
|
|
174
174
|
setupMediaSessionActionHandlers(this.player, this.sourceConfig, this.streamObject);
|
|
175
175
|
this.hidePlayNextScreen();
|
package/lib/package.json
CHANGED
|
@@ -2,13 +2,17 @@ import { NpoPlayerEvent } from '../../types/events';
|
|
|
2
2
|
export const removeEventListeners = (playerContext) => {
|
|
3
3
|
const { eventListeners } = playerContext.npoPlayer;
|
|
4
4
|
if (eventListeners) {
|
|
5
|
-
const { segmentHandleTimeChangedCallback, segmentSeekFunctionCallback, liveStreamHandleTimeChangedCallback, adBreakFinishedCallback, adErrorCallback } = eventListeners;
|
|
5
|
+
const { segmentHandleTimeChangedCallback, segmentSeekFunctionCallback, liveStreamHandleTimeChangedCallback, adBreakFinishedCallback, adErrorCallback, handleStartOffsetCallbackOnReady, handleStartOffsetCallbackOnSourceLoaded, handleStartOffsetCallbackOnAdBreakFinished, handleStartOffsetCallbackOnAdError } = eventListeners;
|
|
6
6
|
const eventMapping = [
|
|
7
7
|
{ event: NpoPlayerEvent.TimeChanged, callback: liveStreamHandleTimeChangedCallback },
|
|
8
8
|
{ event: NpoPlayerEvent.TimeChanged, callback: segmentHandleTimeChangedCallback },
|
|
9
9
|
{ event: NpoPlayerEvent.Seek, callback: segmentSeekFunctionCallback },
|
|
10
10
|
{ event: NpoPlayerEvent.AdBreakFinished, callback: adBreakFinishedCallback },
|
|
11
|
-
{ event: NpoPlayerEvent.AdError, callback: adErrorCallback }
|
|
11
|
+
{ event: NpoPlayerEvent.AdError, callback: adErrorCallback },
|
|
12
|
+
{ event: NpoPlayerEvent.Ready, callback: handleStartOffsetCallbackOnReady },
|
|
13
|
+
{ event: NpoPlayerEvent.SourceLoaded, callback: handleStartOffsetCallbackOnSourceLoaded },
|
|
14
|
+
{ event: NpoPlayerEvent.AdBreakFinished, callback: handleStartOffsetCallbackOnAdBreakFinished },
|
|
15
|
+
{ event: NpoPlayerEvent.AdError, callback: handleStartOffsetCallbackOnAdError }
|
|
12
16
|
];
|
|
13
17
|
for (const { event, callback } of eventMapping) {
|
|
14
18
|
if (callback) {
|
|
@@ -7,36 +7,30 @@ describe('removeEventListeners', () => {
|
|
|
7
7
|
jest.clearAllMocks();
|
|
8
8
|
mockPlayerContext = createPlayerContextMock();
|
|
9
9
|
});
|
|
10
|
-
it('should remove
|
|
11
|
-
|
|
10
|
+
it('should remove all event listeners if they exist', () => {
|
|
11
|
+
const eventListeners = {
|
|
12
12
|
segmentHandleTimeChangedCallback: jest.fn(),
|
|
13
13
|
liveStreamHandleTimeChangedCallback: jest.fn(),
|
|
14
|
-
segmentSeekFunctionCallback: jest.fn()
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
});
|
|
22
|
-
it('should remove Seek event listener if exists', () => {
|
|
23
|
-
mockPlayerContext.npoPlayer.eventListeners = {
|
|
24
|
-
segmentHandleTimeChangedCallback: jest.fn(),
|
|
25
|
-
liveStreamHandleTimeChangedCallback: jest.fn(),
|
|
26
|
-
segmentSeekFunctionCallback: jest.fn()
|
|
27
|
-
};
|
|
28
|
-
removeEventListeners(mockPlayerContext);
|
|
29
|
-
if (mockPlayerContext.npoPlayer.eventListeners) {
|
|
30
|
-
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.Seek, mockPlayerContext.npoPlayer.eventListeners.segmentSeekFunctionCallback);
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
it('should reset EventListeners in playerContext', () => {
|
|
34
|
-
mockPlayerContext.npoPlayer.eventListeners = {
|
|
35
|
-
segmentHandleTimeChangedCallback: jest.fn(),
|
|
36
|
-
liveStreamHandleTimeChangedCallback: jest.fn(),
|
|
37
|
-
segmentSeekFunctionCallback: jest.fn()
|
|
14
|
+
segmentSeekFunctionCallback: jest.fn(),
|
|
15
|
+
adBreakFinishedCallback: jest.fn(),
|
|
16
|
+
adErrorCallback: jest.fn(),
|
|
17
|
+
handleStartOffsetCallbackOnReady: jest.fn(),
|
|
18
|
+
handleStartOffsetCallbackOnSourceLoaded: jest.fn(),
|
|
19
|
+
handleStartOffsetCallbackOnAdBreakFinished: jest.fn(),
|
|
20
|
+
handleStartOffsetCallbackOnAdError: jest.fn()
|
|
38
21
|
};
|
|
22
|
+
mockPlayerContext.npoPlayer.eventListeners = { ...eventListeners };
|
|
39
23
|
removeEventListeners(mockPlayerContext);
|
|
24
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledTimes(9);
|
|
25
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, eventListeners.liveStreamHandleTimeChangedCallback);
|
|
26
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.TimeChanged, eventListeners.segmentHandleTimeChangedCallback);
|
|
27
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.Seek, eventListeners.segmentSeekFunctionCallback);
|
|
28
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.AdBreakFinished, eventListeners.adBreakFinishedCallback);
|
|
29
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.AdError, eventListeners.adErrorCallback);
|
|
30
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.Ready, eventListeners.handleStartOffsetCallbackOnReady);
|
|
31
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.SourceLoaded, eventListeners.handleStartOffsetCallbackOnSourceLoaded);
|
|
32
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.AdBreakFinished, eventListeners.handleStartOffsetCallbackOnAdBreakFinished);
|
|
33
|
+
expect(mockPlayerContext.player.off).toHaveBeenCalledWith(NpoPlayerEvent.AdError, eventListeners.handleStartOffsetCallbackOnAdError);
|
|
40
34
|
expect(mockPlayerContext.npoPlayer.eventListeners).toBeUndefined();
|
|
41
35
|
});
|
|
42
36
|
});
|
|
@@ -172,6 +172,7 @@ export class NpoPlayerAPI {
|
|
|
172
172
|
playerContext.npoPlayer.uiManager = uiManager;
|
|
173
173
|
playerContext.npoPlayer.variant = variant;
|
|
174
174
|
npoPlayerServices.addUivisiblityHandlers(playerContext);
|
|
175
|
+
npoPlayerServices.setupNicamKijkwijzerIcons(playerContext);
|
|
175
176
|
npoPlayerServices.showNicamAfterUiDelay(playerContext);
|
|
176
177
|
}
|
|
177
178
|
}
|
|
@@ -70,7 +70,8 @@ export function setupAutoplay(playerContext) {
|
|
|
70
70
|
};
|
|
71
71
|
const doAutoPlay = async () => {
|
|
72
72
|
player.off(NpoPlayerEvent.Ready, handleAutoPlay);
|
|
73
|
+
player.off(NpoPlayerEvent.SourceLoaded, handleAutoPlay);
|
|
73
74
|
await player.play();
|
|
74
75
|
};
|
|
75
|
-
player.on(NpoPlayerEvent.
|
|
76
|
+
player.on(NpoPlayerEvent.SourceLoaded, handleAutoPlay);
|
|
76
77
|
}
|
|
@@ -178,7 +178,7 @@ describe('handleStreamOptions', () => {
|
|
|
178
178
|
player: mockNpoPlayerAPI
|
|
179
179
|
});
|
|
180
180
|
setupAutoplay(playerContextMock);
|
|
181
|
-
expect(playerContextMock.player.on).toHaveBeenCalledWith(NpoPlayerEvent.
|
|
181
|
+
expect(playerContextMock.player.on).toHaveBeenCalledWith(NpoPlayerEvent.SourceLoaded, expect.any(Function));
|
|
182
182
|
const handleAutoPlay = playerContextMock.player.on.mock.calls[0][1];
|
|
183
183
|
await handleAutoPlay();
|
|
184
184
|
expect(playerContextMock.player.play).toHaveBeenCalled();
|
|
@@ -17,7 +17,7 @@ export const startPlayerTracker = function ({ playerContext, source, duration })
|
|
|
17
17
|
}) || 'unknown';
|
|
18
18
|
npoPlayer.streamTracker = initStreamTracker({
|
|
19
19
|
playerContext: playerContext,
|
|
20
|
-
duration: getStreamDurationInSeconds({ duration: playerDuration }),
|
|
20
|
+
duration: getStreamDurationInSeconds({ duration: playerDuration, durationIsInMs: !!duration }),
|
|
21
21
|
source: analyticsPrid
|
|
22
22
|
});
|
|
23
23
|
bindPlayerEvents(playerContext);
|
|
@@ -22,31 +22,32 @@ jest.mock('./eventLogging', () => ({
|
|
|
22
22
|
}));
|
|
23
23
|
describe('startPlayerTracker', () => {
|
|
24
24
|
let playerContextMock;
|
|
25
|
+
let playerMock;
|
|
25
26
|
beforeEach(() => {
|
|
27
|
+
playerMock = { getDuration: jest.fn().mockReturnValue(200) };
|
|
26
28
|
playerContextMock = createPlayerContextMock({
|
|
27
29
|
npoPlayer: {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
npoTagPageTracker: undefined
|
|
30
|
+
player: playerMock,
|
|
31
|
+
sourceConfig: {},
|
|
32
|
+
streamObject: {}
|
|
32
33
|
}
|
|
33
34
|
});
|
|
34
35
|
jest.clearAllMocks();
|
|
35
36
|
});
|
|
36
|
-
it('should initialize the stream tracker with
|
|
37
|
+
it('should initialize the stream tracker with the provided duration', () => {
|
|
37
38
|
const source = 'some-source';
|
|
38
39
|
const duration = 150;
|
|
39
40
|
getAnalyticsPrid.mockReturnValue('some-prid');
|
|
40
41
|
getStreamDurationInSeconds.mockReturnValue(duration);
|
|
41
|
-
startPlayerTracker({
|
|
42
|
-
playerContext: playerContextMock,
|
|
43
|
-
source,
|
|
44
|
-
duration
|
|
45
|
-
});
|
|
42
|
+
startPlayerTracker({ playerContext: playerContextMock, source, duration });
|
|
46
43
|
expect(getAnalyticsPrid).toHaveBeenCalledWith({
|
|
47
44
|
source,
|
|
48
|
-
sourceConfig:
|
|
49
|
-
streamObject:
|
|
45
|
+
sourceConfig: {},
|
|
46
|
+
streamObject: {}
|
|
47
|
+
});
|
|
48
|
+
expect(getStreamDurationInSeconds).toHaveBeenCalledWith({
|
|
49
|
+
duration,
|
|
50
|
+
durationIsInMs: true
|
|
50
51
|
});
|
|
51
52
|
expect(initStreamTracker).toHaveBeenCalledWith({
|
|
52
53
|
playerContext: playerContextMock,
|
|
@@ -56,4 +57,20 @@ describe('startPlayerTracker', () => {
|
|
|
56
57
|
expect(bindPlayerEvents).toHaveBeenCalledWith(playerContextMock);
|
|
57
58
|
expect(logEvent).toHaveBeenCalledWith({ playerContext: playerContextMock, event: 'load' });
|
|
58
59
|
});
|
|
60
|
+
it('should fallback to player.getDuration() if duration is not provided', () => {
|
|
61
|
+
const source = 'some-source';
|
|
62
|
+
const fallbackDuration = 200;
|
|
63
|
+
getAnalyticsPrid.mockReturnValue('some-prid');
|
|
64
|
+
getStreamDurationInSeconds.mockReturnValue(fallbackDuration);
|
|
65
|
+
startPlayerTracker({ playerContext: playerContextMock, source });
|
|
66
|
+
expect(getStreamDurationInSeconds).toHaveBeenCalledWith({
|
|
67
|
+
duration: fallbackDuration,
|
|
68
|
+
durationIsInMs: false
|
|
69
|
+
});
|
|
70
|
+
expect(initStreamTracker).toHaveBeenCalledWith({
|
|
71
|
+
playerContext: playerContextMock,
|
|
72
|
+
duration: fallbackDuration,
|
|
73
|
+
source: 'some-prid'
|
|
74
|
+
});
|
|
75
|
+
});
|
|
59
76
|
});
|
|
@@ -21,6 +21,10 @@ export interface EventListeners {
|
|
|
21
21
|
segmentSeekFunctionCallback?: NpoPlayerEventCallback;
|
|
22
22
|
adBreakFinishedCallback?: NpoPlayerEventCallback;
|
|
23
23
|
adErrorCallback?: NpoPlayerEventCallback;
|
|
24
|
+
handleStartOffsetCallbackOnReady?: NpoPlayerEventCallback;
|
|
25
|
+
handleStartOffsetCallbackOnSourceLoaded?: NpoPlayerEventCallback;
|
|
26
|
+
handleStartOffsetCallbackOnAdBreakFinished?: NpoPlayerEventCallback;
|
|
27
|
+
handleStartOffsetCallbackOnAdError?: NpoPlayerEventCallback;
|
|
24
28
|
}
|
|
25
29
|
export interface StreamObject {
|
|
26
30
|
stream: StreamObject_Stream;
|
|
@@ -230,8 +234,8 @@ export type LocalStorageData = Partial<Record<LocalStorageValues, string | numbe
|
|
|
230
234
|
export type NPOGoogleCastRemoteControlConfig = GoogleCastRemoteControlConfig;
|
|
231
235
|
export interface PlayerTrackerParams {
|
|
232
236
|
playerContext: PlayerContext;
|
|
233
|
-
duration
|
|
234
|
-
source
|
|
237
|
+
duration?: number;
|
|
238
|
+
source?: string;
|
|
235
239
|
}
|
|
236
240
|
export interface LogEventParams {
|
|
237
241
|
playerContext: PlayerContext;
|
|
@@ -21,6 +21,10 @@ export interface EventListeners {
|
|
|
21
21
|
segmentSeekFunctionCallback?: NpoPlayerEventCallback;
|
|
22
22
|
adBreakFinishedCallback?: NpoPlayerEventCallback;
|
|
23
23
|
adErrorCallback?: NpoPlayerEventCallback;
|
|
24
|
+
handleStartOffsetCallbackOnReady?: NpoPlayerEventCallback;
|
|
25
|
+
handleStartOffsetCallbackOnSourceLoaded?: NpoPlayerEventCallback;
|
|
26
|
+
handleStartOffsetCallbackOnAdBreakFinished?: NpoPlayerEventCallback;
|
|
27
|
+
handleStartOffsetCallbackOnAdError?: NpoPlayerEventCallback;
|
|
24
28
|
}
|
|
25
29
|
export interface StreamObject {
|
|
26
30
|
stream: StreamObject_Stream;
|
|
@@ -230,8 +234,8 @@ export type LocalStorageData = Partial<Record<LocalStorageValues, string | numbe
|
|
|
230
234
|
export type NPOGoogleCastRemoteControlConfig = GoogleCastRemoteControlConfig;
|
|
231
235
|
export interface PlayerTrackerParams {
|
|
232
236
|
playerContext: PlayerContext;
|
|
233
|
-
duration
|
|
234
|
-
source
|
|
237
|
+
duration?: number;
|
|
238
|
+
source?: string;
|
|
235
239
|
}
|
|
236
240
|
export interface LogEventParams {
|
|
237
241
|
playerContext: PlayerContext;
|