@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.5553532911",
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-rc.49",
40
- "@applicaster/quick-brick-tv-transport-controls": "11.0.0-rc.133",
41
- "@applicaster/zapp-react-native-tvos-app": "12.0.0-alpha.5553532911",
42
- "@applicaster/zapp-react-native-ui-components": "12.0.0-alpha.5553532911",
43
- "@applicaster/zapp-react-native-utils": "12.0.0-alpha.5553532911",
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?: React.ReactNode;
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 = Number(value("seek_duration"));
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?.hasContentDuration?.() ? onRewindButtonPress : null,
249
+ onPress: controller?.hasSeekableDuration?.() ? onRewindButtonPress : null,
225
250
  });
226
251
 
227
252
  const forward = forwardButton({
228
253
  isTablet,
229
- onPress: controller?.hasContentDuration?.() ? onForwardButtonPress : null,
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 : null}
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 : null}
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 : null,
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
+ };
@@ -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
- this.handleAnalyticEvent(GENERAL_EVENT.session_end);
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 = controls && !docked;
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}