@applicaster/quick-brick-player 13.0.0-rc.13 → 13.0.0-rc.131

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 (49) hide show
  1. package/package.json +27 -14
  2. package/src/CellPlayer/Assets/AssetsComponent.tsx +17 -3
  3. package/src/Player/AudioLayer/AudioDescription.tsx +107 -68
  4. package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +142 -295
  5. package/src/Player/AudioLayer/Layout/Controls/VerticalGutter.tsx +45 -0
  6. package/src/Player/AudioLayer/Layout/Controls/index.tsx +291 -0
  7. package/src/Player/AudioLayer/Layout/{defaultLayoutsConts.ts → Controls/utils.ts} +9 -27
  8. package/src/Player/AudioLayer/Layout/Debug/index.tsx +55 -0
  9. package/src/Player/AudioLayer/Layout/{DockedLayout.tsx → DockedControls/index.tsx} +77 -81
  10. package/src/Player/AudioLayer/Layout/MobileLayout.tsx +222 -0
  11. package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +87 -0
  12. package/src/Player/AudioLayer/Layout/PlayerImage/FlexImage.tsx +20 -0
  13. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/index.ts +1 -0
  14. package/src/Player/AudioLayer/Layout/PlayerImage/hooks/useChangePlayerState.ts +99 -0
  15. package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +112 -0
  16. package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +36 -0
  17. package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +212 -0
  18. package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +215 -0
  19. package/src/Player/AudioLayer/Layout/TransportInfo/index.tsx +128 -0
  20. package/src/Player/AudioLayer/Layout/VerticalGutter/index.tsx +8 -0
  21. package/src/Player/AudioLayer/Layout/const.ts +26 -0
  22. package/src/Player/AudioLayer/Layout/debug.ts +6 -0
  23. package/src/Player/AudioLayer/Layout/hooks/index.ts +5 -0
  24. package/src/Player/AudioLayer/Layout/hooks/useMobileLayoutImageSize.ts +14 -0
  25. package/src/Player/AudioLayer/Layout/hooks/useTabletLayoutImageSize.ts +105 -0
  26. package/src/Player/AudioLayer/Layout/hooks/useTransportInfoHeight.ts +54 -0
  27. package/src/Player/AudioLayer/Layout/index.tsx +21 -48
  28. package/src/Player/AudioLayer/Layout/types.ts +7 -0
  29. package/src/Player/AudioLayer/Layout/utils.ts +7 -0
  30. package/src/Player/AudioLayer/SleepTimerManager.ts +130 -0
  31. package/src/Player/AudioLayer/SpeedManager.ts +52 -0
  32. package/src/Player/AudioLayer/components/SleepTimerModalHeader/SleepTimerModalHeader.tsx +66 -0
  33. package/src/Player/AudioLayer/components/SleepTimerModalHeader/index.ts +1 -0
  34. package/src/Player/AudioLayer/useSleepTimerModal.ts +109 -0
  35. package/src/Player/AudioLayer/utils.ts +27 -0
  36. package/src/Player/Const/sleepTimerOptions.ts +41 -0
  37. package/src/Player/Const/speedOptions.ts +4 -0
  38. package/src/Player/Utils/Utils.ts +0 -5
  39. package/src/Player/Utils/index.tsx +123 -0
  40. package/src/Player/hooks/useIsCasting.tsx +57 -0
  41. package/src/Player/index.tsx +106 -49
  42. package/src/QuickBrickPlayer.tsx +3 -0
  43. package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +0 -452
  44. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.ts +0 -3
  45. package/src/Player/AudioLayer/LinearGradient/LinearGradientProxy.web.ts +0 -3
  46. package/src/Player/AudioLayer/LinearGradient/index.ts +0 -1
  47. package/src/Player/AudioLayer/MagicBG/index.tsx +0 -155
  48. package/src/Player/Helpers/VideoResizeMode.ts +0 -7
  49. package/src/utils/utils.ts +0 -25
@@ -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,124 @@
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;
119
+
120
+ export const selectSleepTitle = (configuration) =>
121
+ configuration.playback_sleep_title;
122
+
123
+ export const selectSleepOffLabel = (configuration) =>
124
+ configuration.playback_sleep_off_label;
@@ -0,0 +1,57 @@
1
+ import React from "react";
2
+ import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
3
+ import { useAppState } from "@applicaster/zapp-react-native-utils/reactHooks/app";
4
+ import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
5
+
6
+ const CHROMECAST_IDENTIFIER = "quick-brick-chromecast-action";
7
+
8
+ const fakeEntry: any = {
9
+ title: "Chromecast use is casting fake entry",
10
+ id: "quick-brick-use-is-casting-fake-entry",
11
+ };
12
+
13
+ /**
14
+ * Returns the cast action state connection status, does not update when app is in background on Apple platforms
15
+ * On other platforms, it continues to check the cast action state even when the app is in background
16
+ */
17
+ export const useIsCasting = () => {
18
+ const actionContext = useActions(CHROMECAST_IDENTIFIER);
19
+ const appState = useAppState();
20
+ const isAppInForeground = appState === "active";
21
+ const shouldOnlyUpdateInForeground = isApplePlatform();
22
+
23
+ const [castActionState, setCastActionState] = React.useState(
24
+ !actionContext ? null : actionContext.initialEntryState(fakeEntry)
25
+ );
26
+
27
+ React.useEffect(() => {
28
+ if (!shouldOnlyUpdateInForeground || isAppInForeground) {
29
+ if (actionContext && castActionState === null) {
30
+ setCastActionState(actionContext.initialEntryState(fakeEntry));
31
+ }
32
+ }
33
+ }, [
34
+ actionContext,
35
+ setCastActionState,
36
+ isAppInForeground,
37
+ shouldOnlyUpdateInForeground,
38
+ ]);
39
+
40
+ React.useEffect(() => {
41
+ if (typeof actionContext?.addListener === "function") {
42
+ return actionContext?.addListener(String(fakeEntry.id), (state) => {
43
+ // Only check foreground state on Apple platforms
44
+ if (!shouldOnlyUpdateInForeground || isAppInForeground) {
45
+ setCastActionState(state);
46
+ }
47
+ });
48
+ }
49
+ }, [
50
+ setCastActionState,
51
+ actionContext,
52
+ isAppInForeground,
53
+ shouldOnlyUpdateInForeground,
54
+ ]);
55
+
56
+ return !!castActionState?.connected;
57
+ };
@@ -4,6 +4,8 @@
4
4
  import React from "react";
5
5
  import * as R from "ramda";
6
6
 
7
+ import { flatten } from "@applicaster/zapp-react-native-utils/utils";
8
+
7
9
  import { findNodeHandle, StyleSheet, View } from "react-native";
8
10
  import TransportControlsMobile from "@applicaster/quick-brick-mobile-transport-controls";
9
11
  import TransportControlsTV from "@applicaster/quick-brick-tv-transport-controls";
@@ -40,6 +42,7 @@ import { PlayerAnalyticsManager } from "@applicaster/zapp-react-native-utils/ana
40
42
  import { PlayerAnalyticsTrackerI } from "@applicaster/zapp-react-native-utils/analyticsUtils/playerAnalyticsTracker";
41
43
 
42
44
  import { RNPlayerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/nativePlayerManager";
45
+ import { isAudioItem as isAudioItemUtil } from "@applicaster/zapp-react-native-utils/playerUtils";
43
46
 
44
47
  const styles = StyleSheet.create({
45
48
  container: { flex: 1 },
@@ -50,6 +53,7 @@ const styles = StyleSheet.create({
50
53
  position: "absolute",
51
54
  zIndex: 1,
52
55
  },
56
+ audioPlayerSize: { width: "100%", height: "100%" },
53
57
  playerSize: { width: "100%", height: "100%" },
54
58
  });
55
59
 
@@ -58,6 +62,10 @@ const logger = createLogger({
58
62
  subsystem: Subsystem,
59
63
  });
60
64
 
65
+ const isTvOS = isTvOSPlatform();
66
+
67
+ const AUDIO_PLAYER_NATIVE_ID = "audio-player-view";
68
+
61
69
  export default class VideoPlayer extends React.Component<
62
70
  QuickBrickPlayer.PlayerProps,
63
71
  QuickBrickPlayer.NativePlayerState
@@ -74,6 +82,7 @@ export default class VideoPlayer extends React.Component<
74
82
  state: QuickBrickPlayer.NativePlayerState = {
75
83
  audioTrackId: null,
76
84
  textTrackId: null,
85
+ isCasting: this.props.isCasting,
77
86
 
78
87
  // TODO: Can be deleted, on controller logic
79
88
  isAd: false,
@@ -92,6 +101,8 @@ export default class VideoPlayer extends React.Component<
92
101
  // Player state
93
102
  currentTime: 0,
94
103
  duration: 0,
104
+
105
+ nativePlayerIsReady: false,
95
106
  };
96
107
 
97
108
  private _tracker: PlayerAnalyticsTrackerI;
@@ -487,6 +498,9 @@ export default class VideoPlayer extends React.Component<
487
498
 
488
499
  onVideoFullscreenPlayerDidPresent = () => {
489
500
  this.props.listener?.onVideoFullscreenPlayerDidPresent?.();
501
+
502
+ // we have to have a signal that player is ready, in order to show audio_player(for example)
503
+ this.setState({ nativePlayerIsReady: true });
490
504
  };
491
505
 
492
506
  onVideoFullscreenPlayerWillDismiss = () => {
@@ -672,32 +686,57 @@ export default class VideoPlayer extends React.Component<
672
686
  }
673
687
  };
674
688
 
675
- childrenWithPlayNext = () => {
676
- if (!isTvOSPlatform() || !this.getPlayNextData()) {
677
- return this.props.children;
689
+ childrenWithExtensions = () => {
690
+ const { docked, entry, children } = this.props;
691
+
692
+ if (!isTvOS) {
693
+ return children;
678
694
  }
679
695
 
680
- // tvos only
681
- const { docked, entry } = this.props;
682
-
683
- const children = R.pathOr([], "children", this.props);
684
-
685
- return [
686
- ...children,
687
- <PlayNextOverlay
688
- key="play-next-overlay"
689
- item={entry}
690
- playerIsDocked={docked}
691
- pluginConfiguration={this.getPluginConfiguration()}
692
- playerId={this.props.playerId}
693
- playNextData={this.getPlayNextData()}
694
- setNextVideoPreloadThresholdPercentage={
695
- this.props.setNextVideoPreloadThresholdPercentage
696
- }
697
- />,
698
- ];
696
+ const output = [];
697
+
698
+ // audio-player
699
+ if (isAudioItemUtil(entry)) {
700
+ const { nativePlayerIsReady } = this.state;
701
+
702
+ // we have to wait ready status of native player view, before showing audio_player
703
+ if (nativePlayerIsReady) {
704
+ output.push(
705
+ <View nativeID={AUDIO_PLAYER_NATIVE_ID} key={AUDIO_PLAYER_NATIVE_ID}>
706
+ {children}
707
+ </View>
708
+ );
709
+ }
710
+ } else {
711
+ output.push(children);
712
+ }
713
+ // audio-player
714
+
715
+ // play-next
716
+ if (this.getPlayNextData()) {
717
+ output.push(
718
+ <PlayNextOverlay
719
+ key="play-next-overlay"
720
+ item={entry}
721
+ playerIsDocked={docked}
722
+ pluginConfiguration={this.getPluginConfiguration()}
723
+ playerId={this.props.playerId}
724
+ playNextData={this.getPlayNextData()}
725
+ setNextVideoPreloadThresholdPercentage={
726
+ this.props.setNextVideoPreloadThresholdPercentage
727
+ }
728
+ />
729
+ );
730
+ }
731
+ // play-next
732
+
733
+ return flatten(output); // prevent possible case with nested array
699
734
  };
700
735
 
736
+ get supportNativeCast() {
737
+ return this.props.controller.supportNativeCast();
738
+ }
739
+
701
740
  render() {
702
741
  const {
703
742
  docked,
@@ -710,18 +749,13 @@ export default class VideoPlayer extends React.Component<
710
749
  muted,
711
750
  style,
712
751
  castAction,
713
- controller,
714
752
  startComponentsAnimation,
715
753
  } = this.props;
716
754
 
717
- const supportNativeCast = controller.supportNativeCast();
718
-
719
755
  const { audioTrackId, keyEvent, paused, seek, textTrackId, rate } =
720
756
  this.state;
721
757
 
722
- const isAudioItem =
723
- entry?.content?.type?.includes?.("audio") ||
724
- entry?.type?.value === "audio";
758
+ const isAudioItem = isAudioItemUtil(entry);
725
759
 
726
760
  const getStyle = (dimensions) => {
727
761
  const generalStyles = isAudioItem ? styles.audio : styles.video;
@@ -791,8 +825,13 @@ export default class VideoPlayer extends React.Component<
791
825
  controls: shouldUseNativeControls,
792
826
  };
793
827
 
828
+ const isFullScreenAudioPlayer =
829
+ this.getPluginConfiguration()?.["full_screen_audio_player"] || false;
830
+
831
+ const isAudioPlayer = isFullScreenAudioPlayer && isAudioItem;
832
+
794
833
  const pictureInPictureEnabled =
795
- this.props.pluginConfiguration?.pictureInPictureEnabled;
834
+ this.props.pluginConfiguration?.pictureInPictureEnabled && !isAudioPlayer;
796
835
 
797
836
  const nativeProps = {
798
837
  entry, // Must be passed first in list
@@ -806,7 +845,6 @@ export default class VideoPlayer extends React.Component<
806
845
  nowPlayingEnabled,
807
846
  paused,
808
847
  seek,
809
- rate,
810
848
  textTrackId,
811
849
  liveSeekingEnabled,
812
850
  liveCatchUpEnabled,
@@ -817,7 +855,14 @@ export default class VideoPlayer extends React.Component<
817
855
  accessibilityProps: getAllAccessibilityProps(
818
856
  this.getPluginConfiguration()
819
857
  ),
820
- }; // rate temporary removed, because of bug with subtitles
858
+ };
859
+
860
+ if (!isAppleTV()) {
861
+ // TODO: Move to RN method and remove from props.
862
+ // Causes tvOS bug: native player passes rate on fast seek,
863
+ // RN returns it and it breaks playback.
864
+ nativeProps.rate = rate;
865
+ }
821
866
 
822
867
  if (
823
868
  this.isReactNativeMethodsSupported() &&
@@ -918,8 +963,8 @@ export default class VideoPlayer extends React.Component<
918
963
  const playerContainerStyles = isApplePlatform()
919
964
  ? styles.playerContainerBlack
920
965
  : isTV() && isAudioItem
921
- ? styles.playerContainerTransparent
922
- : styles.playerContainerBlack;
966
+ ? styles.playerContainerTransparent
967
+ : styles.playerContainerBlack;
923
968
 
924
969
  const isInline = () => {
925
970
  if (isTV()) {
@@ -960,9 +1005,6 @@ export default class VideoPlayer extends React.Component<
960
1005
  ) : null;
961
1006
  };
962
1007
 
963
- const isFullScreenAudioPlayer =
964
- this.getPluginConfiguration()?.["full_screen_audio_player"] || false;
965
-
966
1008
  const sharedWrapperViewProps = {
967
1009
  style,
968
1010
  entry,
@@ -987,17 +1029,21 @@ export default class VideoPlayer extends React.Component<
987
1029
  const backgroundImageKey =
988
1030
  this.getPluginConfiguration()?.player_preview_image_key;
989
1031
 
1032
+ const shouldRenderNativePlayer =
1033
+ !this.props.isCasting || this.supportNativeCast;
1034
+
990
1035
  const renderMobilePlayer = () => {
991
1036
  return isFullScreenAudioPlayer && isAudioItem ? (
992
- <View style={containerStyle}>
993
- {(!castAction?.state?.connected || supportNativeCast) && (
1037
+ // Ensure the View remains in the native hierarchy for proper rendering and interaction
1038
+ <View collapsable={false} style={containerStyle}>
1039
+ {shouldRenderNativePlayer ? (
994
1040
  <this.props.PlayerComponent
995
1041
  ref={this._assignRoot}
996
1042
  {...nativeEvents}
997
1043
  {...nativeProps}
998
1044
  listener={this.props.listener}
999
1045
  />
1000
- )}
1046
+ ) : null}
1001
1047
  <AudioPlayerWrapper {...sharedWrapperViewProps} />
1002
1048
  </View>
1003
1049
  ) : (
@@ -1012,7 +1058,7 @@ export default class VideoPlayer extends React.Component<
1012
1058
  return (
1013
1059
  <View style={styles.container}>
1014
1060
  <View style={[playerContainerStyles, playerDimensions]}>
1015
- {isAudioItem && (
1061
+ {isAudioItem ? (
1016
1062
  <AnimationComponent
1017
1063
  animationType={ComponentAnimationType.player}
1018
1064
  additionalData={{
@@ -1031,21 +1077,24 @@ export default class VideoPlayer extends React.Component<
1031
1077
  plugin_configuration={this.getPluginConfiguration()}
1032
1078
  />
1033
1079
  </AnimationComponent>
1034
- )}
1080
+ ) : null}
1035
1081
 
1036
- {shouldRenderBackground && (
1082
+ {shouldRenderBackground ? (
1037
1083
  <PlayerImageBackground
1038
1084
  imageKey={backgroundImageKey}
1039
1085
  configuration={this.getPluginConfiguration()}
1040
1086
  entry={entry}
1041
1087
  style={getBackgroundImageStyle(playerDimensions)}
1042
1088
  />
1043
- )}
1089
+ ) : null}
1044
1090
 
1045
- {(!castAction?.state?.connected || supportNativeCast) && (
1091
+ {shouldRenderNativePlayer ? (
1046
1092
  <AnimationComponent
1047
1093
  animationType={ComponentAnimationType.player}
1048
- additionalData={playerDimensions}
1094
+ additionalData={{
1095
+ ...playerDimensions,
1096
+ disableAnimatedComponent: isAudioItem,
1097
+ }}
1049
1098
  style={getStyle(playerDimensions)}
1050
1099
  >
1051
1100
  <this.props.PlayerComponent
@@ -1061,10 +1110,10 @@ export default class VideoPlayer extends React.Component<
1061
1110
  pluginConfiguration={this.getPluginConfiguration()}
1062
1111
  controller={this.props.controller}
1063
1112
  >
1064
- {this.childrenWithPlayNext()}
1113
+ {this.props.children}
1065
1114
  </this.props.PlayerComponent>
1066
1115
  </AnimationComponent>
1067
- )}
1116
+ ) : null}
1068
1117
  </View>
1069
1118
 
1070
1119
  {renderTransportControls(playerDimensions)}
@@ -1090,6 +1139,14 @@ export default class VideoPlayer extends React.Component<
1090
1139
  const renderTVPlayer = () => {
1091
1140
  return (
1092
1141
  <View style={this.takeParentStyle} testID={"player-view"}>
1142
+ {!isTvOS && isAudioItem ? (
1143
+ <AudioPlayer
1144
+ style={getStyle(styles.audioPlayerSize)}
1145
+ audio_item={entry}
1146
+ plugin_configuration={this.getPluginConfiguration()}
1147
+ />
1148
+ ) : null}
1149
+
1093
1150
  <this.props.PlayerComponent
1094
1151
  ref={this._assignRoot}
1095
1152
  {...nativeEvents}
@@ -1099,11 +1156,11 @@ export default class VideoPlayer extends React.Component<
1099
1156
  pluginConfiguration={this.getPluginConfiguration()}
1100
1157
  controller={this.props.controller}
1101
1158
  >
1102
- {this.childrenWithPlayNext()}
1159
+ {this.childrenWithExtensions()}
1103
1160
  </this.props.PlayerComponent>
1104
1161
 
1105
1162
  {renderTransportControls(this.takeParentStyle)}
1106
- {!isTvOSPlatform() && (
1163
+ {!isTvOS && (
1107
1164
  <PlayNextOverlay
1108
1165
  item={entry}
1109
1166
  playerIsDocked={docked}
@@ -5,6 +5,7 @@ import Player from "./Player";
5
5
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
6
6
  import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
7
7
  import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
8
+ import { useIsCasting } from "./Player/hooks/useIsCasting";
8
9
 
9
10
  const CHROMECAST_IDENTIFIER = "quick-brick-chromecast-action";
10
11
 
@@ -24,6 +25,7 @@ const QuickBrickPlayerComponent = (
24
25
  }, [props.PlayerComponent]);
25
26
 
26
27
  const castAction = useActions(CHROMECAST_IDENTIFIER);
28
+ const isCasting = useIsCasting();
27
29
 
28
30
  const isModal = Boolean(props?.isModal);
29
31
  const isScreenDisabled = !controller?.isFullScreenSupported() || !isModal;
@@ -48,6 +50,7 @@ const QuickBrickPlayerComponent = (
48
50
  {...props}
49
51
  ref={ref}
50
52
  castAction={!props?.disableCastAction && castAction}
53
+ isCasting={isCasting}
51
54
  PlayerComponent={props.PlayerComponent}
52
55
  openPiP={openPiP}
53
56
  closePiP={closePiP}