@applicaster/quick-brick-player 13.0.0-rc.11 → 13.0.0-rc.110

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.
Files changed (37) hide show
  1. package/package.json +27 -13
  2. package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
  3. package/src/Player/AudioLayer/AudioDescription.tsx +5 -7
  4. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +136 -181
  5. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +27 -0
  6. package/src/Player/AudioLayer/Layout/Controls/index.tsx +316 -0
  7. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +7 -25
  8. package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
  9. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +44 -67
  10. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +231 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +83 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +25 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +101 -0
  14. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +26 -0
  15. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +216 -0
  16. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +224 -0
  17. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +115 -0
  18. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  19. package/src/Player/AudioLayer/Layout/const.ts +22 -0
  20. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  21. package/src/Player/AudioLayer/Layout/hooks/index.ts +5 -0
  22. package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
  23. package/src/Player/AudioLayer/Layout/hooks/useTabletLayoutImageSize.ts +105 -0
  24. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  25. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  26. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  27. package/src/Player/AudioLayer/MagicBG/index.tsx +1 -1
  28. package/src/Player/AudioLayer/SleepTimerManager.ts +119 -0
  29. package/src/Player/AudioLayer/SpeedManager.ts +52 -0
  30. package/src/Player/AudioLayer/utils.ts +27 -0
  31. package/src/Player/Const/sleepTimerOptions.ts +39 -0
  32. package/src/Player/Const/speedOptions.ts +4 -0
  33. package/src/Player/Utils/Utils.ts +0 -5
  34. package/src/Player/Utils/index.tsx +117 -0
  35. package/src/Player/index.tsx +31 -19
  36. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
  37. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
@@ -0,0 +1,119 @@
1
+ import { BehaviorSubject } from "rxjs";
2
+ import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
3
+ import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
4
+ import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
5
+ import { hasDatePassed, NAMESPACE } from "./utils";
6
+
7
+ const { log_debug, log_error } = createLogger({
8
+ subsystem: "Player",
9
+ category: "SleepTimerManager",
10
+ });
11
+
12
+ export type SleepTimer = {
13
+ label: string;
14
+ // interval in minutes for UI at the moment when timer was first started
15
+ value: number;
16
+ };
17
+
18
+ export const SLEEP_TIMER_OFF: SleepTimer = {
19
+ label: "playback_sleep_off_label",
20
+ value: 0,
21
+ };
22
+
23
+ export class SleepTimerState {
24
+ constructor(
25
+ public timer: SleepTimer,
26
+ public timerDate: number
27
+ ) {}
28
+ }
29
+
30
+ const SLEEP_PREFERENCE_KEY = "sleep";
31
+
32
+ export class SleepTimerController {
33
+ private sleepTimerStateSubject = new BehaviorSubject<SleepTimerState>(
34
+ new SleepTimerState(SLEEP_TIMER_OFF, 0)
35
+ );
36
+
37
+ constructor(private player: Player) {}
38
+
39
+ get sleepTimerState$() {
40
+ return this.sleepTimerStateSubject.asObservable();
41
+ }
42
+
43
+ private async scheduleSleep(sleepDate): Promise<boolean> {
44
+ log_debug(`Setting sleep interval to ${sleepDate}`);
45
+
46
+ try {
47
+ this.player.cancelSleepTimer?.();
48
+ this.player.startSleepTimer?.(sleepDate);
49
+
50
+ return true;
51
+ } catch (e) {
52
+ log_error("Failed to start sleep timer", { error: e.message });
53
+
54
+ return false;
55
+ }
56
+ }
57
+
58
+ async setSleepTimer(item: SleepTimer) {
59
+ // User has selected Off state
60
+ if (item.value === 0) {
61
+ log_debug("Cancelling sleep timer");
62
+ this.player.cancelSleepTimer?.();
63
+
64
+ return this.onTimerExpired();
65
+ }
66
+
67
+ log_debug(`Starting sleep timer in ${item.value} minutes`);
68
+
69
+ const futureSleepDate = Date.now() + item.value * 60000;
70
+
71
+ if (await this.scheduleSleep(futureSleepDate)) {
72
+ await localStorage.setItem(
73
+ SLEEP_PREFERENCE_KEY,
74
+ { ...item, futureSleepDate },
75
+ NAMESPACE
76
+ );
77
+
78
+ this.sleepTimerStateSubject.next(
79
+ new SleepTimerState(item, futureSleepDate)
80
+ );
81
+ }
82
+ }
83
+
84
+ async onTimerExpired() {
85
+ await localStorage.removeItem(SLEEP_PREFERENCE_KEY, NAMESPACE);
86
+
87
+ this.sleepTimerStateSubject.next(new SleepTimerState(SLEEP_TIMER_OFF, 0));
88
+ }
89
+
90
+ async loadSleep() {
91
+ const sleep = await localStorage.getItem(SLEEP_PREFERENCE_KEY, NAMESPACE);
92
+
93
+ if (!sleep) return;
94
+
95
+ const { futureSleepDate, ...rest } = sleep;
96
+
97
+ if (!futureSleepDate || hasDatePassed(futureSleepDate)) {
98
+ log_debug("Sleep date has already passed");
99
+ await localStorage.removeItem(SLEEP_PREFERENCE_KEY, NAMESPACE);
100
+
101
+ return;
102
+ }
103
+
104
+ if (await this.scheduleSleep(futureSleepDate)) {
105
+ log_debug(`Sleep state restored, will go to sleep at ${futureSleepDate}`);
106
+
107
+ this.sleepTimerStateSubject.next(
108
+ new SleepTimerState(rest as SleepTimer, futureSleepDate)
109
+ );
110
+ }
111
+ }
112
+
113
+ // Will be called if user closed the player explicitly.
114
+ // TODO: check if it will be called on Android when we need.
115
+ // Probably we will have to handle it on native instead.
116
+ public static async onPlayerDestroy() {
117
+ await localStorage.removeItem(SLEEP_PREFERENCE_KEY, NAMESPACE);
118
+ }
119
+ }
@@ -0,0 +1,52 @@
1
+ import { BehaviorSubject } from "rxjs";
2
+ import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
3
+ import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
4
+ import { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
5
+ import { NAMESPACE } from "./utils";
6
+
7
+ const { log_debug } = createLogger({
8
+ subsystem: "Player",
9
+ category: "PlaybackSpeedManager",
10
+ });
11
+
12
+ export type PlaybackSpeed = {
13
+ asset: string;
14
+ value: number;
15
+ };
16
+
17
+ const SPEED_PREFERENCE_KEY = "speed";
18
+
19
+ export const DEFAULT_SPEED: PlaybackSpeed = {
20
+ asset: "speed_1",
21
+ value: 1.0,
22
+ };
23
+
24
+ // todo: should not be applied to live streams
25
+ export class SpeedController {
26
+ private playbackSpeedSubject = new BehaviorSubject<PlaybackSpeed>(
27
+ DEFAULT_SPEED
28
+ );
29
+
30
+ constructor(private player: Player) {}
31
+
32
+ get playbackSpeed$() {
33
+ return this.playbackSpeedSubject.asObservable();
34
+ }
35
+
36
+ async loadSpeed() {
37
+ const speed = await localStorage.getItem(SPEED_PREFERENCE_KEY, NAMESPACE);
38
+
39
+ // checking for value in case we will pull empty or broken object
40
+ if (speed && speed.value) {
41
+ this.playbackSpeedSubject.next(speed);
42
+ this.player.setPlaybackRate?.(speed.value);
43
+ log_debug(`Speed loaded: ${speed}`);
44
+ }
45
+ }
46
+
47
+ async setPlaybackSpeed(speed: PlaybackSpeed) {
48
+ await localStorage.setItem(SPEED_PREFERENCE_KEY, speed, NAMESPACE);
49
+ this.playbackSpeedSubject.next(speed);
50
+ this.player.setPlaybackRate?.(speed.value);
51
+ }
52
+ }
@@ -1,5 +1,10 @@
1
1
  import { localStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/LocalStorage";
2
+ import {
3
+ PlayerAnimationStateEnum,
4
+ PlayerAnimationStateT,
5
+ } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation/ModalAnimationContext";
2
6
  import { parseJsonIfNeeded } from "@applicaster/zapp-react-native-utils/functionUtils";
7
+ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
3
8
 
4
9
  export const NAMESPACE = "audio-player";
5
10
 
@@ -31,3 +36,25 @@ export const formatSpeed = (value: number) => {
31
36
  // Return the formatted string with "speed_" prefix
32
37
  return `speed_${formattedValue}`;
33
38
  };
39
+
40
+ export const calculateBorderRadius = (
41
+ docked: boolean,
42
+ startComponentsAnimation: boolean,
43
+ isActiveGesture: boolean,
44
+ playerAnimationState: PlayerAnimationStateT,
45
+ configuration: Record<string, any>
46
+ ): number => {
47
+ const shouldRemoveBorderRadius =
48
+ (startComponentsAnimation &&
49
+ isActiveGesture &&
50
+ playerAnimationState !== PlayerAnimationStateEnum.maximize) ||
51
+ docked;
52
+
53
+ if (shouldRemoveBorderRadius) {
54
+ return 0;
55
+ }
56
+
57
+ return toNumberWithDefaultZero(
58
+ configuration.audio_player_artwork_border_radius
59
+ );
60
+ };
@@ -0,0 +1,39 @@
1
+ import { toDayJSLocaleMap } from "@applicaster/zapp-react-native-utils/appUtils/localizationsHelper";
2
+ import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
3
+ import { getUILanguage } from "@applicaster/zapp-react-native-utils/localizationUtils";
4
+
5
+ const createTimerOptions = (value) => {
6
+ let label = "";
7
+
8
+ const str = dayjs
9
+ .duration(value, "minute")
10
+ .locale(toDayJSLocaleMap(getUILanguage()))
11
+ .humanize();
12
+
13
+ if (value === 60) {
14
+ /** Skipping prefix "an"/"un"/"una" for 1 hour */
15
+
16
+ if (str.includes(" ")) {
17
+ label = `1 ${str.split(" ")[1]}`; // Combine "1" with second part of the string
18
+ } else {
19
+ label = `1 ${str}`; // Use dayjs provided translation
20
+ }
21
+ } else {
22
+ label = str;
23
+ }
24
+
25
+ return {
26
+ label,
27
+ value,
28
+ };
29
+ };
30
+
31
+ export const getSleepTimerOptions = (configuration) => {
32
+ return [
33
+ {
34
+ label: configuration["playback_sleep_off_label"],
35
+ value: 0,
36
+ },
37
+ ...[5, 10, 15, 30, 45, 60, 120].map(createTimerOptions),
38
+ ];
39
+ };
@@ -0,0 +1,4 @@
1
+ export const speedOptions = [0.8, 1, 1.2, 1.5, 2].map((v) => ({
2
+ label: v + "x",
3
+ value: v,
4
+ }));
@@ -1,11 +1,6 @@
1
1
  import queryString from "query-string";
2
2
  import { dayjs } from "@applicaster/zapp-react-native-utils/dateUtils";
3
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");
7
- };
8
-
9
4
  export const addQueryParam = (
10
5
  baseUrl: string,
11
6
  paramName: string,
@@ -1 +1,118 @@
1
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
2
+
1
3
  export * from "./Utils";
4
+
5
+ export const getBottomSheetModalIconProps = (theme) => ({
6
+ height: theme["audio_modal_bottom_sheet_item_icon_height"],
7
+ width: theme["audio_modal_bottom_sheet_item_icon_width"],
8
+ marginBottom: theme["audio_modal_bottom_sheet_item_icon_margin_bottom"],
9
+ marginLeft: theme["audio_modal_bottom_sheet_item_icon_margin_left"],
10
+ marginRight: theme["audio_modal_bottom_sheet_item_icon_margin_right"],
11
+ marginTop: theme["audio_modal_bottom_sheet_item_icon_margin_top"],
12
+ flavour: theme["modal_bottom_sheet_item_icon_flavour"],
13
+ });
14
+
15
+ export const getBottomSheetModalLabelProps = (theme, width: number) => {
16
+ const {
17
+ audio_modal_bottom_sheet_item_label_android_letter_spacing,
18
+ audio_modal_bottom_sheet_item_label_ios_letter_spacing,
19
+ audio_modal_bottom_sheet_item_label_family_ios_font_selector,
20
+ audio_modal_bottom_sheet_item_label_family_android_font_selector,
21
+ audio_modal_bottom_sheet_item_label_focus_font_color,
22
+ audio_modal_bottom_sheet_item_label_font_color,
23
+ audio_modal_bottom_sheet_item_label_selected_font_color,
24
+ audio_modal_bottom_sheet_item_label_hover_selected_font_color,
25
+ audio_modal_bottom_sheet_item_label_font_size,
26
+ audio_modal_bottom_sheet_item_label_line_height,
27
+ audio_modal_bottom_sheet_item_label_margin_bottom,
28
+ audio_modal_bottom_sheet_item_label_margin_top,
29
+ audio_modal_bottom_sheet_item_label_margin_left,
30
+ audio_modal_bottom_sheet_item_label_margin_right,
31
+ audio_modal_bottom_sheet_item_label_transform,
32
+ audio_modal_bottom_sheet_item_icon_width,
33
+ audio_modal_bottom_sheet_item_icon_margin_left,
34
+ audio_modal_bottom_sheet_item_icon_margin_right,
35
+ audio_modal_bottom_sheet_item_margin_left,
36
+ audio_modal_bottom_sheet_item_margin_right,
37
+ audio_modal_bottom_sheet_item_padding_left,
38
+ audio_modal_bottom_sheet_item_padding_right,
39
+ } = theme;
40
+
41
+ const maxWidth =
42
+ width -
43
+ (audio_modal_bottom_sheet_item_icon_width +
44
+ audio_modal_bottom_sheet_item_icon_margin_left +
45
+ audio_modal_bottom_sheet_item_icon_margin_right +
46
+ audio_modal_bottom_sheet_item_margin_left +
47
+ audio_modal_bottom_sheet_item_margin_right +
48
+ audio_modal_bottom_sheet_item_padding_left +
49
+ audio_modal_bottom_sheet_item_padding_right);
50
+
51
+ return {
52
+ fontFamily: platformSelect({
53
+ ios: audio_modal_bottom_sheet_item_label_family_ios_font_selector,
54
+ android: audio_modal_bottom_sheet_item_label_family_android_font_selector,
55
+ }),
56
+ letterSpacing: platformSelect({
57
+ ios: audio_modal_bottom_sheet_item_label_ios_letter_spacing,
58
+ android: audio_modal_bottom_sheet_item_label_android_letter_spacing,
59
+ }),
60
+ fontSize: audio_modal_bottom_sheet_item_label_font_size,
61
+ color: audio_modal_bottom_sheet_item_label_font_color,
62
+ focusColor: audio_modal_bottom_sheet_item_label_focus_font_color,
63
+ hoverSelectedColor:
64
+ audio_modal_bottom_sheet_item_label_hover_selected_font_color,
65
+ selectedColor: audio_modal_bottom_sheet_item_label_selected_font_color,
66
+ lineHeight: audio_modal_bottom_sheet_item_label_line_height,
67
+ marginBottom: audio_modal_bottom_sheet_item_label_margin_bottom,
68
+ marginTop: audio_modal_bottom_sheet_item_label_margin_top,
69
+ marginLeft: audio_modal_bottom_sheet_item_label_margin_left,
70
+ marginRight: audio_modal_bottom_sheet_item_label_margin_right,
71
+ transform: audio_modal_bottom_sheet_item_label_transform,
72
+ maxWidth,
73
+ };
74
+ };
75
+
76
+ export const getBottomSheetModalItemProps = (theme, width: number) => {
77
+ const {
78
+ audio_modal_bottom_sheet_item_background_color,
79
+ audio_modal_bottom_sheet_item_focus_background_color,
80
+ audio_modal_bottom_sheet_item_selected_background_color,
81
+ audio_modal_bottom_sheet_item_focused_selected_background_color,
82
+ audio_modal_bottom_sheet_item_corner_radius,
83
+ audio_modal_bottom_sheet_item_margin_bottom,
84
+ audio_modal_bottom_sheet_item_margin_left,
85
+ audio_modal_bottom_sheet_item_margin_right,
86
+ audio_modal_bottom_sheet_item_margin_top,
87
+ audio_modal_bottom_sheet_item_padding_bottom,
88
+ audio_modal_bottom_sheet_item_padding_left,
89
+ audio_modal_bottom_sheet_item_padding_right,
90
+ audio_modal_bottom_sheet_item_padding_top,
91
+ } = theme;
92
+
93
+ return {
94
+ backgroundColor: audio_modal_bottom_sheet_item_background_color,
95
+ focusedBackgroundColor:
96
+ audio_modal_bottom_sheet_item_focus_background_color,
97
+ selectedBackgroundColor:
98
+ audio_modal_bottom_sheet_item_selected_background_color,
99
+ focusedSelectedBackgroundColor:
100
+ audio_modal_bottom_sheet_item_focused_selected_background_color,
101
+ borderRadius: audio_modal_bottom_sheet_item_corner_radius,
102
+ marginBottom: audio_modal_bottom_sheet_item_margin_bottom,
103
+ marginTop: audio_modal_bottom_sheet_item_margin_top,
104
+ marginLeft: audio_modal_bottom_sheet_item_margin_left,
105
+ marginRight: audio_modal_bottom_sheet_item_margin_right,
106
+ paddingTop: audio_modal_bottom_sheet_item_padding_top,
107
+ paddingBottom: audio_modal_bottom_sheet_item_padding_bottom,
108
+ paddingRight: audio_modal_bottom_sheet_item_padding_right,
109
+ paddingLeft: audio_modal_bottom_sheet_item_padding_left,
110
+ maxWidth: width,
111
+ };
112
+ };
113
+
114
+ export const getBottomSheetModalSelectedItemIcon = (theme) =>
115
+ theme["audio_modal_bottom_sheet_item_selected_icon"] || null;
116
+
117
+ export const getBottomSheetModalDefaultItemIcon = (theme) =>
118
+ theme["audio_modal_bottom_sheet_item_default_icon"] || null;
@@ -721,7 +721,7 @@ export default class VideoPlayer extends React.Component<
721
721
 
722
722
  const isAudioItem =
723
723
  entry?.content?.type?.includes?.("audio") ||
724
- entry?.type?.value === "audio";
724
+ entry?.type?.value?.includes?.("audio");
725
725
 
726
726
  const getStyle = (dimensions) => {
727
727
  const generalStyles = isAudioItem ? styles.audio : styles.video;
@@ -791,8 +791,13 @@ export default class VideoPlayer extends React.Component<
791
791
  controls: shouldUseNativeControls,
792
792
  };
793
793
 
794
+ const isFullScreenAudioPlayer =
795
+ this.getPluginConfiguration()?.["full_screen_audio_player"] || false;
796
+
797
+ const isAudioPlayer = isFullScreenAudioPlayer && isAudioItem;
798
+
794
799
  const pictureInPictureEnabled =
795
- this.props.pluginConfiguration?.pictureInPictureEnabled;
800
+ this.props.pluginConfiguration?.pictureInPictureEnabled && !isAudioPlayer;
796
801
 
797
802
  const nativeProps = {
798
803
  entry, // Must be passed first in list
@@ -806,7 +811,6 @@ export default class VideoPlayer extends React.Component<
806
811
  nowPlayingEnabled,
807
812
  paused,
808
813
  seek,
809
- rate,
810
814
  textTrackId,
811
815
  liveSeekingEnabled,
812
816
  liveCatchUpEnabled,
@@ -817,7 +821,14 @@ export default class VideoPlayer extends React.Component<
817
821
  accessibilityProps: getAllAccessibilityProps(
818
822
  this.getPluginConfiguration()
819
823
  ),
820
- }; // rate temporary removed, because of bug with subtitles
824
+ };
825
+
826
+ if (!isAppleTV()) {
827
+ // TODO: Move to RN method and remove from props.
828
+ // Causes tvOS bug: native player passes rate on fast seek,
829
+ // RN returns it and it breaks playback.
830
+ nativeProps.rate = rate;
831
+ }
821
832
 
822
833
  if (
823
834
  this.isReactNativeMethodsSupported() &&
@@ -918,8 +929,8 @@ export default class VideoPlayer extends React.Component<
918
929
  const playerContainerStyles = isApplePlatform()
919
930
  ? styles.playerContainerBlack
920
931
  : isTV() && isAudioItem
921
- ? styles.playerContainerTransparent
922
- : styles.playerContainerBlack;
932
+ ? styles.playerContainerTransparent
933
+ : styles.playerContainerBlack;
923
934
 
924
935
  const isInline = () => {
925
936
  if (isTV()) {
@@ -960,9 +971,6 @@ export default class VideoPlayer extends React.Component<
960
971
  ) : null;
961
972
  };
962
973
 
963
- const isFullScreenAudioPlayer =
964
- this.getPluginConfiguration()?.["full_screen_audio_player"] || false;
965
-
966
974
  const sharedWrapperViewProps = {
967
975
  style,
968
976
  entry,
@@ -989,15 +997,16 @@ export default class VideoPlayer extends React.Component<
989
997
 
990
998
  const renderMobilePlayer = () => {
991
999
  return isFullScreenAudioPlayer && isAudioItem ? (
992
- <View style={containerStyle}>
993
- {(!castAction?.state?.connected || supportNativeCast) && (
1000
+ // Ensure the View remains in the native hierarchy for proper rendering and interaction
1001
+ <View collapsable={false} style={containerStyle}>
1002
+ {!castAction?.state?.connected || supportNativeCast ? (
994
1003
  <this.props.PlayerComponent
995
1004
  ref={this._assignRoot}
996
1005
  {...nativeEvents}
997
1006
  {...nativeProps}
998
1007
  listener={this.props.listener}
999
1008
  />
1000
- )}
1009
+ ) : null}
1001
1010
  <AudioPlayerWrapper {...sharedWrapperViewProps} />
1002
1011
  </View>
1003
1012
  ) : (
@@ -1012,7 +1021,7 @@ export default class VideoPlayer extends React.Component<
1012
1021
  return (
1013
1022
  <View style={styles.container}>
1014
1023
  <View style={[playerContainerStyles, playerDimensions]}>
1015
- {isAudioItem && (
1024
+ {isAudioItem ? (
1016
1025
  <AnimationComponent
1017
1026
  animationType={ComponentAnimationType.player}
1018
1027
  additionalData={{
@@ -1031,21 +1040,24 @@ export default class VideoPlayer extends React.Component<
1031
1040
  plugin_configuration={this.getPluginConfiguration()}
1032
1041
  />
1033
1042
  </AnimationComponent>
1034
- )}
1043
+ ) : null}
1035
1044
 
1036
- {shouldRenderBackground && (
1045
+ {shouldRenderBackground ? (
1037
1046
  <PlayerImageBackground
1038
1047
  imageKey={backgroundImageKey}
1039
1048
  configuration={this.getPluginConfiguration()}
1040
1049
  entry={entry}
1041
1050
  style={getBackgroundImageStyle(playerDimensions)}
1042
1051
  />
1043
- )}
1052
+ ) : null}
1044
1053
 
1045
- {(!castAction?.state?.connected || supportNativeCast) && (
1054
+ {!castAction?.state?.connected || supportNativeCast ? (
1046
1055
  <AnimationComponent
1047
1056
  animationType={ComponentAnimationType.player}
1048
- additionalData={playerDimensions}
1057
+ additionalData={{
1058
+ ...playerDimensions,
1059
+ disableAnimatedComponent: isAudioItem,
1060
+ }}
1049
1061
  style={getStyle(playerDimensions)}
1050
1062
  >
1051
1063
  <this.props.PlayerComponent
@@ -1064,7 +1076,7 @@ export default class VideoPlayer extends React.Component<
1064
1076
  {this.childrenWithPlayNext()}
1065
1077
  </this.props.PlayerComponent>
1066
1078
  </AnimationComponent>
1067
- )}
1079
+ ) : null}
1068
1080
  </View>
1069
1081
 
1070
1082
  {renderTransportControls(playerDimensions)}