@npo/player 1.26.0 → 1.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/js/playeractions/handlers/mediasessionactions.js +2 -2
- package/lib/js/playeractions/playeractions.d.ts +0 -1
- package/lib/js/playeractions/playeractions.js +0 -1
- package/lib/js/utilities/utilities.prid.d.ts +6 -0
- package/lib/js/utilities/utilities.prid.js +8 -0
- package/lib/js/utilities/utilities.prid.test.js +46 -0
- package/lib/npoplayer.d.ts +1 -1
- package/lib/npoplayer.js +52 -69
- package/lib/npoplayer.test.js +2 -2
- package/lib/package.json +1 -1
- package/lib/services/a11y/setup.test.js +0 -1
- package/lib/services/advertHandlers/discardAdBreak.js +2 -0
- package/lib/services/advertHandlers/discardAdBreak.test.js +6 -1
- package/lib/services/advertHandlers/handlePreRolls.js +2 -4
- package/lib/services/advertHandlers/handlePrerolls.test.js +62 -1
- package/lib/services/drmHandlers/decideprofile.js +7 -1
- package/lib/services/drmHandlers/decideprofile.test.js +4 -0
- package/lib/services/drmHandlers/utils.js +4 -1
- package/lib/services/drmHandlers/utils.test.js +7 -0
- package/lib/services/drmHandlers/verifydrm.js +5 -6
- package/lib/services/drmHandlers/verifydrm.test.js +28 -5
- package/lib/services/errors/errorBackground.test.js +48 -0
- package/lib/services/errors/errorHandler.d.ts +3 -0
- package/lib/services/errors/errorHandler.js +46 -0
- package/lib/services/errors/errorText.d.ts +2 -0
- package/lib/services/errors/errorText.js +59 -0
- package/lib/services/errors/errorText.test.js +66 -0
- package/lib/services/keyboardHandlers/resolvekeypress.js +21 -17
- package/lib/services/localStorageHandlers/localStorageHandlers.js +5 -2
- package/lib/services/localStorageHandlers/localStorageHandlers.test.js +0 -1
- package/lib/services/nicamHandlers/nicamhandler.js +0 -4
- package/lib/services/nicamHandlers/nicamhandler.test.js +0 -5
- package/lib/services/npoPlayerAPI/contants.d.ts +20 -0
- package/lib/services/npoPlayerAPI/contants.js +6 -0
- package/lib/services/npoPlayerAPI/npoPlayerAPI.d.ts +4 -1
- package/lib/services/npoPlayerAPI/npoPlayerAPI.js +31 -5
- package/lib/services/npoPlayerAPI/npoPlayerAPI.test.js +11 -0
- package/lib/services/services.d.ts +8 -2
- package/lib/services/services.js +28 -2
- package/lib/services/streamFetchHandler/fetchStream.d.ts +2 -0
- package/lib/services/streamFetchHandler/fetchStream.js +48 -0
- package/lib/services/streamFetchHandler/fetchstream.test.js +70 -0
- package/lib/services/trackingHandlers/eventBinding.d.ts +2 -0
- package/lib/{js/tracking/handlers/eventbinding.js → services/trackingHandlers/eventBinding.js} +16 -14
- package/lib/services/trackingHandlers/eventBinding.test.js +89 -0
- package/lib/services/trackingHandlers/eventLogging.d.ts +2 -0
- package/lib/{js/tracking/handlers/eventlogging.js → services/trackingHandlers/eventLogging.js} +18 -7
- package/lib/services/trackingHandlers/eventLogging.test.js +63 -0
- package/lib/services/trackingHandlers/index.d.ts +3 -0
- package/lib/services/trackingHandlers/index.js +3 -0
- package/lib/services/trackingHandlers/playerTrackerInit.d.ts +2 -0
- package/lib/{js/tracking/handlers/playertrackerinit.js → services/trackingHandlers/playerTrackerInit.js} +6 -3
- package/lib/services/trackingHandlers/playerTrackerInit.test.js +75 -0
- package/lib/services/trackingHandlers/playerTrackerStart.d.ts +2 -0
- package/lib/services/trackingHandlers/playerTrackerStart.js +25 -0
- package/lib/services/trackingHandlers/playerTrackerStart.test.js +59 -0
- package/lib/services/trackingHandlers/streamTrackerInit.d.ts +3 -0
- package/lib/services/trackingHandlers/streamTrackerInit.js +27 -0
- package/lib/services/trackingHandlers/streamTrackerInit.test.js +84 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.d.ts +2 -2
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.js +4 -6
- package/lib/services/verticalVideoHandlers/handleVerticalVideoControls.test.js +4 -17
- package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.d.ts +2 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.js +26 -0
- package/lib/services/verticalVideoHandlers/handleVerticalVideoSettings.test.js +82 -0
- package/lib/src/js/playeractions/playeractions.d.ts +0 -1
- package/lib/src/js/utilities/utilities.prid.d.ts +6 -0
- package/lib/src/js/utilities/utilities.prid.test.d.ts +1 -0
- package/lib/src/npoplayer.d.ts +1 -1
- package/lib/src/services/errors/errorBackground.test.d.ts +1 -0
- package/lib/src/services/errors/errorHandler.d.ts +3 -0
- package/lib/src/services/errors/errorText.d.ts +2 -0
- package/lib/src/services/errors/errorText.test.d.ts +1 -0
- package/lib/src/services/npoPlayerAPI/contants.d.ts +20 -0
- package/lib/src/services/npoPlayerAPI/npoPlayerAPI.d.ts +4 -1
- package/lib/src/services/services.d.ts +8 -2
- package/lib/src/services/streamFetchHandler/fetchStream.d.ts +2 -0
- package/lib/src/services/streamFetchHandler/fetchstream.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/eventBinding.d.ts +2 -0
- package/lib/src/services/trackingHandlers/eventBinding.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/eventLogging.d.ts +2 -0
- package/lib/src/services/trackingHandlers/eventLogging.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/index.d.ts +3 -0
- package/lib/src/services/trackingHandlers/playerTrackerInit.d.ts +2 -0
- package/lib/src/services/trackingHandlers/playerTrackerInit.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/playerTrackerStart.d.ts +2 -0
- package/lib/src/services/trackingHandlers/playerTrackerStart.test.d.ts +1 -0
- package/lib/src/services/trackingHandlers/streamTrackerInit.d.ts +3 -0
- package/lib/src/services/trackingHandlers/streamTrackerInit.test.d.ts +1 -0
- package/lib/src/services/verticalVideoHandlers/handleVerticalVideoControls.d.ts +2 -2
- package/lib/src/services/verticalVideoHandlers/handleVerticalVideoSettings.d.ts +2 -0
- package/lib/src/services/verticalVideoHandlers/handleVerticalVideoSettings.test.d.ts +1 -0
- package/lib/src/types/interfaces.d.ts +16 -2
- package/lib/src/ui/components/seekbar.d.ts +2 -1
- package/lib/src/ui/components/verticalvideo/controlbar.d.ts +3 -3
- package/lib/src/ui/components/verticalvideo/settingspanel.d.ts +2 -0
- package/lib/tests/mocks/mockNpoplayer.js +1 -1
- package/lib/tests/mocks/mockStreamObject.d.ts +2 -0
- package/lib/tests/mocks/mockStreamObject.js +21 -0
- package/lib/tests/mocks/playerContextMock.d.ts +1 -0
- package/lib/tests/mocks/playerContextMock.js +5 -1
- package/lib/types/interfaces.d.ts +16 -2
- package/lib/ui/components/audio/controlbar.js +2 -1
- package/lib/ui/components/controlbar.js +1 -1
- package/lib/ui/components/seekbar.d.ts +2 -1
- package/lib/ui/components/seekbar.js +2 -2
- package/lib/ui/components/settingspanel.js +8 -12
- package/lib/ui/components/verticalvideo/controlbar.d.ts +3 -3
- package/lib/ui/components/verticalvideo/controlbar.js +14 -11
- package/lib/ui/components/verticalvideo/settingspanel.d.ts +2 -0
- package/lib/ui/components/verticalvideo/settingspanel.js +21 -0
- package/lib/ui/handlers/domhandlers.test.js +6 -26
- package/lib/ui/nativemobileuifactory.js +1 -1
- package/lib/ui/uicontainer.js +5 -4
- package/lib/ui/uicontainer.test.js +4 -1
- package/package.json +1 -1
- package/src/style/components/_advert.scss +3 -3
- package/src/style/components/_buffering.scss +14 -8
- package/src/style/components/_error.scss +44 -1
- package/src/style/components/_hugeplaybacktogglebutton.scss +1 -0
- package/src/style/components/_metadata.scss +13 -12
- package/src/style/components/_nicam.scss +11 -6
- package/src/style/components/_playnext.scss +1 -1
- package/src/style/components/_replay.scss +1 -6
- package/src/style/components/_settingspanel.scss +74 -79
- package/src/style/components/audio/_bottombar.scss +7 -9
- package/src/style/components/audio/_errors.scss +1 -1
- package/src/style/components/audio/_metadata.scss +14 -8
- package/src/style/components/audio/_playbutton.scss +1 -0
- package/src/style/components/audio/_topbar.scss +12 -2
- package/src/style/components/audio/_volumeslider.scss +3 -3
- package/src/style/components/vertical-video/_bottombar.scss +42 -1
- package/src/style/components/vertical-video/_hugeplaybacktogglebutton.scss +24 -4
- package/src/style/components/vertical-video/_settingspanel.scss +20 -3
- package/src/style/components/vertical-video/_topbar.scss +47 -6
- package/src/style/npoplayer.css +91 -57
- package/src/style/npoplayer.scss +4 -7
- package/src/style/variants/_player-base.scss +10 -2
- package/src/style/variants/_player-large.scss +4 -0
- package/src/style/variants/_player-medium.scss +4 -1
- package/src/style/variants/_player-small.scss +15 -1
- package/src/style/vars/_fonts.scss +13 -7
- package/src/style/vars/_z-index.scss +1 -0
- package/lib/js/api/getstreamobject.d.ts +0 -3
- package/lib/js/api/getstreamobject.js +0 -38
- package/lib/js/api/getstreamobject.test.js +0 -48
- package/lib/js/playeractions/customerrors.test.js +0 -51
- package/lib/js/playeractions/handlers/customerrors.d.ts +0 -50
- package/lib/js/playeractions/handlers/customerrors.js +0 -56
- package/lib/js/playeractions/handlers/error.d.ts +0 -3
- package/lib/js/playeractions/handlers/error.js +0 -14
- package/lib/js/playeractions/handlers/error.test.js +0 -44
- package/lib/js/tracking/handlers/eventbinding.d.ts +0 -3
- package/lib/js/tracking/handlers/eventlogging.d.ts +0 -2
- package/lib/js/tracking/handlers/eventlogging.test.js +0 -46
- package/lib/js/tracking/handlers/playertrackerinit.d.ts +0 -4
- package/lib/js/tracking/handlers/playertrackerinit.test.js +0 -74
- package/lib/js/tracking/handlers/playertrackerstart.d.ts +0 -1
- package/lib/js/tracking/handlers/playertrackerstart.js +0 -25
- package/lib/js/tracking/playertracker.d.ts +0 -4
- package/lib/js/tracking/playertracker.js +0 -4
- package/lib/src/js/api/getstreamobject.d.ts +0 -3
- package/lib/src/js/playeractions/handlers/customerrors.d.ts +0 -50
- package/lib/src/js/playeractions/handlers/error.d.ts +0 -3
- package/lib/src/js/tracking/handlers/eventbinding.d.ts +0 -3
- package/lib/src/js/tracking/handlers/eventlogging.d.ts +0 -2
- package/lib/src/js/tracking/handlers/playertrackerinit.d.ts +0 -4
- package/lib/src/js/tracking/handlers/playertrackerstart.d.ts +0 -1
- package/lib/src/js/tracking/playertracker.d.ts +0 -4
- /package/lib/js/{api/getstreamobject.test.d.ts → utilities/utilities.prid.test.d.ts} +0 -0
- /package/lib/{js/playeractions/customerrors.test.d.ts → services/errors/errorBackground.test.d.ts} +0 -0
- /package/lib/{js/playeractions/handlers/error.test.d.ts → services/errors/errorText.test.d.ts} +0 -0
- /package/lib/{js/tracking/handlers/eventlogging.test.d.ts → services/streamFetchHandler/fetchstream.test.d.ts} +0 -0
- /package/lib/{js/tracking/handlers/playertrackerinit.test.d.ts → services/trackingHandlers/eventBinding.test.d.ts} +0 -0
- /package/lib/{src/js/api/getstreamobject.test.d.ts → services/trackingHandlers/eventLogging.test.d.ts} +0 -0
- /package/lib/{src/js/playeractions/customerrors.test.d.ts → services/trackingHandlers/playerTrackerInit.test.d.ts} +0 -0
- /package/lib/{src/js/playeractions/handlers/error.test.d.ts → services/trackingHandlers/playerTrackerStart.test.d.ts} +0 -0
- /package/lib/{src/js/tracking/handlers/eventlogging.test.d.ts → services/trackingHandlers/streamTrackerInit.test.d.ts} +0 -0
- /package/lib/{src/js/tracking/handlers/playertrackerinit.test.d.ts → services/verticalVideoHandlers/handleVerticalVideoSettings.test.d.ts} +0 -0
package/lib/services/services.js
CHANGED
|
@@ -7,11 +7,15 @@ import { getLocalStorage, setLocalStorage, setValuesBasedOnLocalStorage } from '
|
|
|
7
7
|
import { getAVType } from './avTypeHandlers/getAVType';
|
|
8
8
|
import { handlePreRolls } from './advertHandlers/handlePreRolls';
|
|
9
9
|
import { handleVerticalVideoControls } from './verticalVideoHandlers/handleVerticalVideoControls';
|
|
10
|
+
import { handleVerticalVideoSettings } from './verticalVideoHandlers/handleVerticalVideoSettings';
|
|
10
11
|
import { setupNicamKijkwijzerIcons, showNicamAfterUiDelay } from './nicamHandlers/nicamhandler';
|
|
11
12
|
import { handlePreferences } from './preferences/handlePreferences';
|
|
12
13
|
import { addUivisiblityHandlers, removeUivisiblityHandlers } from './uiHandlers/uiVisiblityHandler';
|
|
13
14
|
import { discardAdBreak } from './advertHandlers/discardAdBreak';
|
|
14
15
|
import { handleStreamOptions } from './streamoptionsHandlers/streamOptionsHandler';
|
|
16
|
+
import { handlePlayerError } from './errors/errorHandler';
|
|
17
|
+
import { fetchStream } from './streamFetchHandler/fetchStream';
|
|
18
|
+
import { startPlayerTracker, initPlayerTracker, logEvent } from './trackingHandlers';
|
|
15
19
|
export class NpoPlayerServices {
|
|
16
20
|
getAVType(avType) {
|
|
17
21
|
return getAVType(avType);
|
|
@@ -57,8 +61,11 @@ export class NpoPlayerServices {
|
|
|
57
61
|
discardAdBreak(playerContext) {
|
|
58
62
|
discardAdBreak(playerContext);
|
|
59
63
|
}
|
|
60
|
-
handleVerticalVideoControls(playerContext
|
|
61
|
-
return handleVerticalVideoControls(playerContext
|
|
64
|
+
handleVerticalVideoControls(playerContext) {
|
|
65
|
+
return handleVerticalVideoControls(playerContext);
|
|
66
|
+
}
|
|
67
|
+
handleVerticalVideoSettings(playerContext) {
|
|
68
|
+
return handleVerticalVideoSettings(playerContext);
|
|
62
69
|
}
|
|
63
70
|
showNicamAfterUiDelay(playerContext) {
|
|
64
71
|
return showNicamAfterUiDelay(playerContext);
|
|
@@ -78,4 +85,23 @@ export class NpoPlayerServices {
|
|
|
78
85
|
handleStreamOptions(playerContext) {
|
|
79
86
|
handleStreamOptions(playerContext);
|
|
80
87
|
}
|
|
88
|
+
async handleError(playerContext, input) {
|
|
89
|
+
await handlePlayerError(playerContext, input);
|
|
90
|
+
}
|
|
91
|
+
async fetchStream(playerContext, payload) {
|
|
92
|
+
return await fetchStream(playerContext, payload);
|
|
93
|
+
}
|
|
94
|
+
startPlayerTracker({ playerContext, source, duration }) {
|
|
95
|
+
startPlayerTracker({
|
|
96
|
+
playerContext,
|
|
97
|
+
source,
|
|
98
|
+
duration
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
initPlayerTracker(playerContext) {
|
|
102
|
+
initPlayerTracker(playerContext);
|
|
103
|
+
}
|
|
104
|
+
logEvent({ playerContext, event, data }) {
|
|
105
|
+
logEvent({ playerContext, event, data });
|
|
106
|
+
}
|
|
81
107
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { removeTrailingSlash } from '../../js/utilities/utilities.url';
|
|
2
|
+
export async function fetchStream(playerContext, payload) {
|
|
3
|
+
const { npoPlayer } = playerContext;
|
|
4
|
+
const genericError = 'Dit item on niet worden geladen.';
|
|
5
|
+
let hasHandledError = false;
|
|
6
|
+
const handleStreamError = async (status, message) => {
|
|
7
|
+
if (!hasHandledError) {
|
|
8
|
+
hasHandledError = true;
|
|
9
|
+
await npoPlayer.npoPlayerServices.handleError(playerContext, status);
|
|
10
|
+
}
|
|
11
|
+
throw new Error(message);
|
|
12
|
+
};
|
|
13
|
+
try {
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
const { signal } = controller;
|
|
16
|
+
const timeout = setTimeout(() => {
|
|
17
|
+
controller.abort();
|
|
18
|
+
}, 5000);
|
|
19
|
+
const response = await fetch(removeTrailingSlash(payload.baseURL) + '/stream-link', {
|
|
20
|
+
method: 'post',
|
|
21
|
+
headers: {
|
|
22
|
+
'Accept': '*/*',
|
|
23
|
+
'Authorization': payload.jwt,
|
|
24
|
+
'Content-Type': 'application/json'
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify(payload.data),
|
|
27
|
+
signal
|
|
28
|
+
});
|
|
29
|
+
clearTimeout(timeout);
|
|
30
|
+
const streamApiResponse = await response.json();
|
|
31
|
+
if (response.ok && streamApiResponse && typeof streamApiResponse === 'object') {
|
|
32
|
+
return streamApiResponse;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const status = streamApiResponse?.status || 500;
|
|
36
|
+
return await handleStreamError(status, genericError);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (!hasHandledError) {
|
|
41
|
+
const errorMessage = error instanceof Error && error.message === 'AbortError'
|
|
42
|
+
? 'aborterror'
|
|
43
|
+
: 'Dit item on niet worden geladen. Het ophalen van de stream duurde te lang.';
|
|
44
|
+
return await handleStreamError(500, errorMessage);
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { fetchStream } from './fetchStream';
|
|
2
|
+
import { createMockNpoPlayer, createPlayerContextMock } from '../../../tests/mocks/playerContextMock';
|
|
3
|
+
describe('fetchStream', () => {
|
|
4
|
+
let mockPlayerContext;
|
|
5
|
+
let mockNpoPlayer;
|
|
6
|
+
const mockPayload = {
|
|
7
|
+
baseURL: 'https://api.example.com',
|
|
8
|
+
jwt: 'mock-jwt-token',
|
|
9
|
+
data: { some: 'data' }
|
|
10
|
+
};
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
jest.clearAllMocks();
|
|
13
|
+
mockNpoPlayer = createMockNpoPlayer({
|
|
14
|
+
npoPlayerServices: {
|
|
15
|
+
handleError: jest.fn()
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
mockPlayerContext = createPlayerContextMock({
|
|
19
|
+
npoPlayer: mockNpoPlayer
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
it('returns a StreamObject when the fetch is successful', async () => {
|
|
23
|
+
const mockStreamObject = { streamUrl: 'https://stream.example.com' };
|
|
24
|
+
global.fetch = jest.fn().mockResolvedValue({
|
|
25
|
+
ok: true,
|
|
26
|
+
json: jest.fn().mockResolvedValue(mockStreamObject)
|
|
27
|
+
});
|
|
28
|
+
const result = await fetchStream(mockPlayerContext, mockPayload);
|
|
29
|
+
expect(result).toEqual(mockStreamObject);
|
|
30
|
+
expect(global.fetch).toHaveBeenCalledWith('https://api.example.com/stream-link', expect.objectContaining({
|
|
31
|
+
method: 'post',
|
|
32
|
+
headers: expect.objectContaining({
|
|
33
|
+
'Authorization': mockPayload.jwt,
|
|
34
|
+
'Content-Type': 'application/json'
|
|
35
|
+
}),
|
|
36
|
+
body: JSON.stringify(mockPayload.data)
|
|
37
|
+
}));
|
|
38
|
+
expect(mockNpoPlayer.npoPlayerServices.handleError).not.toHaveBeenCalled();
|
|
39
|
+
});
|
|
40
|
+
it('calls handleError with 402 status and throws an error', async () => {
|
|
41
|
+
global.fetch = jest.fn().mockResolvedValue({
|
|
42
|
+
ok: false,
|
|
43
|
+
json: jest.fn().mockResolvedValue({ status: 402 })
|
|
44
|
+
});
|
|
45
|
+
await expect(fetchStream(mockPlayerContext, mockPayload)).rejects.toThrow('Dit item on niet worden geladen.');
|
|
46
|
+
expect(mockNpoPlayer.npoPlayerServices.handleError).toHaveBeenCalledWith(mockPlayerContext, 402);
|
|
47
|
+
});
|
|
48
|
+
it('calls handleError with 500 for timeout (AbortError)', async () => {
|
|
49
|
+
global.fetch = jest.fn().mockImplementation(() => new Promise((_, reject) => reject(new Error('AbortError'))));
|
|
50
|
+
await expect(fetchStream(mockPlayerContext, mockPayload)).rejects.toThrow('aborterror');
|
|
51
|
+
expect(mockNpoPlayer.npoPlayerServices.handleError).toHaveBeenCalledWith(mockPlayerContext, 500);
|
|
52
|
+
});
|
|
53
|
+
it('calls handleError with 500 for unexpected errors', async () => {
|
|
54
|
+
global.fetch = jest.fn().mockRejectedValue(new Error('Unexpected error'));
|
|
55
|
+
await expect(fetchStream(mockPlayerContext, mockPayload)).rejects.toThrow('Dit item on niet worden geladen. Het ophalen van de stream duurde te lang.');
|
|
56
|
+
expect(mockNpoPlayer.npoPlayerServices.handleError).toHaveBeenCalledWith(mockPlayerContext, 500);
|
|
57
|
+
});
|
|
58
|
+
it('clears the timeout if fetch resolves before timeout', async () => {
|
|
59
|
+
jest.useFakeTimers();
|
|
60
|
+
const mockStreamObject = { streamUrl: 'https://stream.example.com' };
|
|
61
|
+
global.fetch = jest.fn().mockResolvedValue({
|
|
62
|
+
ok: true,
|
|
63
|
+
json: jest.fn().mockResolvedValue(mockStreamObject)
|
|
64
|
+
});
|
|
65
|
+
const result = await fetchStream(mockPlayerContext, mockPayload);
|
|
66
|
+
jest.runOnlyPendingTimers();
|
|
67
|
+
expect(result).toEqual(mockStreamObject);
|
|
68
|
+
jest.useRealTimers();
|
|
69
|
+
});
|
|
70
|
+
});
|
package/lib/{js/tracking/handlers/eventbinding.js → services/trackingHandlers/eventBinding.js}
RENAMED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { PlayerEvent, ViewMode } from 'bitmovin-player';
|
|
2
|
-
import { logEvent } from './
|
|
2
|
+
import { logEvent } from './eventLogging';
|
|
3
3
|
const logEventHandlers = new Map();
|
|
4
|
-
export function bindPlayerEvents(
|
|
4
|
+
export function bindPlayerEvents(playerContext) {
|
|
5
|
+
const { npoPlayer } = playerContext;
|
|
6
|
+
const { player, streamObject } = npoPlayer;
|
|
5
7
|
if (player == undefined)
|
|
6
8
|
return;
|
|
7
|
-
const isLiveStream =
|
|
9
|
+
const isLiveStream = streamObject.stream.isLiveStream;
|
|
8
10
|
let isNewSource = true;
|
|
9
11
|
let data = {};
|
|
10
12
|
const timeDifference = (time) => {
|
|
@@ -16,10 +18,10 @@ export function bindPlayerEvents(npoPlayer, player) {
|
|
|
16
18
|
const currentTime = isLiveStream ? +timeOffset : +threeDecimalTime;
|
|
17
19
|
data = { stream_position: currentTime };
|
|
18
20
|
};
|
|
19
|
-
const logEventHandler = (
|
|
21
|
+
const logEventHandler = (event) => {
|
|
20
22
|
return (e) => {
|
|
21
23
|
timeDifference(e.time);
|
|
22
|
-
logEvent(
|
|
24
|
+
logEvent({ playerContext, event, data });
|
|
23
25
|
};
|
|
24
26
|
};
|
|
25
27
|
const seekHandler = (e) => {
|
|
@@ -37,50 +39,50 @@ export function bindPlayerEvents(npoPlayer, player) {
|
|
|
37
39
|
stream_position: e.seekTarget
|
|
38
40
|
};
|
|
39
41
|
}
|
|
40
|
-
logEvent(
|
|
42
|
+
logEvent({ playerContext, event: 'seek', data });
|
|
41
43
|
};
|
|
42
44
|
const handleSourceLoaded = (e) => {
|
|
43
45
|
timeDifference(e.time);
|
|
44
46
|
isNewSource = true;
|
|
45
47
|
if (isLiveStream) {
|
|
46
|
-
logEvent(
|
|
48
|
+
logEvent({ playerContext, event: 'stop', data });
|
|
47
49
|
}
|
|
48
50
|
};
|
|
49
51
|
const handlePlay = (e) => {
|
|
50
52
|
timeDifference(e.time);
|
|
51
53
|
if (!isNewSource && e.issuer !== 'ui-seek') {
|
|
52
|
-
logEvent(
|
|
54
|
+
logEvent({ playerContext, event: 'resume', data });
|
|
53
55
|
}
|
|
54
56
|
};
|
|
55
57
|
const pausedHandler = (e) => {
|
|
56
58
|
timeDifference(e.time);
|
|
57
59
|
if (e.issuer !== 'ui-seek') {
|
|
58
|
-
logEvent(
|
|
60
|
+
logEvent({ playerContext, event: 'pause', data });
|
|
59
61
|
}
|
|
60
62
|
};
|
|
61
63
|
const handleTime = (e) => {
|
|
62
64
|
timeDifference(e.time);
|
|
63
65
|
if (isNewSource && !npoPlayer.adBreakActive) {
|
|
64
|
-
logEvent(
|
|
66
|
+
logEvent({ playerContext, event: 'start', data });
|
|
65
67
|
isNewSource = false;
|
|
66
68
|
}
|
|
67
69
|
else {
|
|
68
|
-
logEvent(
|
|
70
|
+
logEvent({ playerContext, event: 'time', data });
|
|
69
71
|
}
|
|
70
72
|
};
|
|
71
73
|
const handleViewModeChange = (e) => {
|
|
72
74
|
const newViewMode = player.getViewMode();
|
|
73
75
|
timeDifference(e.time);
|
|
74
76
|
if (newViewMode === ViewMode.Fullscreen) {
|
|
75
|
-
logEvent(
|
|
77
|
+
logEvent({ playerContext, event: 'fullscreen', data });
|
|
76
78
|
}
|
|
77
79
|
else {
|
|
78
|
-
logEvent(
|
|
80
|
+
logEvent({ playerContext, event: 'windowed', data });
|
|
79
81
|
}
|
|
80
82
|
};
|
|
81
83
|
const stopBeforeUnload = (e) => {
|
|
82
84
|
timeDifference(e.time);
|
|
83
|
-
logEvent(
|
|
85
|
+
logEvent({ playerContext, event: 'stop', data });
|
|
84
86
|
};
|
|
85
87
|
for (const [key, value] of logEventHandlers) {
|
|
86
88
|
player.off(key, value);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { PlayerEvent, ViewMode } from 'bitmovin-player';
|
|
2
|
+
import { bindPlayerEvents } from './eventBinding';
|
|
3
|
+
import { logEvent } from './eventLogging';
|
|
4
|
+
import { createPlayerContextMock } from '../../../tests/mocks/playerContextMock';
|
|
5
|
+
jest.mock('./eventLogging', () => ({
|
|
6
|
+
logEvent: jest.fn()
|
|
7
|
+
}));
|
|
8
|
+
describe('bindPlayerEvents', () => {
|
|
9
|
+
let mockPlayer;
|
|
10
|
+
let playerContextMock;
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
mockPlayer = {
|
|
13
|
+
on: jest.fn(),
|
|
14
|
+
off: jest.fn(),
|
|
15
|
+
getViewMode: jest.fn().mockReturnValue(ViewMode.Inline)
|
|
16
|
+
};
|
|
17
|
+
playerContextMock = createPlayerContextMock({
|
|
18
|
+
npoPlayer: {
|
|
19
|
+
player: mockPlayer,
|
|
20
|
+
streamObject: {
|
|
21
|
+
stream: { isLiveStream: false }
|
|
22
|
+
},
|
|
23
|
+
adBreakActive: false,
|
|
24
|
+
logEmitter: { emit: jest.fn() }
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
jest.clearAllMocks();
|
|
28
|
+
});
|
|
29
|
+
it('should handle the "beforeunload" event correctly', () => {
|
|
30
|
+
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
|
31
|
+
bindPlayerEvents(playerContextMock);
|
|
32
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith('beforeunload', expect.any(Function));
|
|
33
|
+
const beforeUnloadHandler = addEventListenerSpy.mock.calls.find(([event]) => event === 'beforeunload')?.[1];
|
|
34
|
+
if (beforeUnloadHandler && typeof beforeUnloadHandler === 'function') {
|
|
35
|
+
beforeUnloadHandler({ time: 123 });
|
|
36
|
+
}
|
|
37
|
+
addEventListenerSpy.mockRestore();
|
|
38
|
+
});
|
|
39
|
+
it('should log events when handlers are triggered', () => {
|
|
40
|
+
bindPlayerEvents(playerContextMock);
|
|
41
|
+
const timeChangedHandler = mockPlayer.on.mock.calls.find(([event]) => event === PlayerEvent.TimeChanged)?.[1];
|
|
42
|
+
if (timeChangedHandler && typeof timeChangedHandler === 'function') {
|
|
43
|
+
timeChangedHandler({ time: 456 });
|
|
44
|
+
expect(logEvent).toHaveBeenCalledWith({
|
|
45
|
+
playerContext: playerContextMock,
|
|
46
|
+
event: 'start',
|
|
47
|
+
data: expect.objectContaining({ stream_position: expect.any(Number) })
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
it('should handle seek events correctly', () => {
|
|
52
|
+
bindPlayerEvents(playerContextMock);
|
|
53
|
+
const seekHandler = mockPlayer.on.mock.calls.find(([event]) => event === PlayerEvent.Seek)?.[1];
|
|
54
|
+
if (seekHandler && typeof seekHandler === 'function') {
|
|
55
|
+
seekHandler({
|
|
56
|
+
type: 'seek',
|
|
57
|
+
position: 100,
|
|
58
|
+
seekTarget: 200
|
|
59
|
+
});
|
|
60
|
+
expect(logEvent).toHaveBeenCalledWith({
|
|
61
|
+
playerContext: playerContextMock,
|
|
62
|
+
event: 'seek',
|
|
63
|
+
data: {
|
|
64
|
+
seek_from: 100,
|
|
65
|
+
stream_position: 200
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
it('should handle ViewModeChanged events', () => {
|
|
71
|
+
mockPlayer.getViewMode = jest.fn().mockReturnValueOnce(ViewMode.Fullscreen).mockReturnValueOnce(ViewMode.Inline);
|
|
72
|
+
bindPlayerEvents(playerContextMock);
|
|
73
|
+
const viewModeChangedHandler = mockPlayer.on.mock.calls.find(([event]) => event === PlayerEvent.ViewModeChanged)?.[1];
|
|
74
|
+
if (viewModeChangedHandler && typeof viewModeChangedHandler === 'function') {
|
|
75
|
+
viewModeChangedHandler({ time: 300 });
|
|
76
|
+
expect(logEvent).toHaveBeenCalledWith({
|
|
77
|
+
playerContext: playerContextMock,
|
|
78
|
+
event: 'fullscreen',
|
|
79
|
+
data: expect.objectContaining({ stream_position: expect.any(Number) })
|
|
80
|
+
});
|
|
81
|
+
viewModeChangedHandler({ time: 301 });
|
|
82
|
+
expect(logEvent).toHaveBeenCalledWith({
|
|
83
|
+
playerContext: playerContextMock,
|
|
84
|
+
event: 'windowed',
|
|
85
|
+
data: expect.objectContaining({ stream_position: expect.any(Number) })
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
});
|
package/lib/{js/tracking/handlers/eventlogging.js → services/trackingHandlers/eventLogging.js}
RENAMED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
export function logEvent(
|
|
2
|
-
|
|
1
|
+
export function logEvent({ playerContext, event, data }) {
|
|
2
|
+
const { npoPlayer } = playerContext;
|
|
3
|
+
if (!npoPlayer.player)
|
|
3
4
|
return;
|
|
4
|
-
if (
|
|
5
|
-
|
|
5
|
+
if (npoPlayer.adBreakActive || npoPlayer.player.isCasting())
|
|
6
|
+
return;
|
|
7
|
+
if (!npoPlayer.streamTracker) {
|
|
8
|
+
console.error('No streamTracker available, no tracking will be performed.');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const eventData = data ?? { stream_position: 0 };
|
|
6
12
|
const eventHandlers = {
|
|
7
13
|
start: npoPlayer.streamTracker.start,
|
|
8
14
|
buffering: npoPlayer.streamTracker.buffering,
|
|
@@ -17,10 +23,15 @@ export function logEvent(npoPlayer, event, data) {
|
|
|
17
23
|
windowed: npoPlayer.streamTracker.windowed,
|
|
18
24
|
time: npoPlayer.streamTracker.time,
|
|
19
25
|
seek: () => {
|
|
20
|
-
npoPlayer.streamTracker?.seek(
|
|
26
|
+
npoPlayer.streamTracker?.seek(eventData);
|
|
21
27
|
}
|
|
22
28
|
};
|
|
23
29
|
const streamTrackerHandler = eventHandlers[event];
|
|
24
|
-
npoPlayer.logEmitter.emit('logEvent', event,
|
|
25
|
-
streamTrackerHandler
|
|
30
|
+
npoPlayer.logEmitter.emit('logEvent', event, eventData);
|
|
31
|
+
if (streamTrackerHandler) {
|
|
32
|
+
streamTrackerHandler(eventData);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.warn(`No handler found for event: ${event}`);
|
|
36
|
+
}
|
|
26
37
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { logEvent } from './eventLogging';
|
|
2
|
+
import { createPlayerContextMock, createMockNpoPlayerAPI } from '../../../tests/mocks/playerContextMock';
|
|
3
|
+
describe('logEvent', () => {
|
|
4
|
+
let playerContextMock;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
playerContextMock = createPlayerContextMock({
|
|
7
|
+
npoPlayer: {
|
|
8
|
+
player: createMockNpoPlayerAPI(),
|
|
9
|
+
streamTracker: {
|
|
10
|
+
start: jest.fn(),
|
|
11
|
+
seek: jest.fn()
|
|
12
|
+
},
|
|
13
|
+
logEmitter: {
|
|
14
|
+
emit: jest.fn()
|
|
15
|
+
},
|
|
16
|
+
adBreakActive: false
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
it('should not log event if player is not available', () => {
|
|
21
|
+
playerContextMock.npoPlayer.player = undefined;
|
|
22
|
+
logEvent({ playerContext: playerContextMock, event: 'start' });
|
|
23
|
+
expect(playerContextMock.npoPlayer.streamTracker?.start).not.toHaveBeenCalled();
|
|
24
|
+
expect(playerContextMock.npoPlayer.logEmitter.emit).not.toHaveBeenCalled();
|
|
25
|
+
});
|
|
26
|
+
it('should not log event if streamTracker is not available', () => {
|
|
27
|
+
playerContextMock.npoPlayer.streamTracker = undefined;
|
|
28
|
+
logEvent({ playerContext: playerContextMock, event: 'start' });
|
|
29
|
+
expect(playerContextMock.npoPlayer.logEmitter.emit).not.toHaveBeenCalled();
|
|
30
|
+
});
|
|
31
|
+
it('should not log event if adBreakActive is true', () => {
|
|
32
|
+
playerContextMock.npoPlayer.adBreakActive = true;
|
|
33
|
+
logEvent({ playerContext: playerContextMock, event: 'start' });
|
|
34
|
+
expect(playerContextMock.npoPlayer.streamTracker?.start).not.toHaveBeenCalled();
|
|
35
|
+
expect(playerContextMock.npoPlayer.logEmitter.emit).not.toHaveBeenCalled();
|
|
36
|
+
});
|
|
37
|
+
it('should log event and call the corresponding streamTracker handler', () => {
|
|
38
|
+
logEvent({ playerContext: playerContextMock, event: 'start' });
|
|
39
|
+
expect(playerContextMock.npoPlayer.streamTracker?.start).toHaveBeenCalledWith({ stream_position: 0 });
|
|
40
|
+
expect(playerContextMock.npoPlayer.logEmitter.emit).toHaveBeenCalledWith('logEvent', 'start', {
|
|
41
|
+
stream_position: 0
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
it('should log event and call the seek streamTracker handler with data', () => {
|
|
45
|
+
const data = { position: 20 };
|
|
46
|
+
logEvent({ playerContext: playerContextMock, event: 'seek', data });
|
|
47
|
+
expect(playerContextMock.npoPlayer.streamTracker?.seek).toHaveBeenCalledWith(data);
|
|
48
|
+
expect(playerContextMock.npoPlayer.logEmitter.emit).toHaveBeenCalledWith('logEvent', 'seek', data);
|
|
49
|
+
});
|
|
50
|
+
it('should log event with default data if data is undefined', () => {
|
|
51
|
+
logEvent({ playerContext: playerContextMock, event: 'seek' });
|
|
52
|
+
expect(playerContextMock.npoPlayer.streamTracker?.seek).toHaveBeenCalledWith({ stream_position: 0 });
|
|
53
|
+
expect(playerContextMock.npoPlayer.logEmitter.emit).toHaveBeenCalledWith('logEvent', 'seek', { stream_position: 0 });
|
|
54
|
+
});
|
|
55
|
+
it('should not throw but log a warning for unsupported events', () => {
|
|
56
|
+
console.warn = jest.fn();
|
|
57
|
+
logEvent({ playerContext: playerContextMock, event: 'unsupportedEvent' });
|
|
58
|
+
expect(console.warn).toHaveBeenCalledWith('No handler found for event: unsupportedEvent');
|
|
59
|
+
expect(playerContextMock.npoPlayer.logEmitter.emit).toHaveBeenCalledWith('logEvent', 'unsupportedEvent', {
|
|
60
|
+
stream_position: 0
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { newATInternetPlugin, newGovoltePlugin, newPageTracker, newTag } from '@npotag/tag';
|
|
2
2
|
const npoTagPlugins = [newGovoltePlugin({ maxRetryCount: 5, delayBetweenRetriesInMs: 3000 }), newATInternetPlugin()];
|
|
3
|
-
export function initPlayerTracker(
|
|
3
|
+
export function initPlayerTracker(playerContext) {
|
|
4
|
+
const { npoPlayer } = playerContext;
|
|
4
5
|
if (!npoPlayer.npoTag) {
|
|
5
6
|
npoPlayer.npoTag = {
|
|
6
7
|
npoTagInstance: undefined,
|
|
@@ -9,9 +10,11 @@ export function initPlayerTracker(npoPlayer, _npoTag, _npoTagInstance, _npoTagPa
|
|
|
9
10
|
};
|
|
10
11
|
}
|
|
11
12
|
if (!npoPlayer.npoTag?.npoTagInstance) {
|
|
12
|
-
npoPlayer.npoTag.npoTagInstance =
|
|
13
|
+
npoPlayer.npoTag.npoTagInstance =
|
|
14
|
+
npoPlayer.npoTagInstance ??
|
|
15
|
+
(npoPlayer.npoTagInitialisation ? newTag(npoPlayer.npoTagInitialisation, npoTagPlugins) : undefined);
|
|
13
16
|
}
|
|
14
17
|
if (!npoPlayer.npoTag?.pageTracker && npoPlayer.npoTag?.npoTagInstance) {
|
|
15
|
-
npoPlayer.npoTag.pageTracker =
|
|
18
|
+
npoPlayer.npoTag.pageTracker = npoPlayer.npoTagPageTracker ?? newPageTracker(npoPlayer.npoTag.npoTagInstance);
|
|
16
19
|
}
|
|
17
20
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { newPageTracker, newTag } from '@npotag/tag';
|
|
2
|
+
import { initPlayerTracker } from './playerTrackerInit';
|
|
3
|
+
import { createPlayerContextMock } from '../../../tests/mocks/playerContextMock';
|
|
4
|
+
jest.mock('@npotag/tag', () => ({
|
|
5
|
+
newATInternetPlugin: jest.fn(),
|
|
6
|
+
newGovoltePlugin: jest.fn(),
|
|
7
|
+
newPageTracker: jest.fn(),
|
|
8
|
+
newTag: jest.fn()
|
|
9
|
+
}));
|
|
10
|
+
describe('initPlayerTracker', () => {
|
|
11
|
+
let playerContextMock;
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
playerContextMock = createPlayerContextMock({
|
|
14
|
+
npoPlayer: {
|
|
15
|
+
npoTag: undefined,
|
|
16
|
+
npoTagInitialisation: undefined,
|
|
17
|
+
npoTagInstance: undefined,
|
|
18
|
+
npoTagPageTracker: undefined
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
jest.clearAllMocks();
|
|
22
|
+
});
|
|
23
|
+
it('should initialize npoTag if it is undefined', () => {
|
|
24
|
+
initPlayerTracker(playerContextMock);
|
|
25
|
+
expect(playerContextMock.npoPlayer.npoTag).toBeDefined();
|
|
26
|
+
expect(playerContextMock.npoPlayer.npoTag?.npoTagInstance).toBeUndefined();
|
|
27
|
+
expect(playerContextMock.npoPlayer.npoTag?.pageTracker).toBeUndefined();
|
|
28
|
+
});
|
|
29
|
+
it('should initialize npoTagInstance if npoTagInstance is already provided', () => {
|
|
30
|
+
const mockNpoTagInstance = {};
|
|
31
|
+
playerContextMock.npoPlayer.npoTagInstance = mockNpoTagInstance;
|
|
32
|
+
initPlayerTracker(playerContextMock);
|
|
33
|
+
expect(playerContextMock.npoPlayer.npoTag?.npoTagInstance).toBe(mockNpoTagInstance);
|
|
34
|
+
expect(playerContextMock.npoPlayer.npoTag?.pageTracker).toBeUndefined();
|
|
35
|
+
});
|
|
36
|
+
it('should create a new npoTagInstance if npoTagInitialisation is provided and npoTagInstance is undefined', () => {
|
|
37
|
+
const mockNpoTag = {};
|
|
38
|
+
const mockNewTagInstance = {};
|
|
39
|
+
newTag.mockReturnValue(mockNewTagInstance);
|
|
40
|
+
playerContextMock.npoPlayer.npoTagInitialisation = mockNpoTag;
|
|
41
|
+
initPlayerTracker(playerContextMock);
|
|
42
|
+
expect(newTag).toHaveBeenCalledWith(mockNpoTag, expect.any(Array));
|
|
43
|
+
expect(playerContextMock.npoPlayer.npoTag?.npoTagInstance).toBe(mockNewTagInstance);
|
|
44
|
+
expect(playerContextMock.npoPlayer.npoTag?.pageTracker).toBeUndefined();
|
|
45
|
+
});
|
|
46
|
+
it('should initialize pageTracker if npoTagInstance is present and npoTagPageTracker is provided', () => {
|
|
47
|
+
const mockPageTracker = {};
|
|
48
|
+
const mockNpoTagInstance = {};
|
|
49
|
+
playerContextMock.npoPlayer.npoTagInstance = mockNpoTagInstance;
|
|
50
|
+
playerContextMock.npoPlayer.npoTagPageTracker = mockPageTracker;
|
|
51
|
+
initPlayerTracker(playerContextMock);
|
|
52
|
+
expect(playerContextMock.npoPlayer.npoTag?.pageTracker).toBe(mockPageTracker);
|
|
53
|
+
});
|
|
54
|
+
it('should create a new pageTracker if npoTagPageTracker is undefined', () => {
|
|
55
|
+
const mockNpoTagInstance = {};
|
|
56
|
+
const mockNewPageTracker = {};
|
|
57
|
+
newPageTracker.mockReturnValue(mockNewPageTracker);
|
|
58
|
+
playerContextMock.npoPlayer.npoTagInstance = mockNpoTagInstance;
|
|
59
|
+
initPlayerTracker(playerContextMock);
|
|
60
|
+
expect(newPageTracker).toHaveBeenCalledWith(mockNpoTagInstance);
|
|
61
|
+
expect(playerContextMock.npoPlayer.npoTag?.pageTracker).toBe(mockNewPageTracker);
|
|
62
|
+
});
|
|
63
|
+
it('should not overwrite existing pageTracker', () => {
|
|
64
|
+
const mockPageTracker = {};
|
|
65
|
+
const mockNpoTagInstance = {};
|
|
66
|
+
playerContextMock.npoPlayer.npoTag = {
|
|
67
|
+
npoTagInstance: mockNpoTagInstance,
|
|
68
|
+
pageTracker: mockPageTracker,
|
|
69
|
+
heartbeatInterval: undefined
|
|
70
|
+
};
|
|
71
|
+
initPlayerTracker(playerContextMock);
|
|
72
|
+
expect(playerContextMock.npoPlayer.npoTag?.pageTracker).toBe(mockPageTracker);
|
|
73
|
+
expect(newPageTracker).not.toHaveBeenCalled();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getAnalyticsPrid } from '../../js/utilities/utilities.prid';
|
|
2
|
+
import { getStreamDurationInSeconds } from '../../js/utilities/utilities.stream';
|
|
3
|
+
import { initStreamTracker } from './streamTrackerInit';
|
|
4
|
+
import { bindPlayerEvents } from './eventBinding';
|
|
5
|
+
import { logEvent } from './eventLogging';
|
|
6
|
+
export const startPlayerTracker = function ({ playerContext, source, duration }) {
|
|
7
|
+
const { npoPlayer } = playerContext;
|
|
8
|
+
const { player, sourceConfig, streamObject } = npoPlayer;
|
|
9
|
+
const playerDuration = duration || player?.getDuration() || undefined;
|
|
10
|
+
if (!source) {
|
|
11
|
+
throw new Error('Could not initialize streamTracker, no source specified.');
|
|
12
|
+
}
|
|
13
|
+
const analyticsPrid = getAnalyticsPrid({
|
|
14
|
+
source,
|
|
15
|
+
sourceConfig,
|
|
16
|
+
streamObject
|
|
17
|
+
}) || 'unknown';
|
|
18
|
+
npoPlayer.streamTracker = initStreamTracker({
|
|
19
|
+
playerContext: playerContext,
|
|
20
|
+
duration: getStreamDurationInSeconds({ duration: playerDuration }),
|
|
21
|
+
source: analyticsPrid
|
|
22
|
+
});
|
|
23
|
+
bindPlayerEvents(playerContext);
|
|
24
|
+
logEvent({ playerContext, event: 'load' });
|
|
25
|
+
};
|