@applicaster/quick-brick-player 12.0.0-rc.8 → 12.0.0-rc.80

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.
@@ -1,6 +1,5 @@
1
1
  import React from "react";
2
2
  import DefaultLayout from "./DefaultLayout";
3
- import DockedLayout from "./DockedLayout";
4
3
  import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
5
4
 
6
5
  type Dimensions = {
@@ -24,27 +23,30 @@ type LayoutProps = {
24
23
  isBuffering: boolean;
25
24
  };
26
25
  value: GetValue;
26
+ sleepTimerDate: number;
27
+ playbackSpeedName: string;
28
+ playbackSleepName: string;
27
29
  configuration: { [key: string]: any };
28
30
  onPlaybackButtonPress: () => void;
29
31
  onRewindButtonPress: () => void;
30
32
  onForwardButtonPress: () => void;
33
+ onSpeedButtonPress: () => void;
34
+ onSleepButtonPress: () => void;
31
35
  onCloseVideoModal: () => void;
36
+ cancelSleepTimer: () => void;
32
37
  onPlayerSeek: (targetTime: number) => void;
33
38
  onSkipStart: () => void;
34
39
  onSkipLive: () => void;
35
40
  maximiseVideoModal: () => void;
36
41
  dimensions: Dimensions;
42
+ defaultDimensions: Dimensions;
37
43
  playNextData: PlayNextData;
44
+ title: string | number;
45
+ summary: string | number;
38
46
  };
39
47
 
40
48
  export default function Layout(
41
49
  props: LayoutProps
42
50
  ): React.ReactElement<LayoutProps> {
43
- const { layoutState } = props;
44
-
45
- if (layoutState.docked) {
46
- return <DockedLayout {...props} />;
47
- }
48
-
49
51
  return <DefaultLayout {...props} />;
50
52
  }
@@ -1,17 +1,19 @@
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";
6
+ import { useEffect } from "react";
7
7
 
8
8
  type MagicBGProps = {
9
9
  children: React.ReactNode;
10
10
  image: string;
11
+ fallbackUrl?: string;
11
12
  defaultColor: string;
13
+ colors: string[];
12
14
  };
13
15
 
14
- const colors = {
16
+ const defaultColors = {
15
17
  overlay: "rgba(0, 0, 0, 0.35)",
16
18
  defaultGradientStart: "rgba(0, 0, 0, 0.25)",
17
19
  defaultGradientEnd: "rgba(0, 0, 0, 0)",
@@ -23,7 +25,7 @@ const styles = StyleSheet.create({
23
25
  },
24
26
  fullScreenOverlay: {
25
27
  ...StyleSheet.absoluteFillObject,
26
- backgroundColor: colors.overlay,
28
+ backgroundColor: defaultColors.overlay,
27
29
  },
28
30
  gradientOverlay: {
29
31
  position: "absolute",
@@ -34,53 +36,120 @@ const styles = StyleSheet.create({
34
36
  },
35
37
  });
36
38
 
39
+ const fetchPaletteAndDominantColor = async (imageUrl: string) => {
40
+ const palette = await getPalettes(imageUrl);
41
+
42
+ const colors = palette.map(
43
+ (color: { r: number; g: number; b: number }) =>
44
+ `rgb(${color.r}, ${color.g}, ${color.b})`
45
+ );
46
+
47
+ const dominant = await getDominantColor(imageUrl);
48
+ const dominantColor = `rgb(${dominant.r}, ${dominant.g}, ${dominant.b})`;
49
+
50
+ return { gradientColors: colors.slice(0, 2), dominantColor };
51
+ };
52
+
37
53
  export const MagicBG: React.FC<MagicBGProps> = ({
38
54
  children,
39
55
  image,
56
+ fallbackUrl = "",
57
+ colors = [],
40
58
  defaultColor,
41
59
  }) => {
42
60
  const [dominantColor, setDominantColor] =
43
61
  React.useState<string>(defaultColor);
44
62
 
45
63
  const [gradientColors, setGradientColors] = React.useState<string[]>([
46
- colors.defaultGradientStart,
47
- colors.defaultGradientEnd,
64
+ defaultColors.defaultGradientStart,
65
+ defaultColors.defaultGradientEnd,
48
66
  ]);
49
67
 
50
- React.useEffect(() => {
51
- const fetchColors = async () => {
52
- if (image) {
53
- try {
54
- const palette = await getPalettes(image);
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
55
70
 
56
- const colors = palette.map(
57
- (color: { r: number; g: number; b: number }) =>
58
- `rgb(${color.r}, ${color.g}, ${color.b})`
59
- );
71
+ useEffect(() => {
72
+ const animateColors = () => {
73
+ Animated.timing(backgroundColorAnim, {
74
+ toValue: 1,
75
+ duration: 500,
76
+ useNativeDriver: false,
77
+ }).start();
60
78
 
61
- setGradientColors(colors.slice(0, 2));
79
+ Animated.timing(gradientOpacityAnim, {
80
+ toValue: 1,
81
+ duration: 500,
82
+ useNativeDriver: false,
83
+ }).start();
84
+ };
62
85
 
63
- const dominant = await getDominantColor(image);
64
- setDominantColor(`rgb(${dominant.r}, ${dominant.g}, ${dominant.b})`);
86
+ const fetchColors = async () => {
87
+ if (colors && colors.length > 0) {
88
+ setGradientColors(colors.slice(0, 2));
89
+ setDominantColor(colors[0]);
90
+ animateColors();
91
+ } else if (image) {
92
+ try {
93
+ const { gradientColors, dominantColor } =
94
+ await fetchPaletteAndDominantColor(image);
95
+
96
+ setGradientColors(gradientColors);
97
+ setDominantColor(dominantColor);
98
+ animateColors();
65
99
  } catch (error) {
66
- setGradientColors([
67
- colors.defaultGradientStart,
68
- colors.defaultGradientEnd,
69
- ]);
100
+ try {
101
+ const { gradientColors, dominantColor } =
102
+ await fetchPaletteAndDominantColor(fallbackUrl);
103
+
104
+ setGradientColors(gradientColors);
105
+ setDominantColor(dominantColor);
106
+ animateColors();
107
+ } catch {
108
+ setGradientColors([
109
+ defaultColors.defaultGradientStart,
110
+ defaultColors.defaultGradientEnd,
111
+ ]);
70
112
 
71
- setDominantColor(defaultColor);
113
+ setDominantColor(defaultColor);
114
+ }
72
115
  }
116
+ } else {
117
+ setGradientColors([
118
+ defaultColors.defaultGradientStart,
119
+ defaultColors.defaultGradientEnd,
120
+ ]);
121
+
122
+ setDominantColor(defaultColor);
73
123
  }
74
124
  };
75
125
 
76
126
  fetchColors();
77
- }, [image, defaultColor]);
127
+ }, []);
128
+
129
+ const interpolatedBackgroundColor = backgroundColorAnim.interpolate({
130
+ inputRange: [0, 1],
131
+ outputRange: ["black", dominantColor],
132
+ });
78
133
 
79
134
  return (
80
- <View style={[styles.container, { backgroundColor: dominantColor }]}>
135
+ <Animated.View
136
+ style={[
137
+ styles.container,
138
+ { backgroundColor: interpolatedBackgroundColor },
139
+ ]}
140
+ >
81
141
  <View style={styles.fullScreenOverlay} />
82
- <LinearGradient colors={gradientColors} style={styles.gradientOverlay} />
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
+
83
152
  {children}
84
- </View>
153
+ </Animated.View>
85
154
  );
86
155
  };
@@ -0,0 +1,33 @@
1
+ import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
2
+ import { parseJsonIfNeeded } from "@applicaster/zapp-react-native-utils/functionUtils";
3
+
4
+ export const NAMESPACE = "audio-player";
5
+
6
+ export async function loadItemsFromStorage(key: string) {
7
+ const storedItems = await localStorage.getItem(key, NAMESPACE);
8
+
9
+ return parseJsonIfNeeded(storedItems) || null;
10
+ }
11
+
12
+ export const hasDatePassed = (timestamp: number) => {
13
+ // Get the current date and time
14
+ const currentDate = new Date();
15
+
16
+ // Compare the current date's timestamp with the given timestamp
17
+ return currentDate.getTime() > timestamp;
18
+ };
19
+
20
+ export const formatSpeed = (value: number) => {
21
+ let formattedValue = value.toString();
22
+
23
+ // If the value ends with ".0", remove it
24
+ if (formattedValue.endsWith(".0")) {
25
+ formattedValue = formattedValue.slice(0, -2);
26
+ }
27
+
28
+ // Replace "." with "_"
29
+ formattedValue = formattedValue.replace(".", "_");
30
+
31
+ // Return the formatted string with "speed_" prefix
32
+ return `speed_${formattedValue}`;
33
+ };
@@ -1,21 +1,31 @@
1
- export const toTypeString = (obj) => {
2
- switch (typeof obj) {
3
- case "object":
4
- return obj instanceof Date ? obj.toISOString() : JSON.stringify(obj); // object, null
5
- case "undefined":
6
- return "";
7
- default:
8
- // boolean, number, string
9
- return obj.toString();
10
- }
1
+ import queryString from "query-string";
2
+ import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
3
+
4
+ export const getLiveUrl = (url: string) => {
5
+ // Use the replace method with a regular expression to replace all instances of subClass with livePage
6
+ return url.replace(new RegExp("subClass", "g"), "livePage");
11
7
  };
12
8
 
13
- export const stringsOnlyObject = (obj) => {
14
- const strObj = {};
9
+ export const addQueryParam = (
10
+ baseUrl: string,
11
+ paramName: string,
12
+ paramValue: string | number
13
+ ) => {
14
+ const [urlWithoutQuery, query] = baseUrl.split("?");
15
+
16
+ const parsedQuery = queryString.parse(query);
17
+
18
+ parsedQuery[paramName] = paramValue.toString();
15
19
 
16
- Object.keys(obj).forEach((x) => {
17
- strObj[x] = toTypeString(obj[x]);
18
- });
20
+ const updatedQueryString = queryString.stringify(parsedQuery);
21
+
22
+ return `${urlWithoutQuery}?${updatedQueryString}`;
23
+ };
19
24
 
20
- return strObj;
25
+ export const isValidDate = (dateString: string | undefined): boolean => {
26
+ return (
27
+ typeof dateString === "string" &&
28
+ dateString.trim() !== "" &&
29
+ dayjs.utc(dateString).isValid()
30
+ );
21
31
  };
@@ -1,3 +1 @@
1
- export * from "./AssetsHelper";
2
-
3
1
  export * from "./Utils";
@@ -4,7 +4,7 @@
4
4
  import React from "react";
5
5
  import * as R from "ramda";
6
6
 
7
- import { findNodeHandle, NativeModules, StyleSheet, View } from "react-native";
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
 
@@ -36,15 +36,13 @@ import { AudioPlayerWrapper } from "./AudioLayer/AudioPlayerWrapper";
36
36
  import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
37
37
  import { getAllAccessibilityProps } from "@applicaster/zapp-react-native-utils/configurationUtils";
38
38
  import { PlayNextData } from "@applicaster/zapp-react-native-ui-components/Components/PlayerContainer/PlayerContainer";
39
-
40
- const RNPlayerManager = {
41
- QuickBrickPlayerPlugin: isApplePlatform()
42
- ? NativeModules.PlayerModule
43
- : NativeModules.QuickBrickDefaultPlayerModule,
44
- KalturaPlayerPlugin: isApplePlatform()
45
- ? NativeModules.KalturaPlayerModule
46
- : NativeModules.QBKalturaPlayerModule,
47
- };
39
+ import { getTargetScreenDataFromEntry } from "@applicaster/zapp-react-native-utils/reactHooks/screen/useTargetScreenData";
40
+ import { isAppleTV } from "@applicaster/zapp-react-native-ui-components/Helpers/Platform";
41
+ import {
42
+ AnimationComponent,
43
+ ComponentAnimationType,
44
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";
45
+ import { RNPlayerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/nativePlayerManager";
48
46
 
49
47
  const styles = StyleSheet.create({
50
48
  container: { flex: 1 },
@@ -55,6 +53,7 @@ const styles = StyleSheet.create({
55
53
  position: "absolute",
56
54
  zIndex: 1,
57
55
  },
56
+ playerSize: { width: "100%", height: "100%" },
58
57
  });
59
58
 
60
59
  const logger = createLogger({
@@ -87,7 +86,7 @@ export default class VideoPlayer extends React.Component<
87
86
  // TODO: Can be deleted, on controller logic
88
87
  paused: false,
89
88
  piped: false,
90
- rate: 1,
89
+ rate: 1.0,
91
90
  // TODO: Hack for analytics, must br removed
92
91
  resume: null,
93
92
 
@@ -113,8 +112,6 @@ export default class VideoPlayer extends React.Component<
113
112
  }
114
113
 
115
114
  componentWillUnmount() {
116
- this.stopBackgroundPlayback();
117
-
118
115
  this.playbackStarted = false;
119
116
  this.handleAnalyticEvent(GENERAL_EVENT.session_end);
120
117
  this.onPlayerClosed();
@@ -159,6 +156,11 @@ export default class VideoPlayer extends React.Component<
159
156
  }
160
157
  }
161
158
 
159
+ // For close button
160
+ public closeNativePlayer = () => {
161
+ this.stopBackgroundPlayback();
162
+ };
163
+
162
164
  getPlayNextData = () => this.props.playNextData as PlayNextData;
163
165
 
164
166
  /**
@@ -337,7 +339,7 @@ export default class VideoPlayer extends React.Component<
337
339
  * Sets either subtitle language, or audio language if we have a selected a new locale.
338
340
  * If no locale is set it defaults to system language for audio, and leaves subtitles unaltered.
339
341
  */
340
- setLanguage = (selected = null) => {
342
+ selectTrack = (selected = null) => {
341
343
  const { trackType, id, language } = selected || {};
342
344
 
343
345
  const isOff = language === "Off";
@@ -368,6 +370,10 @@ export default class VideoPlayer extends React.Component<
368
370
  }
369
371
  };
370
372
 
373
+ setPlaybackRate = (rate = 1.0) => {
374
+ this.setState({ rate });
375
+ };
376
+
371
377
  getCurrentTime = () => {
372
378
  return this.state.currentTime;
373
379
  };
@@ -551,6 +557,26 @@ export default class VideoPlayer extends React.Component<
551
557
  this.props.listener?.onPlayerDetached?.(nativeEvent);
552
558
  };
553
559
 
560
+ onVideoFullscreenPlayerDidDismiss = () => {
561
+ this.props.listener?.onVideoFullscreenPlayerDidDismiss?.();
562
+ };
563
+
564
+ onVideoFullscreenPlayerDidPresent = () => {
565
+ this.props.listener?.onVideoFullscreenPlayerDidPresent?.();
566
+ };
567
+
568
+ onVideoFullscreenPlayerWillDismiss = () => {
569
+ this.props.listener?.onVideoFullscreenPlayerWillDismiss?.();
570
+ };
571
+
572
+ onVideoFullscreenPlayerWillPresent = () => {
573
+ this.props.listener?.onVideoFullscreenPlayerWillPresent?.();
574
+ };
575
+
576
+ onPlayerClose = () => {
577
+ this.props.listener?.onPlayerClose?.();
578
+ };
579
+
554
580
  onPiPEnter = () => {
555
581
  this.setState({ piped: true });
556
582
  this.props.openPiP();
@@ -754,8 +780,6 @@ export default class VideoPlayer extends React.Component<
754
780
 
755
781
  render() {
756
782
  const {
757
- castAction,
758
- controls,
759
783
  docked,
760
784
  entry,
761
785
  fullscreen,
@@ -765,9 +789,15 @@ export default class VideoPlayer extends React.Component<
765
789
  isTabletPortrait,
766
790
  muted,
767
791
  style,
792
+ castAction,
793
+ controller,
794
+ startComponentsAnimation,
768
795
  } = this.props;
769
796
 
770
- const { audioTrackId, keyEvent, paused, seek, textTrackId } = this.state;
797
+ const supportNativeCast = controller.supportNativeCast();
798
+
799
+ const { audioTrackId, keyEvent, paused, seek, textTrackId, rate } =
800
+ this.state;
771
801
 
772
802
  const isAudioItem =
773
803
  entry?.content?.type?.includes?.("audio") ||
@@ -812,17 +842,35 @@ export default class VideoPlayer extends React.Component<
812
842
  const liveCatchUpEnabled =
813
843
  this.props.pluginConfiguration?.liveCatchUpEnabled;
814
844
 
815
- const hideNativeControls = isTV()
816
- ? { controls: !this.getPlayNextData() }
817
- : {};
845
+ // TODO: Get screen data more reliable way useCurrentScreenData
846
+ const screenData = getTargetScreenDataFromEntry(this.props.playableItem);
847
+
848
+ const isInlineTV = screenData?.ui_components?.length > 0 && isTV();
818
849
 
819
- const platformSpecificProps = isApplePlatform()
850
+ let platformSpecificProps: any = isApplePlatform()
820
851
  ? {
821
- ...hideNativeControls,
822
852
  resizeMode: nativeResizeMode,
823
853
  }
824
854
  : {};
825
855
 
856
+ const supportsNativeControls =
857
+ !!this.props.controller?.supportsNativeControls?.();
858
+
859
+ const controls = isAppleTV()
860
+ ? supportsNativeControls && !isInlineTV && !this.getPlayNextData()
861
+ : supportsNativeControls && !this.getPlayNextData();
862
+
863
+ const shouldUseNativeControls =
864
+ controls &&
865
+ !startComponentsAnimation &&
866
+ !docked &&
867
+ !castAction?.state?.connected;
868
+
869
+ platformSpecificProps = {
870
+ ...platformSpecificProps,
871
+ controls: shouldUseNativeControls,
872
+ };
873
+
826
874
  const pictureInPictureEnabled =
827
875
  this.props.pluginConfiguration?.pictureInPictureEnabled;
828
876
 
@@ -830,7 +878,6 @@ export default class VideoPlayer extends React.Component<
830
878
  entry, // Must be passed first in list
831
879
  ...platformSpecificProps,
832
880
  audioTrackId,
833
- controls,
834
881
  docked,
835
882
  enableAutoAudioTrackSelection,
836
883
  fullscreen, // TODO: Check fullscreen params not crash
@@ -839,6 +886,7 @@ export default class VideoPlayer extends React.Component<
839
886
  nowPlayingEnabled,
840
887
  paused,
841
888
  seek,
889
+ rate,
842
890
  textTrackId,
843
891
  liveSeekingEnabled,
844
892
  liveCatchUpEnabled,
@@ -884,22 +932,17 @@ export default class VideoPlayer extends React.Component<
884
932
  onVideoEnd: this.onVideoEnd, // complete
885
933
  onVideoError: this.onVideoError, // error
886
934
  onVideoProgress: this.onVideoProgress,
887
- onVideoFullscreenPlayerDidDismiss: this.unHandledEvent(
888
- "onVideoFullscreenPlayerDidPresent"
889
- ),
890
- onVideoFullscreenPlayerDidPresent: this.unHandledEvent(
891
- "onVideoFullscreenPlayerDidPresent"
892
- ),
893
- onVideoFullscreenPlayerWillDismiss: this.unHandledEvent(
894
- "onVideoFullscreenPlayerWillDismiss"
895
- ),
896
- onVideoFullscreenPlayerWillPresent: this.unHandledEvent(
897
- "onVideoFullscreenPlayerWillPresent"
898
- ),
935
+ onVideoFullscreenPlayerDidDismiss: this.onVideoFullscreenPlayerDidDismiss,
936
+ onVideoFullscreenPlayerDidPresent: this.onVideoFullscreenPlayerDidPresent,
937
+ onVideoFullscreenPlayerWillDismiss:
938
+ this.onVideoFullscreenPlayerWillDismiss,
939
+ onVideoFullscreenPlayerWillPresent:
940
+ this.onVideoFullscreenPlayerWillPresent,
899
941
  onVideoLoad: this.onVideoLoad,
900
942
  onVideoLoadStart: this.unHandledEvent("onVideoLoadStart"),
901
943
  onVideoBuffer: this.onVideoBuffer,
902
944
  onPlaybackStalled: this.onPlaybackStalled,
945
+ onPlayerClose: this.onPlayerClose,
903
946
  onPlayerAttached: this.onPlayerAttached,
904
947
  onPlayerDetached: this.onPlayerDetached,
905
948
  };
@@ -973,7 +1016,7 @@ export default class VideoPlayer extends React.Component<
973
1016
  !needToShowPlayNextOverlay &&
974
1017
  this.props.mode !== "PIP";
975
1018
 
976
- if (controls === true) {
1019
+ if (shouldUseNativeControls) {
977
1020
  return null;
978
1021
  }
979
1022
 
@@ -992,6 +1035,7 @@ export default class VideoPlayer extends React.Component<
992
1035
  extraInfoText={castAction?.state?.friendlyStatus}
993
1036
  controlsAlwaysVisible={castAction?.state?.connected}
994
1037
  playNextData={this.getPlayNextData()}
1038
+ nativeControls={!!controls}
995
1039
  />
996
1040
  ) : null;
997
1041
  };
@@ -1005,10 +1049,12 @@ export default class VideoPlayer extends React.Component<
1005
1049
  inline,
1006
1050
  docked,
1007
1051
  isModal,
1052
+ pip: this.state.piped,
1008
1053
  layoutState: {
1009
1054
  inline,
1010
1055
  docked,
1011
1056
  isModal,
1057
+ pip: this.state.piped,
1012
1058
  },
1013
1059
  configuration: this.getPluginConfiguration(),
1014
1060
  fullscreen: fullscreen,
@@ -1024,29 +1070,14 @@ export default class VideoPlayer extends React.Component<
1024
1070
  const renderMobilePlayer = () => {
1025
1071
  return isFullScreenAudioPlayer && isAudioItem ? (
1026
1072
  <View style={containerStyle}>
1027
- {!castAction?.state?.connected && (
1073
+ {(!castAction?.state?.connected || supportNativeCast) && (
1028
1074
  <this.props.PlayerComponent
1029
1075
  ref={this._assignRoot}
1030
1076
  {...nativeEvents}
1031
1077
  {...nativeProps}
1032
1078
  />
1033
1079
  )}
1034
- <AudioPlayerWrapper {...sharedWrapperViewProps}>
1035
- <View>
1036
- {
1037
- <PlayNextOverlay
1038
- item={entry}
1039
- playerIsDocked={docked}
1040
- pluginConfiguration={this.getPluginConfiguration()}
1041
- playerId={this.props.playerId}
1042
- playNextData={this.getPlayNextData()}
1043
- setNextVideoPreloadThresholdPercentage={
1044
- this.props.setNextVideoPreloadThresholdPercentage
1045
- }
1046
- />
1047
- }
1048
- </View>
1049
- </AudioPlayerWrapper>
1080
+ <AudioPlayerWrapper {...sharedWrapperViewProps} />
1050
1081
  </View>
1051
1082
  ) : (
1052
1083
  <PlayerWrapper {...sharedWrapperViewProps}>
@@ -1061,11 +1092,24 @@ export default class VideoPlayer extends React.Component<
1061
1092
  <View style={styles.container}>
1062
1093
  <View style={[playerContainerStyles, playerDimensions]}>
1063
1094
  {isAudioItem && (
1064
- <AudioPlayer
1065
- style={playerDimensions}
1066
- audio_item={entry}
1067
- plugin_configuration={this.getPluginConfiguration()}
1068
- />
1095
+ <AnimationComponent
1096
+ animationType={ComponentAnimationType.player}
1097
+ additionalData={{
1098
+ ...playerDimensions,
1099
+ inlineAudioPlayer: true,
1100
+ }}
1101
+ style={getStyle(playerDimensions)}
1102
+ >
1103
+ <AudioPlayer
1104
+ style={
1105
+ isTV()
1106
+ ? getStyle(playerDimensions)
1107
+ : styles.playerSize
1108
+ }
1109
+ audio_item={entry}
1110
+ plugin_configuration={this.getPluginConfiguration()}
1111
+ />
1112
+ </AnimationComponent>
1069
1113
  )}
1070
1114
 
1071
1115
  {shouldRenderBackground && (
@@ -1077,17 +1121,28 @@ export default class VideoPlayer extends React.Component<
1077
1121
  />
1078
1122
  )}
1079
1123
 
1080
- {!castAction?.state?.connected && (
1081
- <this.props.PlayerComponent
1082
- ref={this._assignRoot}
1083
- {...nativeEvents}
1084
- {...nativeProps}
1085
- listener={this.props.listener}
1124
+ {(!castAction?.state?.connected || supportNativeCast) && (
1125
+ <AnimationComponent
1126
+ animationType={ComponentAnimationType.player}
1127
+ additionalData={playerDimensions}
1086
1128
  style={getStyle(playerDimensions)}
1087
- pluginConfiguration={this.getPluginConfiguration()}
1088
1129
  >
1089
- {this.childrenWithPlayNext()}
1090
- </this.props.PlayerComponent>
1130
+ <this.props.PlayerComponent
1131
+ ref={this._assignRoot}
1132
+ {...nativeEvents}
1133
+ {...nativeProps}
1134
+ listener={this.props.listener}
1135
+ style={
1136
+ isTV()
1137
+ ? getStyle(playerDimensions)
1138
+ : styles.playerSize
1139
+ }
1140
+ pluginConfiguration={this.getPluginConfiguration()}
1141
+ controller={this.props.controller}
1142
+ >
1143
+ {this.childrenWithPlayNext()}
1144
+ </this.props.PlayerComponent>
1145
+ </AnimationComponent>
1091
1146
  )}
1092
1147
  </View>
1093
1148
 
@@ -1121,6 +1176,7 @@ export default class VideoPlayer extends React.Component<
1121
1176
  listener={this.props.listener}
1122
1177
  style={this.takeParentStyle}
1123
1178
  pluginConfiguration={this.getPluginConfiguration()}
1179
+ controller={this.props.controller}
1124
1180
  >
1125
1181
  {this.childrenWithPlayNext()}
1126
1182
  </this.props.PlayerComponent>