@npo/player 1.27.3 → 1.27.5

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/npoplayer.js CHANGED
@@ -159,25 +159,25 @@ export default class NpoPlayer {
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
161
  await this.npoPlayerServices.verifyDRM(this.playerContext, payload);
162
- setupMediaSessionActionHandlers(this.player, this.sourceConfig, _streamObject);
163
- this.hidePlayNextScreen();
164
162
  const streamDuration = _streamObject.metadata.duration;
165
163
  this.npoPlayerServices.startPlayerTracker({
166
164
  playerContext: this.playerContext,
167
165
  source: source,
168
166
  duration: streamDuration ? Number(streamDuration) : undefined
169
167
  });
170
- if (this.variant === NpoPlayerUIVariants.DEFAULT &&
171
- this.streamObject.metadata.hasPreroll === 'true' &&
172
- this.streamObject.assets.preroll) {
173
- await this.npoPlayerServices.schedulePreRolls(this.playerContext);
174
- }
175
168
  }
176
169
  else {
177
170
  await this.npoPlayerServices.handleError(this.playerContext, 500);
178
171
  }
179
172
  this.npoPlayerServices.handleStreamOptions(this.playerContext);
180
173
  this.npoPlayerServices.setupNicamKijkwijzerIcons(this.playerContext);
174
+ setupMediaSessionActionHandlers(this.player, this.sourceConfig, this.streamObject);
175
+ this.hidePlayNextScreen();
176
+ if (this.variant === NpoPlayerUIVariants.DEFAULT &&
177
+ this.streamObject.metadata.hasPreroll === 'true' &&
178
+ this.streamObject.assets.preroll) {
179
+ await this.npoPlayerServices.schedulePreRolls(this.playerContext);
180
+ }
181
181
  if (this.variant === NpoPlayerUIVariants.VERTICAL) {
182
182
  this.npoPlayerServices.handleVerticalVideoControls(this.playerContext);
183
183
  this.npoPlayerServices.handleVerticalVideoSettings(this.playerContext);
@@ -329,6 +329,7 @@ export default class NpoPlayer {
329
329
  }
330
330
  this.pause();
331
331
  if (this.playerContext) {
332
+ this.npoPlayerServices.removeEventListeners(this.playerContext);
332
333
  this.npoPlayerServices.discardAdBreak(this.playerContext);
333
334
  }
334
335
  this.hidePlayNextScreen();
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npo/player",
3
- "version": "1.27.3",
3
+ "version": "1.27.5",
4
4
  "description": "NPO Player",
5
5
  "author": "Publieke Omroep <player@npo.nl>",
6
6
  "contributors": [
@@ -1,13 +1,9 @@
1
1
  import { NpoPlayerUIVariants } from '../../types/interfaces';
2
2
  export function discardAdBreak(playerContext) {
3
3
  const { npoPlayer, player } = playerContext;
4
- const { adBreakActive } = npoPlayer;
5
- if (!player || adBreakActive === false)
4
+ const { adBreakActive, variant } = npoPlayer;
5
+ if (!player || (!adBreakActive && variant !== NpoPlayerUIVariants.AD))
6
6
  return;
7
7
  void playerContext.player.createUIManager(playerContext, NpoPlayerUIVariants.DEFAULT);
8
- const activeAdBreak = player.getActiveAdBreak();
9
- if (activeAdBreak?.id) {
10
- player.playerAPI.ads.discardAdBreak(activeAdBreak.id);
11
- }
12
- npoPlayer.adBreakActive = false;
8
+ playerContext.npoPlayer.adBreakActive = false;
13
9
  }
@@ -4,73 +4,36 @@ import { discardAdBreak } from './discardAdBreak';
4
4
  describe('discardAdBreak', () => {
5
5
  let mockNpoPlayerAPI;
6
6
  let npoPlayerMock;
7
- const activeAdBreakMock = { id: 'ad-break-id' };
8
7
  afterEach(() => {
9
8
  jest.resetAllMocks();
10
9
  });
11
10
  it('should not discard ad break if player is undefined', () => {
12
- npoPlayerMock = createMockNpoPlayer({
13
- adBreakActive: true
14
- });
15
- const playerContextMock = createPlayerContextMock({
16
- player: undefined,
17
- npoPlayer: npoPlayerMock
18
- });
11
+ npoPlayerMock = createMockNpoPlayer({ adBreakActive: true, variant: NpoPlayerUIVariants.AD });
12
+ const playerContextMock = createPlayerContextMock({ player: undefined, npoPlayer: npoPlayerMock });
19
13
  discardAdBreak(playerContextMock);
20
14
  expect(npoPlayerMock.adBreakActive).toBe(true);
21
15
  });
22
16
  it('should not discard ad break if adBreakActive is false', () => {
23
- mockNpoPlayerAPI = createMockNpoPlayerAPI({
24
- getActiveAdBreak: jest.fn().mockReturnValue(activeAdBreakMock),
25
- discardAdBreak: jest.fn()
26
- });
27
- npoPlayerMock = createMockNpoPlayer({
28
- adBreakActive: false
29
- });
30
- const playerContextMock = createPlayerContextMock({
31
- player: mockNpoPlayerAPI,
32
- npoPlayer: npoPlayerMock
33
- });
17
+ mockNpoPlayerAPI = createMockNpoPlayerAPI();
18
+ npoPlayerMock = createMockNpoPlayer({ adBreakActive: false });
19
+ const playerContextMock = createPlayerContextMock({ player: mockNpoPlayerAPI, npoPlayer: npoPlayerMock });
34
20
  discardAdBreak(playerContextMock);
35
- expect(mockNpoPlayerAPI.getActiveAdBreak).not.toHaveBeenCalled();
36
- expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).not.toHaveBeenCalled();
37
21
  expect(npoPlayerMock.adBreakActive).toBe(false);
38
22
  expect(playerContextMock.player.createUIManager).not.toHaveBeenCalled();
39
23
  });
40
- it('should discard active ad break if adBreakActive is true and ad break exists', () => {
41
- mockNpoPlayerAPI = createMockNpoPlayerAPI({
42
- getActiveAdBreak: jest.fn().mockReturnValue(activeAdBreakMock),
43
- discardAdBreak: jest.fn(),
44
- variant: NpoPlayerUIVariants.AD
45
- });
46
- npoPlayerMock = createMockNpoPlayer({
47
- adBreakActive: true
48
- });
49
- const playerContextMock = createPlayerContextMock({
50
- player: mockNpoPlayerAPI,
51
- npoPlayer: npoPlayerMock
52
- });
24
+ it('should discard ad break if adBreakActive is true', () => {
25
+ mockNpoPlayerAPI = createMockNpoPlayerAPI();
26
+ npoPlayerMock = createMockNpoPlayer({ adBreakActive: true, variant: NpoPlayerUIVariants.DEFAULT });
27
+ const playerContextMock = createPlayerContextMock({ player: mockNpoPlayerAPI, npoPlayer: npoPlayerMock });
53
28
  discardAdBreak(playerContextMock);
54
- expect(mockNpoPlayerAPI.getActiveAdBreak).toHaveBeenCalled();
55
- expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).toHaveBeenCalledWith(activeAdBreakMock.id);
56
29
  expect(npoPlayerMock.adBreakActive).toBe(false);
57
- expect(playerContextMock.player.createUIManager).toHaveBeenCalledWith(playerContextMock, NpoPlayerUIVariants.DEFAULT);
30
+ expect(playerContextMock.player.createUIManager).toHaveBeenCalled();
58
31
  });
59
- it('should not discard ad break if active ad break does not exist', () => {
60
- mockNpoPlayerAPI = createMockNpoPlayerAPI({
61
- getActiveAdBreak: jest.fn().mockReturnValue(undefined),
62
- discardAdBreak: jest.fn()
63
- });
64
- npoPlayerMock = createMockNpoPlayer({
65
- adBreakActive: true
66
- });
67
- const playerContextMock = createPlayerContextMock({
68
- player: mockNpoPlayerAPI,
69
- npoPlayer: npoPlayerMock
70
- });
32
+ it('should discard active ad break if conditions are met', () => {
33
+ mockNpoPlayerAPI = createMockNpoPlayerAPI();
34
+ npoPlayerMock = createMockNpoPlayer({ adBreakActive: true, variant: NpoPlayerUIVariants.AD });
35
+ const playerContextMock = createPlayerContextMock({ player: mockNpoPlayerAPI, npoPlayer: npoPlayerMock });
71
36
  discardAdBreak(playerContextMock);
72
- expect(mockNpoPlayerAPI.getActiveAdBreak).toHaveBeenCalled();
73
- expect(mockNpoPlayerAPI.playerAPI.ads.discardAdBreak).not.toHaveBeenCalled();
74
37
  expect(npoPlayerMock.adBreakActive).toBe(false);
75
38
  expect(playerContextMock.player.createUIManager).toHaveBeenCalledWith(playerContextMock, NpoPlayerUIVariants.DEFAULT);
76
39
  });
@@ -124,7 +124,14 @@ export async function handlePreRolls(playerContext) {
124
124
  adUiSet = false;
125
125
  resolve();
126
126
  }
127
- playerContext.player.on(NpoPlayerEvent.AdBreakFinished, handleAdBreakFinished);
128
- playerContext.player.on(NpoPlayerEvent.AdError, handleAdBreakFinished);
127
+ const adBreakFinishedCallback = () => handleAdBreakFinished();
128
+ const adErrorCallback = () => handleAdBreakFinished();
129
+ playerContext.player.on(NpoPlayerEvent.AdBreakFinished, adBreakFinishedCallback);
130
+ playerContext.player.on(NpoPlayerEvent.AdError, adErrorCallback);
131
+ playerContext.npoPlayer.eventListeners = {
132
+ ...playerContext.npoPlayer.eventListeners,
133
+ adBreakFinishedCallback,
134
+ adErrorCallback
135
+ };
129
136
  });
130
137
  }
@@ -2,11 +2,13 @@ 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 } = eventListeners;
5
+ const { segmentHandleTimeChangedCallback, segmentSeekFunctionCallback, liveStreamHandleTimeChangedCallback, adBreakFinishedCallback, adErrorCallback } = eventListeners;
6
6
  const eventMapping = [
7
7
  { event: NpoPlayerEvent.TimeChanged, callback: liveStreamHandleTimeChangedCallback },
8
8
  { event: NpoPlayerEvent.TimeChanged, callback: segmentHandleTimeChangedCallback },
9
- { event: NpoPlayerEvent.Seek, callback: segmentSeekFunctionCallback }
9
+ { event: NpoPlayerEvent.Seek, callback: segmentSeekFunctionCallback },
10
+ { event: NpoPlayerEvent.AdBreakFinished, callback: adBreakFinishedCallback },
11
+ { event: NpoPlayerEvent.AdError, callback: adErrorCallback }
10
12
  ];
11
13
  for (const { event, callback } of eventMapping) {
12
14
  if (callback) {
@@ -4,6 +4,7 @@ export const handleLiveStreamControls = (playerContext) => {
4
4
  const { player, npoPlayer } = playerContext;
5
5
  player.on(NpoPlayerEvent.TimeChanged, liveStreamHandleTimeChangedCallback);
6
6
  npoPlayer.eventListeners = {
7
+ ...npoPlayer.eventListeners,
7
8
  liveStreamHandleTimeChangedCallback
8
9
  };
9
10
  };
@@ -8,6 +8,7 @@ export const addSegmentEventListeners = (playerContext, segment) => {
8
8
  player.on(NpoPlayerEvent.TimeChanged, segmentHandleTimeChangedCallback);
9
9
  player.on(NpoPlayerEvent.Seek, segmentSeekFunctionCallback);
10
10
  npoPlayer.eventListeners = {
11
+ ...npoPlayer.eventListeners,
11
12
  segmentHandleTimeChangedCallback,
12
13
  segmentSeekFunctionCallback
13
14
  };
@@ -26,4 +26,5 @@ export declare class NpoPlayerServices {
26
26
  startPlayerTracker({ playerContext, source, duration }: PlayerTrackerParams): void;
27
27
  initPlayerTracker(playerContext: PlayerContext): void;
28
28
  logEvent({ playerContext, event, data }: LogEventParams): void;
29
+ removeEventListeners(playerContext: PlayerContext): void;
29
30
  }
@@ -16,6 +16,7 @@ import { handleStreamOptions } from './streamoptionsHandlers/streamOptionsHandle
16
16
  import { handlePlayerError } from './errors/errorHandler';
17
17
  import { fetchStream } from './streamFetchHandler/fetchStream';
18
18
  import { startPlayerTracker, initPlayerTracker, logEvent } from './trackingHandlers';
19
+ import { removeEventListeners } from './eventListenerHandlers/removeEventListeners';
19
20
  export class NpoPlayerServices {
20
21
  getAVType(avType) {
21
22
  return getAVType(avType);
@@ -104,4 +105,7 @@ export class NpoPlayerServices {
104
105
  logEvent({ playerContext, event, data }) {
105
106
  logEvent({ playerContext, event, data });
106
107
  }
108
+ removeEventListeners(playerContext) {
109
+ removeEventListeners(playerContext);
110
+ }
107
111
  }
@@ -1,14 +1,12 @@
1
1
  import * as playerAction from '../../js/playeractions/playeractions';
2
2
  import { initSegment } from '../segmentHandlers/initSegment';
3
3
  import { handleLiveStreamControls } from '../liveStreamHandlers/handleLiveStreamControls';
4
- import { removeEventListeners } from '../eventListenerHandlers/removeEventListeners';
5
4
  import { NpoPlayerEvent } from '../../types/events';
6
5
  import { updateClassFromElementByQuery } from '../../js/utilities/utilities.element';
7
6
  export function handleStreamOptions(playerContext) {
8
7
  const { streamObject, uiManager } = playerContext.npoPlayer;
9
8
  if (!streamObject || !uiManager)
10
9
  return;
11
- removeEventListeners(playerContext);
12
10
  initializeFragment(playerContext);
13
11
  handleStartOffset(playerContext);
14
12
  updateStreamClasses(playerContext);
@@ -26,4 +26,5 @@ export declare class NpoPlayerServices {
26
26
  startPlayerTracker({ playerContext, source, duration }: PlayerTrackerParams): void;
27
27
  initPlayerTracker(playerContext: PlayerContext): void;
28
28
  logEvent({ playerContext, event, data }: LogEventParams): void;
29
+ removeEventListeners(playerContext: PlayerContext): void;
29
30
  }
@@ -19,6 +19,8 @@ export interface EventListeners {
19
19
  liveStreamHandleTimeChangedCallback?: NpoPlayerEventCallback;
20
20
  segmentHandleTimeChangedCallback?: NpoPlayerEventCallback;
21
21
  segmentSeekFunctionCallback?: NpoPlayerEventCallback;
22
+ adBreakFinishedCallback?: NpoPlayerEventCallback;
23
+ adErrorCallback?: NpoPlayerEventCallback;
22
24
  }
23
25
  export interface StreamObject {
24
26
  stream: StreamObject_Stream;
@@ -19,6 +19,8 @@ export interface EventListeners {
19
19
  liveStreamHandleTimeChangedCallback?: NpoPlayerEventCallback;
20
20
  segmentHandleTimeChangedCallback?: NpoPlayerEventCallback;
21
21
  segmentSeekFunctionCallback?: NpoPlayerEventCallback;
22
+ adBreakFinishedCallback?: NpoPlayerEventCallback;
23
+ adErrorCallback?: NpoPlayerEventCallback;
22
24
  }
23
25
  export interface StreamObject {
24
26
  stream: StreamObject_Stream;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npo/player",
3
- "version": "1.27.3",
3
+ "version": "1.27.5",
4
4
  "description": "NPO Player",
5
5
  "author": "Publieke Omroep <player@npo.nl>",
6
6
  "contributors": [