@applicaster/quick-brick-player 12.0.0-rc.7 → 12.0.0-rc.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -6
- package/src/CellPlayer/Assets/AssetsComponent.tsx +2 -1
- package/src/Player/AudioLayer/AudioDescription.tsx +3 -3
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +276 -58
- package/src/Player/AudioLayer/Layout/DefaultLayout.tsx +261 -72
- package/src/Player/AudioLayer/Layout/DockedLayout.tsx +74 -23
- package/src/Player/AudioLayer/Layout/defaultLayoutsConts.ts +32 -1
- package/src/Player/AudioLayer/Layout/index.tsx +9 -7
- package/src/Player/AudioLayer/MagicBG/index.tsx +96 -27
- package/src/Player/AudioLayer/utils.ts +33 -0
- package/src/Player/Utils/Utils.ts +26 -16
- package/src/Player/Utils/index.tsx +0 -2
- package/src/Player/index.tsx +115 -54
|
@@ -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
|
|
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:
|
|
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
|
-
|
|
47
|
-
|
|
64
|
+
defaultColors.defaultGradientStart,
|
|
65
|
+
defaultColors.defaultGradientEnd,
|
|
48
66
|
]);
|
|
49
67
|
|
|
50
|
-
React.
|
|
51
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const animateColors = () => {
|
|
73
|
+
Animated.timing(backgroundColorAnim, {
|
|
74
|
+
toValue: 1,
|
|
75
|
+
duration: 500,
|
|
76
|
+
useNativeDriver: false,
|
|
77
|
+
}).start();
|
|
60
78
|
|
|
61
|
-
|
|
79
|
+
Animated.timing(gradientOpacityAnim, {
|
|
80
|
+
toValue: 1,
|
|
81
|
+
duration: 500,
|
|
82
|
+
useNativeDriver: false,
|
|
83
|
+
}).start();
|
|
84
|
+
};
|
|
62
85
|
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
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
|
-
}, [
|
|
127
|
+
}, []);
|
|
128
|
+
|
|
129
|
+
const interpolatedBackgroundColor = backgroundColorAnim.interpolate({
|
|
130
|
+
inputRange: [0, 1],
|
|
131
|
+
outputRange: ["black", dominantColor],
|
|
132
|
+
});
|
|
78
133
|
|
|
79
134
|
return (
|
|
80
|
-
<View
|
|
135
|
+
<Animated.View
|
|
136
|
+
style={[
|
|
137
|
+
styles.container,
|
|
138
|
+
{ backgroundColor: interpolatedBackgroundColor },
|
|
139
|
+
]}
|
|
140
|
+
>
|
|
81
141
|
<View style={styles.fullScreenOverlay} />
|
|
82
|
-
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
14
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
20
|
+
const updatedQueryString = queryString.stringify(parsedQuery);
|
|
21
|
+
|
|
22
|
+
return `${urlWithoutQuery}?${updatedQueryString}`;
|
|
23
|
+
};
|
|
19
24
|
|
|
20
|
-
|
|
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
|
};
|
package/src/Player/index.tsx
CHANGED
|
@@ -36,6 +36,12 @@ 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
|
+
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";
|
|
39
45
|
|
|
40
46
|
const RNPlayerManager = {
|
|
41
47
|
QuickBrickPlayerPlugin: isApplePlatform()
|
|
@@ -55,6 +61,7 @@ const styles = StyleSheet.create({
|
|
|
55
61
|
position: "absolute",
|
|
56
62
|
zIndex: 1,
|
|
57
63
|
},
|
|
64
|
+
playerSize: { width: "100%", height: "100%" },
|
|
58
65
|
});
|
|
59
66
|
|
|
60
67
|
const logger = createLogger({
|
|
@@ -87,7 +94,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
87
94
|
// TODO: Can be deleted, on controller logic
|
|
88
95
|
paused: false,
|
|
89
96
|
piped: false,
|
|
90
|
-
rate: 1,
|
|
97
|
+
rate: 1.0,
|
|
91
98
|
// TODO: Hack for analytics, must br removed
|
|
92
99
|
resume: null,
|
|
93
100
|
|
|
@@ -368,6 +375,10 @@ export default class VideoPlayer extends React.Component<
|
|
|
368
375
|
}
|
|
369
376
|
};
|
|
370
377
|
|
|
378
|
+
setPlaybackRate = (rate = 1.0) => {
|
|
379
|
+
this.setState({ rate });
|
|
380
|
+
};
|
|
381
|
+
|
|
371
382
|
getCurrentTime = () => {
|
|
372
383
|
return this.state.currentTime;
|
|
373
384
|
};
|
|
@@ -551,6 +562,26 @@ export default class VideoPlayer extends React.Component<
|
|
|
551
562
|
this.props.listener?.onPlayerDetached?.(nativeEvent);
|
|
552
563
|
};
|
|
553
564
|
|
|
565
|
+
onVideoFullscreenPlayerDidDismiss = () => {
|
|
566
|
+
this.props.listener?.onVideoFullscreenPlayerDidDismiss?.();
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
onVideoFullscreenPlayerDidPresent = () => {
|
|
570
|
+
this.props.listener?.onVideoFullscreenPlayerDidPresent?.();
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
onVideoFullscreenPlayerWillDismiss = () => {
|
|
574
|
+
this.props.listener?.onVideoFullscreenPlayerWillDismiss?.();
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
onVideoFullscreenPlayerWillPresent = () => {
|
|
578
|
+
this.props.listener?.onVideoFullscreenPlayerWillPresent?.();
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
onPlayerClose = () => {
|
|
582
|
+
this.props.listener?.onPlayerClose?.();
|
|
583
|
+
};
|
|
584
|
+
|
|
554
585
|
onPiPEnter = () => {
|
|
555
586
|
this.setState({ piped: true });
|
|
556
587
|
this.props.openPiP();
|
|
@@ -754,8 +785,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
754
785
|
|
|
755
786
|
render() {
|
|
756
787
|
const {
|
|
757
|
-
castAction,
|
|
758
|
-
controls,
|
|
759
788
|
docked,
|
|
760
789
|
entry,
|
|
761
790
|
fullscreen,
|
|
@@ -765,9 +794,15 @@ export default class VideoPlayer extends React.Component<
|
|
|
765
794
|
isTabletPortrait,
|
|
766
795
|
muted,
|
|
767
796
|
style,
|
|
797
|
+
castAction,
|
|
798
|
+
controller,
|
|
799
|
+
startComponentsAnimation,
|
|
768
800
|
} = this.props;
|
|
769
801
|
|
|
770
|
-
const
|
|
802
|
+
const supportNativeCast = controller.supportNativeCast();
|
|
803
|
+
|
|
804
|
+
const { audioTrackId, keyEvent, paused, seek, textTrackId, rate } =
|
|
805
|
+
this.state;
|
|
771
806
|
|
|
772
807
|
const isAudioItem =
|
|
773
808
|
entry?.content?.type?.includes?.("audio") ||
|
|
@@ -812,17 +847,35 @@ export default class VideoPlayer extends React.Component<
|
|
|
812
847
|
const liveCatchUpEnabled =
|
|
813
848
|
this.props.pluginConfiguration?.liveCatchUpEnabled;
|
|
814
849
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
850
|
+
// TODO: Get screen data more reliable way useCurrentScreenData
|
|
851
|
+
const screenData = getTargetScreenDataFromEntry(this.props.playableItem);
|
|
852
|
+
|
|
853
|
+
const isInlineTV = screenData?.ui_components?.length > 0 && isTV();
|
|
818
854
|
|
|
819
|
-
|
|
855
|
+
let platformSpecificProps: any = isApplePlatform()
|
|
820
856
|
? {
|
|
821
|
-
...hideNativeControls,
|
|
822
857
|
resizeMode: nativeResizeMode,
|
|
823
858
|
}
|
|
824
859
|
: {};
|
|
825
860
|
|
|
861
|
+
const supportsNativeControls =
|
|
862
|
+
!!this.props.controller?.supportsNativeControls?.();
|
|
863
|
+
|
|
864
|
+
const controls = isAppleTV()
|
|
865
|
+
? supportsNativeControls && !isInlineTV && !this.getPlayNextData()
|
|
866
|
+
: supportsNativeControls && !this.getPlayNextData();
|
|
867
|
+
|
|
868
|
+
const shouldUseNativeControls =
|
|
869
|
+
controls &&
|
|
870
|
+
!startComponentsAnimation &&
|
|
871
|
+
!docked &&
|
|
872
|
+
!castAction?.state?.connected;
|
|
873
|
+
|
|
874
|
+
platformSpecificProps = {
|
|
875
|
+
...platformSpecificProps,
|
|
876
|
+
controls: shouldUseNativeControls,
|
|
877
|
+
};
|
|
878
|
+
|
|
826
879
|
const pictureInPictureEnabled =
|
|
827
880
|
this.props.pluginConfiguration?.pictureInPictureEnabled;
|
|
828
881
|
|
|
@@ -830,7 +883,6 @@ export default class VideoPlayer extends React.Component<
|
|
|
830
883
|
entry, // Must be passed first in list
|
|
831
884
|
...platformSpecificProps,
|
|
832
885
|
audioTrackId,
|
|
833
|
-
controls,
|
|
834
886
|
docked,
|
|
835
887
|
enableAutoAudioTrackSelection,
|
|
836
888
|
fullscreen, // TODO: Check fullscreen params not crash
|
|
@@ -839,6 +891,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
839
891
|
nowPlayingEnabled,
|
|
840
892
|
paused,
|
|
841
893
|
seek,
|
|
894
|
+
rate,
|
|
842
895
|
textTrackId,
|
|
843
896
|
liveSeekingEnabled,
|
|
844
897
|
liveCatchUpEnabled,
|
|
@@ -884,22 +937,17 @@ export default class VideoPlayer extends React.Component<
|
|
|
884
937
|
onVideoEnd: this.onVideoEnd, // complete
|
|
885
938
|
onVideoError: this.onVideoError, // error
|
|
886
939
|
onVideoProgress: this.onVideoProgress,
|
|
887
|
-
onVideoFullscreenPlayerDidDismiss: this.
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
onVideoFullscreenPlayerWillDismiss: this.unHandledEvent(
|
|
894
|
-
"onVideoFullscreenPlayerWillDismiss"
|
|
895
|
-
),
|
|
896
|
-
onVideoFullscreenPlayerWillPresent: this.unHandledEvent(
|
|
897
|
-
"onVideoFullscreenPlayerWillPresent"
|
|
898
|
-
),
|
|
940
|
+
onVideoFullscreenPlayerDidDismiss: this.onVideoFullscreenPlayerDidDismiss,
|
|
941
|
+
onVideoFullscreenPlayerDidPresent: this.onVideoFullscreenPlayerDidPresent,
|
|
942
|
+
onVideoFullscreenPlayerWillDismiss:
|
|
943
|
+
this.onVideoFullscreenPlayerWillDismiss,
|
|
944
|
+
onVideoFullscreenPlayerWillPresent:
|
|
945
|
+
this.onVideoFullscreenPlayerWillPresent,
|
|
899
946
|
onVideoLoad: this.onVideoLoad,
|
|
900
947
|
onVideoLoadStart: this.unHandledEvent("onVideoLoadStart"),
|
|
901
948
|
onVideoBuffer: this.onVideoBuffer,
|
|
902
949
|
onPlaybackStalled: this.onPlaybackStalled,
|
|
950
|
+
onPlayerClose: this.onPlayerClose,
|
|
903
951
|
onPlayerAttached: this.onPlayerAttached,
|
|
904
952
|
onPlayerDetached: this.onPlayerDetached,
|
|
905
953
|
};
|
|
@@ -973,7 +1021,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
973
1021
|
!needToShowPlayNextOverlay &&
|
|
974
1022
|
this.props.mode !== "PIP";
|
|
975
1023
|
|
|
976
|
-
if (
|
|
1024
|
+
if (shouldUseNativeControls) {
|
|
977
1025
|
return null;
|
|
978
1026
|
}
|
|
979
1027
|
|
|
@@ -992,6 +1040,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
992
1040
|
extraInfoText={castAction?.state?.friendlyStatus}
|
|
993
1041
|
controlsAlwaysVisible={castAction?.state?.connected}
|
|
994
1042
|
playNextData={this.getPlayNextData()}
|
|
1043
|
+
nativeControls={!!controls}
|
|
995
1044
|
/>
|
|
996
1045
|
) : null;
|
|
997
1046
|
};
|
|
@@ -1005,10 +1054,12 @@ export default class VideoPlayer extends React.Component<
|
|
|
1005
1054
|
inline,
|
|
1006
1055
|
docked,
|
|
1007
1056
|
isModal,
|
|
1057
|
+
pip: this.state.piped,
|
|
1008
1058
|
layoutState: {
|
|
1009
1059
|
inline,
|
|
1010
1060
|
docked,
|
|
1011
1061
|
isModal,
|
|
1062
|
+
pip: this.state.piped,
|
|
1012
1063
|
},
|
|
1013
1064
|
configuration: this.getPluginConfiguration(),
|
|
1014
1065
|
fullscreen: fullscreen,
|
|
@@ -1024,29 +1075,14 @@ export default class VideoPlayer extends React.Component<
|
|
|
1024
1075
|
const renderMobilePlayer = () => {
|
|
1025
1076
|
return isFullScreenAudioPlayer && isAudioItem ? (
|
|
1026
1077
|
<View style={containerStyle}>
|
|
1027
|
-
{!castAction?.state?.connected && (
|
|
1078
|
+
{(!castAction?.state?.connected || supportNativeCast) && (
|
|
1028
1079
|
<this.props.PlayerComponent
|
|
1029
1080
|
ref={this._assignRoot}
|
|
1030
1081
|
{...nativeEvents}
|
|
1031
1082
|
{...nativeProps}
|
|
1032
1083
|
/>
|
|
1033
1084
|
)}
|
|
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>
|
|
1085
|
+
<AudioPlayerWrapper {...sharedWrapperViewProps} />
|
|
1050
1086
|
</View>
|
|
1051
1087
|
) : (
|
|
1052
1088
|
<PlayerWrapper {...sharedWrapperViewProps}>
|
|
@@ -1061,11 +1097,24 @@ export default class VideoPlayer extends React.Component<
|
|
|
1061
1097
|
<View style={styles.container}>
|
|
1062
1098
|
<View style={[playerContainerStyles, playerDimensions]}>
|
|
1063
1099
|
{isAudioItem && (
|
|
1064
|
-
<
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1100
|
+
<AnimationComponent
|
|
1101
|
+
animationType={ComponentAnimationType.player}
|
|
1102
|
+
additionalData={{
|
|
1103
|
+
...playerDimensions,
|
|
1104
|
+
inlineAudioPlayer: true,
|
|
1105
|
+
}}
|
|
1106
|
+
style={getStyle(playerDimensions)}
|
|
1107
|
+
>
|
|
1108
|
+
<AudioPlayer
|
|
1109
|
+
style={
|
|
1110
|
+
isTV()
|
|
1111
|
+
? getStyle(playerDimensions)
|
|
1112
|
+
: styles.playerSize
|
|
1113
|
+
}
|
|
1114
|
+
audio_item={entry}
|
|
1115
|
+
plugin_configuration={this.getPluginConfiguration()}
|
|
1116
|
+
/>
|
|
1117
|
+
</AnimationComponent>
|
|
1069
1118
|
)}
|
|
1070
1119
|
|
|
1071
1120
|
{shouldRenderBackground && (
|
|
@@ -1077,17 +1126,28 @@ export default class VideoPlayer extends React.Component<
|
|
|
1077
1126
|
/>
|
|
1078
1127
|
)}
|
|
1079
1128
|
|
|
1080
|
-
{!castAction?.state?.connected && (
|
|
1081
|
-
<
|
|
1082
|
-
|
|
1083
|
-
{
|
|
1084
|
-
{...nativeProps}
|
|
1085
|
-
listener={this.props.listener}
|
|
1129
|
+
{(!castAction?.state?.connected || supportNativeCast) && (
|
|
1130
|
+
<AnimationComponent
|
|
1131
|
+
animationType={ComponentAnimationType.player}
|
|
1132
|
+
additionalData={playerDimensions}
|
|
1086
1133
|
style={getStyle(playerDimensions)}
|
|
1087
|
-
pluginConfiguration={this.getPluginConfiguration()}
|
|
1088
1134
|
>
|
|
1089
|
-
|
|
1090
|
-
|
|
1135
|
+
<this.props.PlayerComponent
|
|
1136
|
+
ref={this._assignRoot}
|
|
1137
|
+
{...nativeEvents}
|
|
1138
|
+
{...nativeProps}
|
|
1139
|
+
listener={this.props.listener}
|
|
1140
|
+
style={
|
|
1141
|
+
isTV()
|
|
1142
|
+
? getStyle(playerDimensions)
|
|
1143
|
+
: styles.playerSize
|
|
1144
|
+
}
|
|
1145
|
+
pluginConfiguration={this.getPluginConfiguration()}
|
|
1146
|
+
controller={this.props.controller}
|
|
1147
|
+
>
|
|
1148
|
+
{this.childrenWithPlayNext()}
|
|
1149
|
+
</this.props.PlayerComponent>
|
|
1150
|
+
</AnimationComponent>
|
|
1091
1151
|
)}
|
|
1092
1152
|
</View>
|
|
1093
1153
|
|
|
@@ -1121,6 +1181,7 @@ export default class VideoPlayer extends React.Component<
|
|
|
1121
1181
|
listener={this.props.listener}
|
|
1122
1182
|
style={this.takeParentStyle}
|
|
1123
1183
|
pluginConfiguration={this.getPluginConfiguration()}
|
|
1184
|
+
controller={this.props.controller}
|
|
1124
1185
|
>
|
|
1125
1186
|
{this.childrenWithPlayNext()}
|
|
1126
1187
|
</this.props.PlayerComponent>
|