@applicaster/quick-brick-player 12.0.0-alpha.3235354579 → 12.0.0-alpha.3262004353
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/quick-brick-player",
|
|
3
|
-
"version": "12.0.0-alpha.
|
|
3
|
+
"version": "12.0.0-alpha.3262004353",
|
|
4
4
|
"description": "Quick Brick Player",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
},
|
|
37
37
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@applicaster/quick-brick-mobile-transport-controls": "12.0.0-rc.
|
|
40
|
-
"@applicaster/quick-brick-tv-transport-controls": "12.0.0-rc.
|
|
41
|
-
"@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.
|
|
42
|
-
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.
|
|
43
|
-
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.
|
|
39
|
+
"@applicaster/quick-brick-mobile-transport-controls": "12.0.0-rc.81",
|
|
40
|
+
"@applicaster/quick-brick-tv-transport-controls": "12.0.0-rc.70",
|
|
41
|
+
"@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.3262004353",
|
|
42
|
+
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.3262004353",
|
|
43
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.3262004353",
|
|
44
44
|
"keymirror": "^0.1.1",
|
|
45
45
|
"query-string": "7.1.3",
|
|
46
46
|
"react-native-web-linear-gradient": "1.1.2",
|
|
@@ -419,6 +419,7 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
419
419
|
startTimestamp={startTimestamp}
|
|
420
420
|
endTimestamp={endTimestamp}
|
|
421
421
|
isDateBasedLiveContent={isDateBasedLiveContent}
|
|
422
|
+
onSkipLive={onSkipLive}
|
|
422
423
|
/>
|
|
423
424
|
|
|
424
425
|
{showCounter && timeLeft >= 0 && (
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
// Disabling for now as lint can't recognise typescript definition here
|
|
2
1
|
/* eslint-disable react/prop-types */
|
|
3
2
|
import * as React from "react";
|
|
4
|
-
import { StyleSheet, View } from "react-native";
|
|
3
|
+
import { Animated, StyleSheet, View } from "react-native";
|
|
5
4
|
import LinearGradient from "../LinearGradient";
|
|
6
5
|
import { getDominantColor, getPalettes } from "../../../utils/utils";
|
|
7
6
|
import { useEffect } from "react";
|
|
@@ -11,7 +10,7 @@ type MagicBGProps = {
|
|
|
11
10
|
image: string;
|
|
12
11
|
fallbackUrl?: string;
|
|
13
12
|
defaultColor: string;
|
|
14
|
-
colors: string[];
|
|
13
|
+
colors: string[];
|
|
15
14
|
};
|
|
16
15
|
|
|
17
16
|
const defaultColors = {
|
|
@@ -66,31 +65,46 @@ export const MagicBG: React.FC<MagicBGProps> = ({
|
|
|
66
65
|
defaultColors.defaultGradientEnd,
|
|
67
66
|
]);
|
|
68
67
|
|
|
68
|
+
const [backgroundColorAnim] = React.useState(new Animated.Value(0)); // from 0 to 1
|
|
69
|
+
const [gradientOpacityAnim] = React.useState(new Animated.Value(0)); // from 0 to 1
|
|
70
|
+
|
|
69
71
|
useEffect(() => {
|
|
72
|
+
const animateColors = () => {
|
|
73
|
+
Animated.timing(backgroundColorAnim, {
|
|
74
|
+
toValue: 1,
|
|
75
|
+
duration: 500,
|
|
76
|
+
useNativeDriver: false,
|
|
77
|
+
}).start();
|
|
78
|
+
|
|
79
|
+
Animated.timing(gradientOpacityAnim, {
|
|
80
|
+
toValue: 1,
|
|
81
|
+
duration: 500,
|
|
82
|
+
useNativeDriver: false,
|
|
83
|
+
}).start();
|
|
84
|
+
};
|
|
85
|
+
|
|
70
86
|
const fetchColors = async () => {
|
|
71
|
-
// Check if colors are provided and not empty
|
|
72
87
|
if (colors && colors.length > 0) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
88
|
+
setGradientColors(colors.slice(0, 2));
|
|
89
|
+
setDominantColor(colors[0]);
|
|
90
|
+
animateColors();
|
|
76
91
|
} else if (image) {
|
|
77
|
-
// If no colors, try fetching from image
|
|
78
92
|
try {
|
|
79
93
|
const { gradientColors, dominantColor } =
|
|
80
94
|
await fetchPaletteAndDominantColor(image);
|
|
81
95
|
|
|
82
96
|
setGradientColors(gradientColors);
|
|
83
97
|
setDominantColor(dominantColor);
|
|
98
|
+
animateColors();
|
|
84
99
|
} catch (error) {
|
|
85
|
-
// If image fetch fails, try fallback URL
|
|
86
100
|
try {
|
|
87
101
|
const { gradientColors, dominantColor } =
|
|
88
102
|
await fetchPaletteAndDominantColor(fallbackUrl);
|
|
89
103
|
|
|
90
104
|
setGradientColors(gradientColors);
|
|
91
105
|
setDominantColor(dominantColor);
|
|
106
|
+
animateColors();
|
|
92
107
|
} catch {
|
|
93
|
-
// If everything fails, use default color
|
|
94
108
|
setGradientColors([
|
|
95
109
|
defaultColors.defaultGradientStart,
|
|
96
110
|
defaultColors.defaultGradientEnd,
|
|
@@ -100,7 +114,6 @@ export const MagicBG: React.FC<MagicBGProps> = ({
|
|
|
100
114
|
}
|
|
101
115
|
}
|
|
102
116
|
} else {
|
|
103
|
-
// If no image or colors, use default color
|
|
104
117
|
setGradientColors([
|
|
105
118
|
defaultColors.defaultGradientStart,
|
|
106
119
|
defaultColors.defaultGradientEnd,
|
|
@@ -113,11 +126,30 @@ export const MagicBG: React.FC<MagicBGProps> = ({
|
|
|
113
126
|
fetchColors();
|
|
114
127
|
}, []);
|
|
115
128
|
|
|
129
|
+
const interpolatedBackgroundColor = backgroundColorAnim.interpolate({
|
|
130
|
+
inputRange: [0, 1],
|
|
131
|
+
outputRange: ["black", dominantColor],
|
|
132
|
+
});
|
|
133
|
+
|
|
116
134
|
return (
|
|
117
|
-
<View
|
|
135
|
+
<Animated.View
|
|
136
|
+
style={[
|
|
137
|
+
styles.container,
|
|
138
|
+
{ backgroundColor: interpolatedBackgroundColor },
|
|
139
|
+
]}
|
|
140
|
+
>
|
|
118
141
|
<View style={styles.fullScreenOverlay} />
|
|
119
|
-
|
|
142
|
+
|
|
143
|
+
<Animated.View
|
|
144
|
+
style={[styles.gradientOverlay, { opacity: gradientOpacityAnim }]}
|
|
145
|
+
>
|
|
146
|
+
<LinearGradient
|
|
147
|
+
colors={gradientColors}
|
|
148
|
+
style={StyleSheet.absoluteFill}
|
|
149
|
+
/>
|
|
150
|
+
</Animated.View>
|
|
151
|
+
|
|
120
152
|
{children}
|
|
121
|
-
</View>
|
|
153
|
+
</Animated.View>
|
|
122
154
|
);
|
|
123
155
|
};
|
|
@@ -22,6 +22,10 @@ export const addQueryParam = (
|
|
|
22
22
|
return `${urlWithoutQuery}?${updatedQueryString}`;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
|
-
export const isValidDate = (dateString: string): boolean => {
|
|
26
|
-
return
|
|
25
|
+
export const isValidDate = (dateString: string | undefined): boolean => {
|
|
26
|
+
return (
|
|
27
|
+
typeof dateString === "string" &&
|
|
28
|
+
dateString.trim() !== "" &&
|
|
29
|
+
dayjs.utc(dateString).isValid()
|
|
30
|
+
);
|
|
27
31
|
};
|
package/src/Player/index.tsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import React from "react";
|
|
5
5
|
import * as R from "ramda";
|
|
6
6
|
|
|
7
|
-
import { findNodeHandle,
|
|
7
|
+
import { findNodeHandle, StyleSheet, View } from "react-native";
|
|
8
8
|
import TransportControlsMobile from "@applicaster/quick-brick-mobile-transport-controls";
|
|
9
9
|
import TransportControlsTV from "@applicaster/quick-brick-tv-transport-controls";
|
|
10
10
|
|
|
@@ -21,8 +21,14 @@ import { PlayerWrapper } from "@applicaster/zapp-react-native-ui-components/Comp
|
|
|
21
21
|
|
|
22
22
|
import { PlayNextOverlay } from "./PlayNextOverlay";
|
|
23
23
|
import { PlayerImageBackground } from "@applicaster/zapp-react-native-ui-components/Components/PlayerImageBackground";
|
|
24
|
+
import { AnalyticsTracker } from "@applicaster/zapp-react-native-utils/analyticsUtils/analyticsTracker";
|
|
24
25
|
|
|
25
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
AD_EVENT,
|
|
28
|
+
GENERAL_EVENT,
|
|
29
|
+
PLAYBACK_EVENT,
|
|
30
|
+
QOS_EVENT,
|
|
31
|
+
} from "@applicaster/zapp-react-native-utils/analyticsUtils/events";
|
|
26
32
|
import { Categories, createLogger, Subsystem } from "../logger";
|
|
27
33
|
import { parseLanguageTracks } from "@applicaster/zapp-react-native-utils/playerUtils/configurationUtils";
|
|
28
34
|
import { DEFAULT_COLORS, SEEK_TIME } from "../utils/const";
|
|
@@ -36,17 +42,7 @@ import {
|
|
|
36
42
|
AnimationComponent,
|
|
37
43
|
ComponentAnimationType,
|
|
38
44
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
39
|
-
import {
|
|
40
|
-
import { PlayerAnalyticsTrackerI } from "@applicaster/zapp-react-native-utils/analyticsUtils/playerAnalyticsTracker";
|
|
41
|
-
|
|
42
|
-
const RNPlayerManager = {
|
|
43
|
-
QuickBrickPlayerPlugin: isApplePlatform()
|
|
44
|
-
? NativeModules.PlayerModule
|
|
45
|
-
: NativeModules.QuickBrickDefaultPlayerModule,
|
|
46
|
-
KalturaPlayerPlugin: isApplePlatform()
|
|
47
|
-
? NativeModules.KalturaPlayerModule
|
|
48
|
-
: NativeModules.QBKalturaPlayerModule,
|
|
49
|
-
};
|
|
45
|
+
import { RNPlayerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/nativePlayerManager";
|
|
50
46
|
|
|
51
47
|
const styles = StyleSheet.create({
|
|
52
48
|
container: { flex: 1 },
|
|
@@ -71,6 +67,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
71
67
|
> {
|
|
72
68
|
public static propTypes = {};
|
|
73
69
|
_root: any;
|
|
70
|
+
analyticsTracker: AnalyticsTracker;
|
|
74
71
|
playerPluginId: string;
|
|
75
72
|
takeParentStyle: Record<any, any>;
|
|
76
73
|
playbackStarted = false;
|
|
@@ -101,17 +98,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
101
98
|
duration: 0,
|
|
102
99
|
};
|
|
103
100
|
|
|
104
|
-
private _tracker: PlayerAnalyticsTrackerI;
|
|
105
|
-
get analyticsTracker() {
|
|
106
|
-
if (!this._tracker) {
|
|
107
|
-
this._tracker = PlayerAnalyticsManager.getInstance().getTracker(
|
|
108
|
-
this.props.playerId
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return this._tracker;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
101
|
constructor(props) {
|
|
116
102
|
super(props);
|
|
117
103
|
this.onVideoLoadCalled = false; // android
|
|
@@ -120,15 +106,14 @@ export default class VideoPlayer extends React.Component<
|
|
|
120
106
|
? { width: "100%", flex: "1 1 auto", objectFit: "contain" }
|
|
121
107
|
: { flexBasis: "auto", flexGrow: 1, flexShrink: 1 };
|
|
122
108
|
|
|
109
|
+
const entry = this.props?.entry;
|
|
110
|
+
this.analyticsTracker = new AnalyticsTracker(entry);
|
|
123
111
|
this.playerPluginId = this.props?.playerPluginIdentifier;
|
|
124
112
|
}
|
|
125
113
|
|
|
126
114
|
componentWillUnmount() {
|
|
127
|
-
this.stopBackgroundPlayback();
|
|
128
|
-
|
|
129
115
|
this.playbackStarted = false;
|
|
130
|
-
|
|
131
|
-
this.analyticsTracker.handleAnalyticEvent(GENERAL_EVENT.session_end);
|
|
116
|
+
this.handleAnalyticEvent(GENERAL_EVENT.session_end);
|
|
132
117
|
this.onPlayerClosed();
|
|
133
118
|
|
|
134
119
|
if (isAndroidPlatform()) {
|
|
@@ -171,6 +156,11 @@ export default class VideoPlayer extends React.Component<
|
|
|
171
156
|
}
|
|
172
157
|
}
|
|
173
158
|
|
|
159
|
+
// For close button
|
|
160
|
+
public closeNativePlayer = () => {
|
|
161
|
+
this.stopBackgroundPlayback();
|
|
162
|
+
};
|
|
163
|
+
|
|
174
164
|
getPlayNextData = () => this.props.playNextData as PlayNextData;
|
|
175
165
|
|
|
176
166
|
/**
|
|
@@ -184,6 +174,27 @@ export default class VideoPlayer extends React.Component<
|
|
|
184
174
|
return this.props.pluginConfiguration;
|
|
185
175
|
};
|
|
186
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Handles analytic events, generates a new analytics tracker and transmits events
|
|
179
|
+
* Passes entry data, and playerState to the tracker for additional context
|
|
180
|
+
* The end result is an event formatted and passed to AnalyticsBridge.postEvent
|
|
181
|
+
* When we get the synthetic event we need to pull the data in the nativeEvent object
|
|
182
|
+
* nativeEvent contains the return value from native
|
|
183
|
+
*/
|
|
184
|
+
handleAnalyticEvent = (event, data = {}) => {
|
|
185
|
+
const entry = this.props?.entry;
|
|
186
|
+
const playerState = this.getState();
|
|
187
|
+
|
|
188
|
+
if (this.analyticsTracker?.handleAnalyticEvent) {
|
|
189
|
+
this.analyticsTracker?.handleAnalyticEvent?.(
|
|
190
|
+
event,
|
|
191
|
+
{ ...data, player_type: this.props.playerPluginIdentifier },
|
|
192
|
+
entry,
|
|
193
|
+
playerState
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
187
198
|
/**
|
|
188
199
|
* This method is for the events that have no implementation in react but are being invoked by native
|
|
189
200
|
* When we get the synthetic event we need to pull the data in the nativeEvent object
|
|
@@ -328,7 +339,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
328
339
|
* Sets either subtitle language, or audio language if we have a selected a new locale.
|
|
329
340
|
* If no locale is set it defaults to system language for audio, and leaves subtitles unaltered.
|
|
330
341
|
*/
|
|
331
|
-
|
|
342
|
+
selectTrack = (selected = null) => {
|
|
332
343
|
const { trackType, id, language } = selected || {};
|
|
333
344
|
|
|
334
345
|
const isOff = language === "Off";
|
|
@@ -387,16 +398,28 @@ export default class VideoPlayer extends React.Component<
|
|
|
387
398
|
};
|
|
388
399
|
|
|
389
400
|
onPlayerPresented = () => {
|
|
390
|
-
this.
|
|
401
|
+
this.handleAnalyticEvent(GENERAL_EVENT.player_presented);
|
|
391
402
|
};
|
|
392
403
|
|
|
393
404
|
onPlayerClosed = () => {
|
|
394
|
-
this.
|
|
405
|
+
this.handleAnalyticEvent(GENERAL_EVENT.player_closed);
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
onPlayerSessionEnd = () => {
|
|
409
|
+
// TODO: Implement method on native android, ios exists
|
|
410
|
+
this.handleAnalyticEvent(GENERAL_EVENT.session_end);
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
onPlayerSessionStart = () => {
|
|
414
|
+
// TODO: Implement method on native android, ios exists
|
|
415
|
+
|
|
416
|
+
this.handleAnalyticEvent(GENERAL_EVENT.session_start);
|
|
395
417
|
};
|
|
396
418
|
|
|
397
419
|
onVideoEnd = () => {
|
|
398
420
|
this.setState({ displayOverlay: !this.state.displayOverlay }, () => {
|
|
399
421
|
if (this.state?.displayOverlay) {
|
|
422
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.complete);
|
|
400
423
|
this.props?.listener?.onVideoEnd({});
|
|
401
424
|
}
|
|
402
425
|
});
|
|
@@ -406,12 +429,15 @@ export default class VideoPlayer extends React.Component<
|
|
|
406
429
|
onVideoError = ({ nativeEvent }) => {
|
|
407
430
|
const { message } = nativeEvent;
|
|
408
431
|
|
|
432
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.error, nativeEvent);
|
|
433
|
+
|
|
409
434
|
return this.props?.listener?.onError(new Error(message));
|
|
410
435
|
};
|
|
411
436
|
|
|
412
437
|
onPlayerPause = ({ nativeEvent = null }) => {
|
|
413
438
|
this.setState({ paused: true });
|
|
414
439
|
this.props?.listener?.onPlayerPause(nativeEvent);
|
|
440
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.pause, nativeEvent);
|
|
415
441
|
};
|
|
416
442
|
|
|
417
443
|
onPlayerResume = ({ nativeEvent = null }) => {
|
|
@@ -422,61 +448,98 @@ export default class VideoPlayer extends React.Component<
|
|
|
422
448
|
|
|
423
449
|
if (isNotAnAd && !resume) {
|
|
424
450
|
this.setState({ resume: true });
|
|
451
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.play, nativeEvent);
|
|
425
452
|
}
|
|
426
453
|
};
|
|
427
454
|
|
|
428
455
|
onPlayerSeekComplete = ({ nativeEvent }) => {
|
|
429
456
|
this.props?.listener?.onPlayerSeekComplete(nativeEvent);
|
|
457
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.seek_complete, nativeEvent);
|
|
430
458
|
};
|
|
431
459
|
|
|
432
460
|
onPlayerSeekStart = ({ nativeEvent }) => {
|
|
433
461
|
this.props?.listener?.onPlayerSeekStart(nativeEvent);
|
|
462
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.seek_start, nativeEvent);
|
|
434
463
|
};
|
|
435
464
|
|
|
436
465
|
onBufferStart = ({ nativeEvent }) => {
|
|
437
466
|
this.props?.listener?.onBufferStart(nativeEvent);
|
|
467
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.buffer_start, nativeEvent);
|
|
438
468
|
};
|
|
439
469
|
|
|
440
470
|
onBufferComplete = ({ nativeEvent }) => {
|
|
441
471
|
this.props?.listener?.onBufferComplete(nativeEvent);
|
|
472
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.buffer_complete, nativeEvent);
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
onPlayerNext = ({ nativeEvent }) => {
|
|
476
|
+
// TODO: Implement method on native
|
|
477
|
+
|
|
478
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.next, nativeEvent);
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
onPlayerPrevious = ({ nativeEvent }) => {
|
|
482
|
+
// TODO: Implement method on native
|
|
483
|
+
|
|
484
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.previous, nativeEvent);
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
onPlayerStop = ({ nativeEvent }) => {
|
|
488
|
+
// TODO: Implement method on native
|
|
489
|
+
|
|
490
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.stop, nativeEvent);
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
onVideoBandwidthUpdate = ({ nativeEvent }) => {
|
|
494
|
+
// TODO: Implement method on native
|
|
495
|
+
|
|
496
|
+
this.handleAnalyticEvent(QOS_EVENT.bitrate_changed, nativeEvent);
|
|
442
497
|
};
|
|
443
498
|
|
|
444
499
|
onAdBegin = ({ nativeEvent }) => {
|
|
445
500
|
this.setState({ isAd: true });
|
|
501
|
+
this.handleAnalyticEvent(AD_EVENT.ad_start, nativeEvent);
|
|
446
502
|
this.props.listener?.onAdBegin?.(nativeEvent);
|
|
447
503
|
};
|
|
448
504
|
|
|
449
505
|
onAdBreakBegin = ({ nativeEvent }) => {
|
|
450
506
|
this.setState({ isAd: true });
|
|
507
|
+
this.handleAnalyticEvent(AD_EVENT.ad_break_start, nativeEvent);
|
|
451
508
|
this.props.listener?.onAdBreakBegin?.(nativeEvent);
|
|
452
509
|
};
|
|
453
510
|
|
|
454
511
|
onAdBreakEnd = ({ nativeEvent }) => {
|
|
455
512
|
this.setState({ isAd: false });
|
|
513
|
+
this.handleAnalyticEvent(AD_EVENT.ad_break_completed, nativeEvent);
|
|
456
514
|
this.props.listener?.onAdBreakEnd?.(nativeEvent);
|
|
457
515
|
};
|
|
458
516
|
|
|
459
517
|
onAdEnd = ({ nativeEvent }) => {
|
|
460
518
|
this.setState({ isAd: false });
|
|
519
|
+
this.handleAnalyticEvent(AD_EVENT.ad_complete, nativeEvent);
|
|
461
520
|
this.props.listener?.onAdEnd?.(nativeEvent);
|
|
462
521
|
};
|
|
463
522
|
|
|
464
523
|
onAdError = ({ nativeEvent }) => {
|
|
465
524
|
this.setState({ isAd: false });
|
|
525
|
+
this.handleAnalyticEvent(AD_EVENT.ad_error, nativeEvent);
|
|
466
526
|
this.props.listener?.onAdError?.(nativeEvent);
|
|
467
527
|
};
|
|
468
528
|
|
|
469
529
|
onAdRequest = ({ nativeEvent }) => {
|
|
530
|
+
this.handleAnalyticEvent(AD_EVENT.ad_request, nativeEvent);
|
|
470
531
|
this.props.listener?.onAdRequest?.(nativeEvent);
|
|
471
532
|
};
|
|
472
533
|
|
|
473
534
|
onAdClicked = ({ nativeEvent }) => {
|
|
535
|
+
this.handleAnalyticEvent(AD_EVENT.ad_clicked, nativeEvent);
|
|
474
536
|
// Broadcast click event
|
|
475
537
|
this.props.playerEvent("ad-clicked", nativeEvent);
|
|
476
538
|
this.props.listener?.onAdClicked?.(nativeEvent);
|
|
477
539
|
};
|
|
478
540
|
|
|
479
541
|
onAdTapped = ({ nativeEvent }) => {
|
|
542
|
+
this.handleAnalyticEvent(AD_EVENT.ad_tapped, nativeEvent);
|
|
480
543
|
// Broadcast click event
|
|
481
544
|
this.props.playerEvent("ad-tapped", nativeEvent);
|
|
482
545
|
this.props.listener?.onAdTapped?.(nativeEvent);
|
|
@@ -589,6 +652,10 @@ export default class VideoPlayer extends React.Component<
|
|
|
589
652
|
}
|
|
590
653
|
|
|
591
654
|
if (!this.state.isAd && !this.onVideoLoadCalled) {
|
|
655
|
+
this.handleAnalyticEvent(PLAYBACK_EVENT.load_video, {
|
|
656
|
+
player_type: this.props.playerPluginIdentifier,
|
|
657
|
+
});
|
|
658
|
+
|
|
592
659
|
// TODO: Hack, needs to remove
|
|
593
660
|
this.onVideoLoadCalled = true;
|
|
594
661
|
}
|
|
@@ -856,6 +923,8 @@ export default class VideoPlayer extends React.Component<
|
|
|
856
923
|
onPlayerResume: this.onPlayerResume, // play
|
|
857
924
|
onPlayerSeekComplete: this.onPlayerSeekComplete, // seek_complete
|
|
858
925
|
onPlayerSeekStart: this.onPlayerSeekStart, // seek_start
|
|
926
|
+
onPlayerSessionEnd: this.onPlayerSessionEnd, // session_end
|
|
927
|
+
onPlayerSessionStart: this.onPlayerSessionStart, // session_start
|
|
859
928
|
};
|
|
860
929
|
|
|
861
930
|
const lifecycleEvents = {
|
|
@@ -888,6 +957,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
888
957
|
onTimedMetadata: this.unHandledEvent("onTimedMetadata"),
|
|
889
958
|
onTracksChanged: this.onTracksChanged,
|
|
890
959
|
eventSubtitlesChange: this.unHandledEvent("eventSubtitlesChange"),
|
|
960
|
+
onVideoBandwidthUpdate: this.onVideoBandwidthUpdate,
|
|
891
961
|
};
|
|
892
962
|
|
|
893
963
|
const playerSystemEvents = {
|
|
@@ -907,6 +977,9 @@ export default class VideoPlayer extends React.Component<
|
|
|
907
977
|
const unsupportedEvents = {
|
|
908
978
|
onBufferComplete: this.onBufferComplete, // buffer_complete
|
|
909
979
|
onBufferStart: this.onBufferStart, // buffer_start
|
|
980
|
+
onPlayerNext: this.onPlayerNext, // next
|
|
981
|
+
onPlayerPrevious: this.onPlayerPrevious, // previous
|
|
982
|
+
onPlayerStop: this.onPlayerStop, // stop
|
|
910
983
|
};
|
|
911
984
|
|
|
912
985
|
const nativeEvents = {
|