@applicaster/quick-brick-player 12.0.0-alpha.5553532911 → 12.0.0-alpha.5624518702
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.5624518702",
|
|
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-
|
|
40
|
-
"@applicaster/quick-brick-tv-transport-controls": "
|
|
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-alpha.5624518702",
|
|
40
|
+
"@applicaster/quick-brick-tv-transport-controls": "12.0.0-alpha.5624518702",
|
|
41
|
+
"@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.5624518702",
|
|
42
|
+
"@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5624518702",
|
|
43
|
+
"@applicaster/zapp-react-native-utils": "12.0.0-alpha.5624518702",
|
|
44
44
|
"keymirror": "^0.1.1",
|
|
45
45
|
"query-string": "7.1.3",
|
|
46
46
|
"react-native-web-linear-gradient": "1.1.2",
|
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
AnimatedScrollModal,
|
|
33
33
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
34
34
|
import { PADDING_HORIZONTAL } from "./Layout/defaultLayoutsConts";
|
|
35
|
+
import { toNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
35
36
|
|
|
36
37
|
const { log_debug } = createLogger({
|
|
37
38
|
subsystem: "UIComponent",
|
|
@@ -54,7 +55,7 @@ type Configuration = {
|
|
|
54
55
|
};
|
|
55
56
|
|
|
56
57
|
type Props = {
|
|
57
|
-
children
|
|
58
|
+
children: React.ReactNode;
|
|
58
59
|
inline?: boolean;
|
|
59
60
|
docked?: boolean;
|
|
60
61
|
configuration: Configuration;
|
|
@@ -294,7 +295,7 @@ export const AudioPlayerWrapper: React.FC<Props> = (props: Props) => {
|
|
|
294
295
|
playerState.isPaused ? player?.play() : player.pause();
|
|
295
296
|
}, [playerState, player]);
|
|
296
297
|
|
|
297
|
-
const seekDuration =
|
|
298
|
+
const seekDuration = toNumberWithDefault(10, value("seek_duration"));
|
|
298
299
|
|
|
299
300
|
const onRewindButtonPress = React.useCallback(() => {
|
|
300
301
|
player?.rewind(seekDuration);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
import { View } from "react-native";
|
|
4
|
+
import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
|
|
4
5
|
|
|
5
6
|
import {
|
|
6
7
|
ProgressBar,
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
ComponentAnimationType,
|
|
34
35
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
35
36
|
import DockedLayout from "./DockedLayout";
|
|
37
|
+
import { isValidDate } from "../../Utils";
|
|
36
38
|
|
|
37
39
|
type Dimensions = {
|
|
38
40
|
width: number;
|
|
@@ -79,7 +81,7 @@ type LayoutProps = {
|
|
|
79
81
|
|
|
80
82
|
const Styles = {
|
|
81
83
|
container: { flex: 1 },
|
|
82
|
-
tabletContainer: (isPortraitMode) => ({
|
|
84
|
+
tabletContainer: (isPortraitMode: boolean) => ({
|
|
83
85
|
flex: 1,
|
|
84
86
|
alignItems: "center",
|
|
85
87
|
justifyContent: isPortraitMode ? "center" : "flex-start",
|
|
@@ -109,10 +111,10 @@ const Styles = {
|
|
|
109
111
|
};
|
|
110
112
|
},
|
|
111
113
|
backgroundImageContainerImageStyle: (
|
|
112
|
-
isTablet,
|
|
113
|
-
docked,
|
|
114
|
-
startComponentsAnimation,
|
|
115
|
-
isActiveGesture
|
|
114
|
+
isTablet: boolean,
|
|
115
|
+
docked: boolean,
|
|
116
|
+
startComponentsAnimation: boolean,
|
|
117
|
+
isActiveGesture: boolean
|
|
116
118
|
) => ({
|
|
117
119
|
borderRadius:
|
|
118
120
|
(startComponentsAnimation && isActiveGesture) || docked
|
|
@@ -190,8 +192,31 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
190
192
|
|
|
191
193
|
let showFullControls = !controller?.isAd();
|
|
192
194
|
|
|
195
|
+
const startTime = entry.extensions?.live?.start_time;
|
|
196
|
+
const endTime = entry.extensions?.live?.end_time;
|
|
197
|
+
|
|
198
|
+
const hasValidStartTime = isValidDate(startTime);
|
|
199
|
+
const hasValidEndTime = isValidDate(endTime);
|
|
200
|
+
|
|
201
|
+
const isDateBasedLiveContent =
|
|
202
|
+
isLiveContent && hasValidStartTime && hasValidEndTime;
|
|
203
|
+
|
|
204
|
+
const needsToShowProgressBar =
|
|
205
|
+
(isLiveContent &&
|
|
206
|
+
(Boolean(value("liveSeekingEnabled")) || isDateBasedLiveContent)) ||
|
|
207
|
+
!isLiveContent;
|
|
208
|
+
|
|
209
|
+
const startTimestamp = hasValidStartTime
|
|
210
|
+
? dayjs.utc(startTime!).valueOf()
|
|
211
|
+
: undefined;
|
|
212
|
+
|
|
213
|
+
const endTimestamp = hasValidEndTime
|
|
214
|
+
? dayjs.utc(endTime!).valueOf()
|
|
215
|
+
: undefined;
|
|
216
|
+
|
|
193
217
|
if (isLiveContent) {
|
|
194
218
|
const seekEnabled = Boolean(value("liveSeekingEnabled"));
|
|
219
|
+
|
|
195
220
|
showFullControls = !!(controller?.hasSeekableDuration?.() && seekEnabled);
|
|
196
221
|
}
|
|
197
222
|
|
|
@@ -221,12 +246,14 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
221
246
|
|
|
222
247
|
const rewind = rewindButton({
|
|
223
248
|
isTablet,
|
|
224
|
-
onPress: controller?.
|
|
249
|
+
onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
|
|
225
250
|
});
|
|
226
251
|
|
|
227
252
|
const forward = forwardButton({
|
|
228
253
|
isTablet,
|
|
229
|
-
onPress: controller?.
|
|
254
|
+
onPress: controller?.hasSeekableDuration?.()
|
|
255
|
+
? onForwardButtonPress
|
|
256
|
+
: null,
|
|
230
257
|
});
|
|
231
258
|
|
|
232
259
|
const speed = speedButton({
|
|
@@ -255,7 +282,6 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
255
282
|
return [skipToStart, rewind, play, forward, skipToLive];
|
|
256
283
|
}
|
|
257
284
|
|
|
258
|
-
// Temporary empty button until we add sleep button. It will ensure the buttons will not break in their position
|
|
259
285
|
return [speed, rewind, play, forward, sleep];
|
|
260
286
|
}, [
|
|
261
287
|
playerState,
|
|
@@ -276,15 +302,12 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
276
302
|
|
|
277
303
|
useEffect(() => {
|
|
278
304
|
if (showCounter && sleepTimerDate !== 0) {
|
|
279
|
-
// Setting the initial timeLeft based on sleepTimerDate
|
|
280
305
|
setTimeLeft(sleepTimerDate - Date.now());
|
|
281
306
|
|
|
282
|
-
// Setting up an interval to update the remaining time every second
|
|
283
307
|
const intervalId = setInterval(() => {
|
|
284
308
|
setTimeLeft(() => {
|
|
285
309
|
const newTimeLeft = sleepTimerDate - Date.now();
|
|
286
310
|
|
|
287
|
-
// If the new remaining time is less than or equal to 0, clear the interval and trigger the cancelSleepTimer function
|
|
288
311
|
if (newTimeLeft <= 0) {
|
|
289
312
|
clearInterval(intervalId);
|
|
290
313
|
|
|
@@ -292,32 +315,24 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
292
315
|
|
|
293
316
|
return 0;
|
|
294
317
|
} else {
|
|
295
|
-
// Otherwise, update the state with the new remaining time
|
|
296
318
|
return newTimeLeft;
|
|
297
319
|
}
|
|
298
320
|
});
|
|
299
321
|
}, 1000);
|
|
300
322
|
|
|
301
|
-
// Clearing the interval when the component unmounts or dependencies change
|
|
302
323
|
return () => clearInterval(intervalId);
|
|
303
324
|
} else {
|
|
304
|
-
// Ensure the timeLeft state is set correctly if showCounter is false
|
|
305
325
|
setTimeLeft(0);
|
|
306
326
|
}
|
|
307
327
|
}, [sleepTimerDate, showCounter, cancelSleepTimer]);
|
|
308
328
|
|
|
309
329
|
const Separator = () => <View style={Styles.separator} />;
|
|
310
330
|
|
|
311
|
-
const liveSeekingEnabled = value("liveSeekingEnabled");
|
|
312
|
-
|
|
313
|
-
const needsToShowProgressBar =
|
|
314
|
-
(isLiveContent && liveSeekingEnabled) || !isLiveContent;
|
|
315
|
-
|
|
316
331
|
const defaultImageDimensions = React.useMemo(
|
|
317
332
|
() =>
|
|
318
333
|
defaultDimensions &&
|
|
319
334
|
Styles.backgroundImageContainer(defaultDimensions, isTablet),
|
|
320
|
-
[defaultDimensions]
|
|
335
|
+
[defaultDimensions, isTablet]
|
|
321
336
|
);
|
|
322
337
|
|
|
323
338
|
const { isActiveGesture, startComponentsAnimation } =
|
|
@@ -341,7 +356,7 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
341
356
|
</AnimationComponent>
|
|
342
357
|
<AnimationComponent
|
|
343
358
|
animationType={ComponentAnimationType.moveUpComponent}
|
|
344
|
-
style={isTablet ? Styles.playerImageWrapper :
|
|
359
|
+
style={isTablet ? Styles.playerImageWrapper : undefined}
|
|
345
360
|
>
|
|
346
361
|
<AnimationComponent
|
|
347
362
|
animationType={ComponentAnimationType.moveComponentHorizontal}
|
|
@@ -356,7 +371,7 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
356
371
|
}
|
|
357
372
|
: null,
|
|
358
373
|
}}
|
|
359
|
-
style={isTablet ? Styles.alignItemsCenter :
|
|
374
|
+
style={isTablet ? Styles.alignItemsCenter : undefined}
|
|
360
375
|
>
|
|
361
376
|
<PlayerImageBackground
|
|
362
377
|
entry={entry}
|
|
@@ -376,7 +391,7 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
376
391
|
<View
|
|
377
392
|
style={[
|
|
378
393
|
Styles.paddingHorizontal,
|
|
379
|
-
isTablet ? Styles.tabletLayout :
|
|
394
|
+
isTablet ? Styles.tabletLayout : undefined,
|
|
380
395
|
]}
|
|
381
396
|
>
|
|
382
397
|
{!docked && (
|
|
@@ -401,6 +416,9 @@ export default function DefaultLayout(props: LayoutProps) {
|
|
|
401
416
|
playerState={playerState}
|
|
402
417
|
disableFullscreen={true}
|
|
403
418
|
sliderStyle={2}
|
|
419
|
+
startTimestamp={startTimestamp}
|
|
420
|
+
endTimestamp={endTimestamp}
|
|
421
|
+
isDateBasedLiveContent={isDateBasedLiveContent}
|
|
404
422
|
/>
|
|
405
423
|
|
|
406
424
|
{showCounter && timeLeft >= 0 && (
|
|
@@ -1,26 +1,5 @@
|
|
|
1
1
|
import queryString from "query-string";
|
|
2
|
-
|
|
3
|
-
export const toTypeString = (obj) => {
|
|
4
|
-
switch (typeof obj) {
|
|
5
|
-
case "object":
|
|
6
|
-
return obj instanceof Date ? obj.toISOString() : JSON.stringify(obj); // object, null
|
|
7
|
-
case "undefined":
|
|
8
|
-
return "";
|
|
9
|
-
default:
|
|
10
|
-
// boolean, number, string
|
|
11
|
-
return obj.toString();
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export const stringsOnlyObject = (obj) => {
|
|
16
|
-
const strObj = {};
|
|
17
|
-
|
|
18
|
-
Object.keys(obj).forEach((x) => {
|
|
19
|
-
strObj[x] = toTypeString(obj[x]);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
return strObj;
|
|
23
|
-
};
|
|
2
|
+
import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
|
|
24
3
|
|
|
25
4
|
export const getLiveUrl = (url: string) => {
|
|
26
5
|
// Use the replace method with a regular expression to replace all instances of subClass with livePage
|
|
@@ -42,3 +21,7 @@ export const addQueryParam = (
|
|
|
42
21
|
|
|
43
22
|
return `${urlWithoutQuery}?${updatedQueryString}`;
|
|
44
23
|
};
|
|
24
|
+
|
|
25
|
+
export const isValidDate = (dateString: string): boolean => {
|
|
26
|
+
return dateString.trim() !== "" && dayjs.utc(dateString).isValid();
|
|
27
|
+
};
|
package/src/Player/index.tsx
CHANGED
|
@@ -21,14 +21,8 @@ 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";
|
|
25
24
|
|
|
26
|
-
import {
|
|
27
|
-
AD_EVENT,
|
|
28
|
-
GENERAL_EVENT,
|
|
29
|
-
PLAYBACK_EVENT,
|
|
30
|
-
QOS_EVENT,
|
|
31
|
-
} from "@applicaster/zapp-react-native-utils/analyticsUtils/events";
|
|
25
|
+
import { GENERAL_EVENT } from "@applicaster/zapp-react-native-utils/analyticsUtils/events";
|
|
32
26
|
import { Categories, createLogger, Subsystem } from "../logger";
|
|
33
27
|
import { parseLanguageTracks } from "@applicaster/zapp-react-native-utils/playerUtils/configurationUtils";
|
|
34
28
|
import { DEFAULT_COLORS, SEEK_TIME } from "../utils/const";
|
|
@@ -42,6 +36,8 @@ import {
|
|
|
42
36
|
AnimationComponent,
|
|
43
37
|
ComponentAnimationType,
|
|
44
38
|
} from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
|
|
39
|
+
import { PlayerAnalyticsManager } from "@applicaster/zapp-react-native-utils/analyticsUtils/PlayerAnalyticsManager";
|
|
40
|
+
import { PlayerAnalyticsTrackerI } from "@applicaster/zapp-react-native-utils/analyticsUtils/playerAnalyticsTracker";
|
|
45
41
|
|
|
46
42
|
const RNPlayerManager = {
|
|
47
43
|
QuickBrickPlayerPlugin: isApplePlatform()
|
|
@@ -75,7 +71,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
75
71
|
> {
|
|
76
72
|
public static propTypes = {};
|
|
77
73
|
_root: any;
|
|
78
|
-
analyticsTracker: AnalyticsTracker;
|
|
79
74
|
playerPluginId: string;
|
|
80
75
|
takeParentStyle: Record<any, any>;
|
|
81
76
|
playbackStarted = false;
|
|
@@ -106,6 +101,17 @@ export default class VideoPlayer extends React.Component<
|
|
|
106
101
|
duration: 0,
|
|
107
102
|
};
|
|
108
103
|
|
|
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
|
+
|
|
109
115
|
constructor(props) {
|
|
110
116
|
super(props);
|
|
111
117
|
this.onVideoLoadCalled = false; // android
|
|
@@ -114,8 +120,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
114
120
|
? { width: "100%", flex: "1 1 auto", objectFit: "contain" }
|
|
115
121
|
: { flexBasis: "auto", flexGrow: 1, flexShrink: 1 };
|
|
116
122
|
|
|
117
|
-
const entry = this.props?.entry;
|
|
118
|
-
this.analyticsTracker = new AnalyticsTracker(entry);
|
|
119
123
|
this.playerPluginId = this.props?.playerPluginIdentifier;
|
|
120
124
|
}
|
|
121
125
|
|
|
@@ -123,7 +127,8 @@ export default class VideoPlayer extends React.Component<
|
|
|
123
127
|
this.stopBackgroundPlayback();
|
|
124
128
|
|
|
125
129
|
this.playbackStarted = false;
|
|
126
|
-
|
|
130
|
+
|
|
131
|
+
this.analyticsTracker.handleAnalyticEvent(GENERAL_EVENT.session_end);
|
|
127
132
|
this.onPlayerClosed();
|
|
128
133
|
|
|
129
134
|
if (isAndroidPlatform()) {
|
|
@@ -179,27 +184,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
179
184
|
return this.props.pluginConfiguration;
|
|
180
185
|
};
|
|
181
186
|
|
|
182
|
-
/**
|
|
183
|
-
* Handles analytic events, generates a new analytics tracker and transmits events
|
|
184
|
-
* Passes entry data, and playerState to the tracker for additional context
|
|
185
|
-
* The end result is an event formatted and passed to AnalyticsBridge.postEvent
|
|
186
|
-
* When we get the synthetic event we need to pull the data in the nativeEvent object
|
|
187
|
-
* nativeEvent contains the return value from native
|
|
188
|
-
*/
|
|
189
|
-
handleAnalyticEvent = (event, data = {}) => {
|
|
190
|
-
const entry = this.props?.entry;
|
|
191
|
-
const playerState = this.getState();
|
|
192
|
-
|
|
193
|
-
if (this.analyticsTracker?.handleAnalyticEvent) {
|
|
194
|
-
this.analyticsTracker?.handleAnalyticEvent?.(
|
|
195
|
-
event,
|
|
196
|
-
{ ...data, player_type: this.props.playerPluginIdentifier },
|
|
197
|
-
entry,
|
|
198
|
-
playerState
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
|
|
203
187
|
/**
|
|
204
188
|
* This method is for the events that have no implementation in react but are being invoked by native
|
|
205
189
|
* When we get the synthetic event we need to pull the data in the nativeEvent object
|
|
@@ -403,28 +387,16 @@ export default class VideoPlayer extends React.Component<
|
|
|
403
387
|
};
|
|
404
388
|
|
|
405
389
|
onPlayerPresented = () => {
|
|
406
|
-
this.handleAnalyticEvent(GENERAL_EVENT.player_presented);
|
|
390
|
+
this.analyticsTracker?.handleAnalyticEvent(GENERAL_EVENT.player_presented);
|
|
407
391
|
};
|
|
408
392
|
|
|
409
393
|
onPlayerClosed = () => {
|
|
410
|
-
this.handleAnalyticEvent(GENERAL_EVENT.player_closed);
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
onPlayerSessionEnd = () => {
|
|
414
|
-
// TODO: Implement method on native android, ios exists
|
|
415
|
-
this.handleAnalyticEvent(GENERAL_EVENT.session_end);
|
|
416
|
-
};
|
|
417
|
-
|
|
418
|
-
onPlayerSessionStart = () => {
|
|
419
|
-
// TODO: Implement method on native android, ios exists
|
|
420
|
-
|
|
421
|
-
this.handleAnalyticEvent(GENERAL_EVENT.session_start);
|
|
394
|
+
this.analyticsTracker?.handleAnalyticEvent(GENERAL_EVENT.player_closed);
|
|
422
395
|
};
|
|
423
396
|
|
|
424
397
|
onVideoEnd = () => {
|
|
425
398
|
this.setState({ displayOverlay: !this.state.displayOverlay }, () => {
|
|
426
399
|
if (this.state?.displayOverlay) {
|
|
427
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.complete);
|
|
428
400
|
this.props?.listener?.onVideoEnd({});
|
|
429
401
|
}
|
|
430
402
|
});
|
|
@@ -434,15 +406,12 @@ export default class VideoPlayer extends React.Component<
|
|
|
434
406
|
onVideoError = ({ nativeEvent }) => {
|
|
435
407
|
const { message } = nativeEvent;
|
|
436
408
|
|
|
437
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.error, nativeEvent);
|
|
438
|
-
|
|
439
409
|
return this.props?.listener?.onError(new Error(message));
|
|
440
410
|
};
|
|
441
411
|
|
|
442
412
|
onPlayerPause = ({ nativeEvent = null }) => {
|
|
443
413
|
this.setState({ paused: true });
|
|
444
414
|
this.props?.listener?.onPlayerPause(nativeEvent);
|
|
445
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.pause, nativeEvent);
|
|
446
415
|
};
|
|
447
416
|
|
|
448
417
|
onPlayerResume = ({ nativeEvent = null }) => {
|
|
@@ -453,98 +422,61 @@ export default class VideoPlayer extends React.Component<
|
|
|
453
422
|
|
|
454
423
|
if (isNotAnAd && !resume) {
|
|
455
424
|
this.setState({ resume: true });
|
|
456
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.play, nativeEvent);
|
|
457
425
|
}
|
|
458
426
|
};
|
|
459
427
|
|
|
460
428
|
onPlayerSeekComplete = ({ nativeEvent }) => {
|
|
461
429
|
this.props?.listener?.onPlayerSeekComplete(nativeEvent);
|
|
462
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.seek_complete, nativeEvent);
|
|
463
430
|
};
|
|
464
431
|
|
|
465
432
|
onPlayerSeekStart = ({ nativeEvent }) => {
|
|
466
433
|
this.props?.listener?.onPlayerSeekStart(nativeEvent);
|
|
467
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.seek_start, nativeEvent);
|
|
468
434
|
};
|
|
469
435
|
|
|
470
436
|
onBufferStart = ({ nativeEvent }) => {
|
|
471
437
|
this.props?.listener?.onBufferStart(nativeEvent);
|
|
472
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.buffer_start, nativeEvent);
|
|
473
438
|
};
|
|
474
439
|
|
|
475
440
|
onBufferComplete = ({ nativeEvent }) => {
|
|
476
441
|
this.props?.listener?.onBufferComplete(nativeEvent);
|
|
477
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.buffer_complete, nativeEvent);
|
|
478
|
-
};
|
|
479
|
-
|
|
480
|
-
onPlayerNext = ({ nativeEvent }) => {
|
|
481
|
-
// TODO: Implement method on native
|
|
482
|
-
|
|
483
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.next, nativeEvent);
|
|
484
|
-
};
|
|
485
|
-
|
|
486
|
-
onPlayerPrevious = ({ nativeEvent }) => {
|
|
487
|
-
// TODO: Implement method on native
|
|
488
|
-
|
|
489
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.previous, nativeEvent);
|
|
490
|
-
};
|
|
491
|
-
|
|
492
|
-
onPlayerStop = ({ nativeEvent }) => {
|
|
493
|
-
// TODO: Implement method on native
|
|
494
|
-
|
|
495
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.stop, nativeEvent);
|
|
496
|
-
};
|
|
497
|
-
|
|
498
|
-
onVideoBandwidthUpdate = ({ nativeEvent }) => {
|
|
499
|
-
// TODO: Implement method on native
|
|
500
|
-
|
|
501
|
-
this.handleAnalyticEvent(QOS_EVENT.bitrate_changed, nativeEvent);
|
|
502
442
|
};
|
|
503
443
|
|
|
504
444
|
onAdBegin = ({ nativeEvent }) => {
|
|
505
445
|
this.setState({ isAd: true });
|
|
506
|
-
this.handleAnalyticEvent(AD_EVENT.ad_start, nativeEvent);
|
|
507
446
|
this.props.listener?.onAdBegin?.(nativeEvent);
|
|
508
447
|
};
|
|
509
448
|
|
|
510
449
|
onAdBreakBegin = ({ nativeEvent }) => {
|
|
511
450
|
this.setState({ isAd: true });
|
|
512
|
-
this.handleAnalyticEvent(AD_EVENT.ad_break_start, nativeEvent);
|
|
513
451
|
this.props.listener?.onAdBreakBegin?.(nativeEvent);
|
|
514
452
|
};
|
|
515
453
|
|
|
516
454
|
onAdBreakEnd = ({ nativeEvent }) => {
|
|
517
455
|
this.setState({ isAd: false });
|
|
518
|
-
this.handleAnalyticEvent(AD_EVENT.ad_break_completed, nativeEvent);
|
|
519
456
|
this.props.listener?.onAdBreakEnd?.(nativeEvent);
|
|
520
457
|
};
|
|
521
458
|
|
|
522
459
|
onAdEnd = ({ nativeEvent }) => {
|
|
523
460
|
this.setState({ isAd: false });
|
|
524
|
-
this.handleAnalyticEvent(AD_EVENT.ad_complete, nativeEvent);
|
|
525
461
|
this.props.listener?.onAdEnd?.(nativeEvent);
|
|
526
462
|
};
|
|
527
463
|
|
|
528
464
|
onAdError = ({ nativeEvent }) => {
|
|
529
465
|
this.setState({ isAd: false });
|
|
530
|
-
this.handleAnalyticEvent(AD_EVENT.ad_error, nativeEvent);
|
|
531
466
|
this.props.listener?.onAdError?.(nativeEvent);
|
|
532
467
|
};
|
|
533
468
|
|
|
534
469
|
onAdRequest = ({ nativeEvent }) => {
|
|
535
|
-
this.handleAnalyticEvent(AD_EVENT.ad_request, nativeEvent);
|
|
536
470
|
this.props.listener?.onAdRequest?.(nativeEvent);
|
|
537
471
|
};
|
|
538
472
|
|
|
539
473
|
onAdClicked = ({ nativeEvent }) => {
|
|
540
|
-
this.handleAnalyticEvent(AD_EVENT.ad_clicked, nativeEvent);
|
|
541
474
|
// Broadcast click event
|
|
542
475
|
this.props.playerEvent("ad-clicked", nativeEvent);
|
|
543
476
|
this.props.listener?.onAdClicked?.(nativeEvent);
|
|
544
477
|
};
|
|
545
478
|
|
|
546
479
|
onAdTapped = ({ nativeEvent }) => {
|
|
547
|
-
this.handleAnalyticEvent(AD_EVENT.ad_tapped, nativeEvent);
|
|
548
480
|
// Broadcast click event
|
|
549
481
|
this.props.playerEvent("ad-tapped", nativeEvent);
|
|
550
482
|
this.props.listener?.onAdTapped?.(nativeEvent);
|
|
@@ -657,10 +589,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
657
589
|
}
|
|
658
590
|
|
|
659
591
|
if (!this.state.isAd && !this.onVideoLoadCalled) {
|
|
660
|
-
this.handleAnalyticEvent(PLAYBACK_EVENT.load_video, {
|
|
661
|
-
player_type: this.props.playerPluginIdentifier,
|
|
662
|
-
});
|
|
663
|
-
|
|
664
592
|
// TODO: Hack, needs to remove
|
|
665
593
|
this.onVideoLoadCalled = true;
|
|
666
594
|
}
|
|
@@ -785,7 +713,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
785
713
|
|
|
786
714
|
render() {
|
|
787
715
|
const {
|
|
788
|
-
castAction,
|
|
789
716
|
docked,
|
|
790
717
|
entry,
|
|
791
718
|
fullscreen,
|
|
@@ -795,8 +722,13 @@ export default class VideoPlayer extends React.Component<
|
|
|
795
722
|
isTabletPortrait,
|
|
796
723
|
muted,
|
|
797
724
|
style,
|
|
725
|
+
castAction,
|
|
726
|
+
controller,
|
|
727
|
+
startComponentsAnimation,
|
|
798
728
|
} = this.props;
|
|
799
729
|
|
|
730
|
+
const supportNativeCast = controller.supportNativeCast();
|
|
731
|
+
|
|
800
732
|
const { audioTrackId, keyEvent, paused, seek, textTrackId, rate } =
|
|
801
733
|
this.state;
|
|
802
734
|
|
|
@@ -861,7 +793,11 @@ export default class VideoPlayer extends React.Component<
|
|
|
861
793
|
? supportsNativeControls && !isInlineTV && !this.getPlayNextData()
|
|
862
794
|
: supportsNativeControls && !this.getPlayNextData();
|
|
863
795
|
|
|
864
|
-
const shouldUseNativeControls =
|
|
796
|
+
const shouldUseNativeControls =
|
|
797
|
+
controls &&
|
|
798
|
+
!startComponentsAnimation &&
|
|
799
|
+
!docked &&
|
|
800
|
+
!castAction?.state?.connected;
|
|
865
801
|
|
|
866
802
|
platformSpecificProps = {
|
|
867
803
|
...platformSpecificProps,
|
|
@@ -920,8 +856,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
920
856
|
onPlayerResume: this.onPlayerResume, // play
|
|
921
857
|
onPlayerSeekComplete: this.onPlayerSeekComplete, // seek_complete
|
|
922
858
|
onPlayerSeekStart: this.onPlayerSeekStart, // seek_start
|
|
923
|
-
onPlayerSessionEnd: this.onPlayerSessionEnd, // session_end
|
|
924
|
-
onPlayerSessionStart: this.onPlayerSessionStart, // session_start
|
|
925
859
|
};
|
|
926
860
|
|
|
927
861
|
const lifecycleEvents = {
|
|
@@ -954,7 +888,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
954
888
|
onTimedMetadata: this.unHandledEvent("onTimedMetadata"),
|
|
955
889
|
onTracksChanged: this.onTracksChanged,
|
|
956
890
|
eventSubtitlesChange: this.unHandledEvent("eventSubtitlesChange"),
|
|
957
|
-
onVideoBandwidthUpdate: this.onVideoBandwidthUpdate,
|
|
958
891
|
};
|
|
959
892
|
|
|
960
893
|
const playerSystemEvents = {
|
|
@@ -974,9 +907,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
974
907
|
const unsupportedEvents = {
|
|
975
908
|
onBufferComplete: this.onBufferComplete, // buffer_complete
|
|
976
909
|
onBufferStart: this.onBufferStart, // buffer_start
|
|
977
|
-
onPlayerNext: this.onPlayerNext, // next
|
|
978
|
-
onPlayerPrevious: this.onPlayerPrevious, // previous
|
|
979
|
-
onPlayerStop: this.onPlayerStop, // stop
|
|
980
910
|
};
|
|
981
911
|
|
|
982
912
|
const nativeEvents = {
|
|
@@ -1032,6 +962,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
1032
962
|
extraInfoText={castAction?.state?.friendlyStatus}
|
|
1033
963
|
controlsAlwaysVisible={castAction?.state?.connected}
|
|
1034
964
|
playNextData={this.getPlayNextData()}
|
|
965
|
+
nativeControls={!!controls}
|
|
1035
966
|
/>
|
|
1036
967
|
) : null;
|
|
1037
968
|
};
|
|
@@ -1066,7 +997,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
1066
997
|
const renderMobilePlayer = () => {
|
|
1067
998
|
return isFullScreenAudioPlayer && isAudioItem ? (
|
|
1068
999
|
<View style={containerStyle}>
|
|
1069
|
-
{!castAction?.state?.connected && (
|
|
1000
|
+
{(!castAction?.state?.connected || supportNativeCast) && (
|
|
1070
1001
|
<this.props.PlayerComponent
|
|
1071
1002
|
ref={this._assignRoot}
|
|
1072
1003
|
{...nativeEvents}
|
|
@@ -1117,7 +1048,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
1117
1048
|
/>
|
|
1118
1049
|
)}
|
|
1119
1050
|
|
|
1120
|
-
{!castAction?.state?.connected && (
|
|
1051
|
+
{(!castAction?.state?.connected || supportNativeCast) && (
|
|
1121
1052
|
<AnimationComponent
|
|
1122
1053
|
animationType={ComponentAnimationType.player}
|
|
1123
1054
|
additionalData={playerDimensions}
|