@applicaster/quick-brick-player 12.0.0-rc.9 → 12.0.0-rc.91

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
  /**
@@ -333,11 +335,7 @@ export default class VideoPlayer extends React.Component<
333
335
  }
334
336
  };
335
337
 
336
- /**
337
- * Sets either subtitle language, or audio language if we have a selected a new locale.
338
- * If no locale is set it defaults to system language for audio, and leaves subtitles unaltered.
339
- */
340
- setLanguage = (selected = null) => {
338
+ selectTrack = (selected) => {
341
339
  const { trackType, id, language } = selected || {};
342
340
 
343
341
  const isOff = language === "Off";
@@ -368,6 +366,10 @@ export default class VideoPlayer extends React.Component<
368
366
  }
369
367
  };
370
368
 
369
+ setPlaybackRate = (rate = 1.0) => {
370
+ this.setState({ rate });
371
+ };
372
+
371
373
  getCurrentTime = () => {
372
374
  return this.state.currentTime;
373
375
  };
@@ -551,6 +553,26 @@ export default class VideoPlayer extends React.Component<
551
553
  this.props.listener?.onPlayerDetached?.(nativeEvent);
552
554
  };
553
555
 
556
+ onVideoFullscreenPlayerDidDismiss = () => {
557
+ this.props.listener?.onVideoFullscreenPlayerDidDismiss?.();
558
+ };
559
+
560
+ onVideoFullscreenPlayerDidPresent = () => {
561
+ this.props.listener?.onVideoFullscreenPlayerDidPresent?.();
562
+ };
563
+
564
+ onVideoFullscreenPlayerWillDismiss = () => {
565
+ this.props.listener?.onVideoFullscreenPlayerWillDismiss?.();
566
+ };
567
+
568
+ onVideoFullscreenPlayerWillPresent = () => {
569
+ this.props.listener?.onVideoFullscreenPlayerWillPresent?.();
570
+ };
571
+
572
+ onPlayerClose = () => {
573
+ this.props.listener?.onPlayerClose?.();
574
+ };
575
+
554
576
  onPiPEnter = () => {
555
577
  this.setState({ piped: true });
556
578
  this.props.openPiP();
@@ -754,8 +776,6 @@ export default class VideoPlayer extends React.Component<
754
776
 
755
777
  render() {
756
778
  const {
757
- castAction,
758
- controls,
759
779
  docked,
760
780
  entry,
761
781
  fullscreen,
@@ -765,9 +785,15 @@ export default class VideoPlayer extends React.Component<
765
785
  isTabletPortrait,
766
786
  muted,
767
787
  style,
788
+ castAction,
789
+ controller,
790
+ startComponentsAnimation,
768
791
  } = this.props;
769
792
 
770
- const { audioTrackId, keyEvent, paused, seek, textTrackId } = this.state;
793
+ const supportNativeCast = controller.supportNativeCast();
794
+
795
+ const { audioTrackId, keyEvent, paused, seek, textTrackId, rate } =
796
+ this.state;
771
797
 
772
798
  const isAudioItem =
773
799
  entry?.content?.type?.includes?.("audio") ||
@@ -812,17 +838,35 @@ export default class VideoPlayer extends React.Component<
812
838
  const liveCatchUpEnabled =
813
839
  this.props.pluginConfiguration?.liveCatchUpEnabled;
814
840
 
815
- const hideNativeControls = isTV()
816
- ? { controls: !this.getPlayNextData() }
817
- : {};
841
+ // TODO: Get screen data more reliable way useCurrentScreenData
842
+ const screenData = getTargetScreenDataFromEntry(this.props.playableItem);
843
+
844
+ const isInlineTV = screenData?.ui_components?.length > 0 && isTV();
818
845
 
819
- const platformSpecificProps = isApplePlatform()
846
+ let platformSpecificProps: any = isApplePlatform()
820
847
  ? {
821
- ...hideNativeControls,
822
848
  resizeMode: nativeResizeMode,
823
849
  }
824
850
  : {};
825
851
 
852
+ const supportsNativeControls =
853
+ !!this.props.controller?.supportsNativeControls?.();
854
+
855
+ const controls = isAppleTV()
856
+ ? supportsNativeControls && !isInlineTV && !this.getPlayNextData()
857
+ : supportsNativeControls && !this.getPlayNextData();
858
+
859
+ const shouldUseNativeControls =
860
+ controls &&
861
+ !startComponentsAnimation &&
862
+ !docked &&
863
+ !castAction?.state?.connected;
864
+
865
+ platformSpecificProps = {
866
+ ...platformSpecificProps,
867
+ controls: shouldUseNativeControls,
868
+ };
869
+
826
870
  const pictureInPictureEnabled =
827
871
  this.props.pluginConfiguration?.pictureInPictureEnabled;
828
872
 
@@ -830,7 +874,6 @@ export default class VideoPlayer extends React.Component<
830
874
  entry, // Must be passed first in list
831
875
  ...platformSpecificProps,
832
876
  audioTrackId,
833
- controls,
834
877
  docked,
835
878
  enableAutoAudioTrackSelection,
836
879
  fullscreen, // TODO: Check fullscreen params not crash
@@ -839,6 +882,7 @@ export default class VideoPlayer extends React.Component<
839
882
  nowPlayingEnabled,
840
883
  paused,
841
884
  seek,
885
+ rate,
842
886
  textTrackId,
843
887
  liveSeekingEnabled,
844
888
  liveCatchUpEnabled,
@@ -884,22 +928,17 @@ export default class VideoPlayer extends React.Component<
884
928
  onVideoEnd: this.onVideoEnd, // complete
885
929
  onVideoError: this.onVideoError, // error
886
930
  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
- ),
931
+ onVideoFullscreenPlayerDidDismiss: this.onVideoFullscreenPlayerDidDismiss,
932
+ onVideoFullscreenPlayerDidPresent: this.onVideoFullscreenPlayerDidPresent,
933
+ onVideoFullscreenPlayerWillDismiss:
934
+ this.onVideoFullscreenPlayerWillDismiss,
935
+ onVideoFullscreenPlayerWillPresent:
936
+ this.onVideoFullscreenPlayerWillPresent,
899
937
  onVideoLoad: this.onVideoLoad,
900
938
  onVideoLoadStart: this.unHandledEvent("onVideoLoadStart"),
901
939
  onVideoBuffer: this.onVideoBuffer,
902
940
  onPlaybackStalled: this.onPlaybackStalled,
941
+ onPlayerClose: this.onPlayerClose,
903
942
  onPlayerAttached: this.onPlayerAttached,
904
943
  onPlayerDetached: this.onPlayerDetached,
905
944
  };
@@ -950,7 +989,13 @@ export default class VideoPlayer extends React.Component<
950
989
  ...androidLifecyclePiPEvents,
951
990
  };
952
991
 
953
- const needToShowPlayNextOverlay = this.getPlayNextData() && !docked;
992
+ const needToShowPlayNextOverlay =
993
+ isTV() && this.getPlayNextData() && !docked;
994
+
995
+ const needToShowDefaultControls = !(
996
+ (controls && !castAction?.state?.connected) ||
997
+ this.getPlayNextData()
998
+ );
954
999
 
955
1000
  const playerContainerStyles = isApplePlatform()
956
1001
  ? styles.playerContainerBlack
@@ -973,7 +1018,7 @@ export default class VideoPlayer extends React.Component<
973
1018
  !needToShowPlayNextOverlay &&
974
1019
  this.props.mode !== "PIP";
975
1020
 
976
- if (controls === true) {
1021
+ if (shouldUseNativeControls) {
977
1022
  return null;
978
1023
  }
979
1024
 
@@ -992,6 +1037,7 @@ export default class VideoPlayer extends React.Component<
992
1037
  extraInfoText={castAction?.state?.friendlyStatus}
993
1038
  controlsAlwaysVisible={castAction?.state?.connected}
994
1039
  playNextData={this.getPlayNextData()}
1040
+ needToShowDefaultControls={needToShowDefaultControls}
995
1041
  />
996
1042
  ) : null;
997
1043
  };
@@ -1005,10 +1051,12 @@ export default class VideoPlayer extends React.Component<
1005
1051
  inline,
1006
1052
  docked,
1007
1053
  isModal,
1054
+ pip: this.state.piped,
1008
1055
  layoutState: {
1009
1056
  inline,
1010
1057
  docked,
1011
1058
  isModal,
1059
+ pip: this.state.piped,
1012
1060
  },
1013
1061
  configuration: this.getPluginConfiguration(),
1014
1062
  fullscreen: fullscreen,
@@ -1024,29 +1072,14 @@ export default class VideoPlayer extends React.Component<
1024
1072
  const renderMobilePlayer = () => {
1025
1073
  return isFullScreenAudioPlayer && isAudioItem ? (
1026
1074
  <View style={containerStyle}>
1027
- {!castAction?.state?.connected && (
1075
+ {(!castAction?.state?.connected || supportNativeCast) && (
1028
1076
  <this.props.PlayerComponent
1029
1077
  ref={this._assignRoot}
1030
1078
  {...nativeEvents}
1031
1079
  {...nativeProps}
1032
1080
  />
1033
1081
  )}
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>
1082
+ <AudioPlayerWrapper {...sharedWrapperViewProps} />
1050
1083
  </View>
1051
1084
  ) : (
1052
1085
  <PlayerWrapper {...sharedWrapperViewProps}>
@@ -1061,11 +1094,24 @@ export default class VideoPlayer extends React.Component<
1061
1094
  <View style={styles.container}>
1062
1095
  <View style={[playerContainerStyles, playerDimensions]}>
1063
1096
  {isAudioItem && (
1064
- <AudioPlayer
1065
- style={playerDimensions}
1066
- audio_item={entry}
1067
- plugin_configuration={this.getPluginConfiguration()}
1068
- />
1097
+ <AnimationComponent
1098
+ animationType={ComponentAnimationType.player}
1099
+ additionalData={{
1100
+ ...playerDimensions,
1101
+ inlineAudioPlayer: true,
1102
+ }}
1103
+ style={getStyle(playerDimensions)}
1104
+ >
1105
+ <AudioPlayer
1106
+ style={
1107
+ isTV()
1108
+ ? getStyle(playerDimensions)
1109
+ : styles.playerSize
1110
+ }
1111
+ audio_item={entry}
1112
+ plugin_configuration={this.getPluginConfiguration()}
1113
+ />
1114
+ </AnimationComponent>
1069
1115
  )}
1070
1116
 
1071
1117
  {shouldRenderBackground && (
@@ -1077,17 +1123,28 @@ export default class VideoPlayer extends React.Component<
1077
1123
  />
1078
1124
  )}
1079
1125
 
1080
- {!castAction?.state?.connected && (
1081
- <this.props.PlayerComponent
1082
- ref={this._assignRoot}
1083
- {...nativeEvents}
1084
- {...nativeProps}
1085
- listener={this.props.listener}
1126
+ {(!castAction?.state?.connected || supportNativeCast) && (
1127
+ <AnimationComponent
1128
+ animationType={ComponentAnimationType.player}
1129
+ additionalData={playerDimensions}
1086
1130
  style={getStyle(playerDimensions)}
1087
- pluginConfiguration={this.getPluginConfiguration()}
1088
1131
  >
1089
- {this.childrenWithPlayNext()}
1090
- </this.props.PlayerComponent>
1132
+ <this.props.PlayerComponent
1133
+ ref={this._assignRoot}
1134
+ {...nativeEvents}
1135
+ {...nativeProps}
1136
+ listener={this.props.listener}
1137
+ style={
1138
+ isTV()
1139
+ ? getStyle(playerDimensions)
1140
+ : styles.playerSize
1141
+ }
1142
+ pluginConfiguration={this.getPluginConfiguration()}
1143
+ controller={this.props.controller}
1144
+ >
1145
+ {this.childrenWithPlayNext()}
1146
+ </this.props.PlayerComponent>
1147
+ </AnimationComponent>
1091
1148
  )}
1092
1149
  </View>
1093
1150
 
@@ -1121,6 +1178,7 @@ export default class VideoPlayer extends React.Component<
1121
1178
  listener={this.props.listener}
1122
1179
  style={this.takeParentStyle}
1123
1180
  pluginConfiguration={this.getPluginConfiguration()}
1181
+ controller={this.props.controller}
1124
1182
  >
1125
1183
  {this.childrenWithPlayNext()}
1126
1184
  </this.props.PlayerComponent>