@applicaster/quick-brick-player 15.0.0-rc.13 → 15.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.
- package/package.json +6 -6
- package/src/Player/AudioLayer/AudioPlayerWrapper.tsx +20 -8
- package/src/Player/AudioLayer/Layout/DockedControls/index.tsx +78 -65
- package/src/Player/AudioLayer/Layout/MobileLayout.tsx +1 -6
- package/src/Player/AudioLayer/Layout/PlayerImage/index.tsx +27 -25
- package/src/Player/AudioLayer/Layout/PlayerImage/styles.ts +6 -1
- package/src/Player/AudioLayer/Layout/TabletLandscapeLayout.tsx +5 -8
- package/src/Player/AudioLayer/Layout/TabletPortraitLayout.tsx +1 -6
- package/src/Player/AudioLayer/utils.ts +1 -27
- package/src/Player/PlayNextOverlay/index.tsx +2 -2
- package/src/Player/PlayerModal/PlayerModal.tsx +16 -15
- package/src/Player/PlayerModal/VideoPlayerModal.tsx +138 -120
- package/src/Player/PlayerModal/consts/index.ts +2 -19
- package/src/Player/PlayerModal/hooks/index.ts +115 -139
- package/src/Player/PlayerModal/styles.ts +5 -0
- package/src/Player/PlayerModal/utils/index.ts +111 -0
- package/src/Player/PlayerView/types.ts +1 -2
- package/src/Player/Utils/index.tsx +9 -9
- package/src/Player/hooks/progressStates/__tests__/utils.test.ts +23 -0
- package/src/Player/hooks/progressStates/useLiveProgressState.tsx +78 -0
- package/src/Player/hooks/progressStates/useProgressState.tsx +30 -0
- package/src/Player/hooks/progressStates/useVodProgressState.tsx +115 -0
- package/src/Player/hooks/progressStates/utils.ts +33 -0
- package/src/Player/index.tsx +586 -354
- package/src/utils/dimensions.ts +29 -0
- package/src/utils/index.ts +12 -0
- package/src/utils/logger.ts +6 -0
- package/src/utils/playerHelpers.ts +11 -0
- package/src/utils/playerStyles.ts +50 -0
- package/src/Player/AudioLayer/Layout/PlayerImage/AnimatedImage.tsx +0 -82
- package/src/Player/AudioLayer/Layout/PlayerImage/hooks/index.ts +0 -1
- package/src/Player/AudioLayer/Layout/PlayerImage/hooks/useChangePlayerState.ts +0 -99
package/src/Player/index.tsx
CHANGED
|
@@ -5,10 +5,14 @@
|
|
|
5
5
|
import React from "react";
|
|
6
6
|
import * as R from "ramda";
|
|
7
7
|
|
|
8
|
-
import { findNodeHandle, StyleSheet, View,
|
|
8
|
+
import { findNodeHandle, StyleSheet, View, ViewStyle } from "react-native";
|
|
9
9
|
|
|
10
|
-
import TransportControlsMobile
|
|
11
|
-
|
|
10
|
+
import TransportControlsMobile, {
|
|
11
|
+
ErrorOverlay,
|
|
12
|
+
} from "@applicaster/quick-brick-mobile-transport-controls";
|
|
13
|
+
import TransportControlsTV, {
|
|
14
|
+
ErrorOverlay as TVErrorOverlay,
|
|
15
|
+
} from "@applicaster/quick-brick-tv-transport-controls";
|
|
12
16
|
|
|
13
17
|
import { AudioPlayer } from "@applicaster/zapp-react-native-ui-components/Components/AudioPlayer";
|
|
14
18
|
import {
|
|
@@ -28,9 +32,9 @@ import { PlayNextOverlay } from "./PlayNextOverlay";
|
|
|
28
32
|
import { PlayerImageBackground } from "@applicaster/zapp-react-native-ui-components/Components/PlayerImageBackground";
|
|
29
33
|
|
|
30
34
|
import { GENERAL_EVENT } from "@applicaster/zapp-react-native-utils/analyticsUtils/events";
|
|
31
|
-
import { Categories, createLogger, Subsystem } from "../logger";
|
|
32
35
|
import { parseLanguageTracks } from "@applicaster/zapp-react-native-utils/playerUtils/configurationUtils";
|
|
33
36
|
import { DEFAULT_COLORS, SEEK_TIME } from "../utils/const";
|
|
37
|
+
import { logger, getScreenAspectRatio } from "../utils";
|
|
34
38
|
import { AudioPlayerWrapper } from "./AudioLayer/AudioPlayerWrapper";
|
|
35
39
|
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
|
|
36
40
|
import { getAllAccessibilityProps } from "@applicaster/zapp-react-native-utils/configurationUtils";
|
|
@@ -52,6 +56,8 @@ import { DockedControls } from "./AudioLayer/Layout/DockedControls";
|
|
|
52
56
|
import { FlexImage } from "./AudioLayer/Layout/PlayerImage/FlexImage";
|
|
53
57
|
import { PlayerError } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/conts";
|
|
54
58
|
|
|
59
|
+
const isTvOS = isTvOSPlatform();
|
|
60
|
+
|
|
55
61
|
const styles = StyleSheet.create({
|
|
56
62
|
container: { flex: 1 },
|
|
57
63
|
playerContainerBlack: { backgroundColor: DEFAULT_COLORS.black },
|
|
@@ -65,25 +71,43 @@ const styles = StyleSheet.create({
|
|
|
65
71
|
flexImage: { height: "100%", aspectRatio: 1, flex: -1 },
|
|
66
72
|
});
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
74
|
+
type VideoPlayerProps = QuickBrickPlayer.PlayerProps & {
|
|
75
|
+
isCasting?: boolean;
|
|
76
|
+
playNextData?: PlayNextData;
|
|
77
|
+
castAction?: {
|
|
78
|
+
state?: {
|
|
79
|
+
connected?: boolean;
|
|
80
|
+
friendlyStatus?: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
openPiP?: () => void;
|
|
84
|
+
closePiP?: () => void;
|
|
85
|
+
playerEvent?: (eventName: string, eventData?: any) => void;
|
|
86
|
+
mode?: string;
|
|
87
|
+
updatePlayerState?: (state: string) => void;
|
|
88
|
+
setNextVideoPreloadThresholdPercentage?: (percentage: number) => void;
|
|
89
|
+
hideTransportControls?: boolean;
|
|
90
|
+
playableItem?: any;
|
|
91
|
+
playerPluginIdentifier?: string;
|
|
92
|
+
controller?: {
|
|
93
|
+
supportNativeCast?: () => boolean;
|
|
94
|
+
supportsNativeControls?: () => boolean;
|
|
95
|
+
};
|
|
96
|
+
children?: React.ReactNode;
|
|
82
97
|
};
|
|
83
98
|
|
|
84
99
|
export default class VideoPlayer extends React.Component<
|
|
85
|
-
|
|
86
|
-
QuickBrickPlayer.NativePlayerState
|
|
100
|
+
VideoPlayerProps,
|
|
101
|
+
QuickBrickPlayer.NativePlayerState & {
|
|
102
|
+
isCastConnected?: boolean;
|
|
103
|
+
audioTrackId: string | null;
|
|
104
|
+
textTrackId: string | null;
|
|
105
|
+
keyEvent?: any;
|
|
106
|
+
isLive?: boolean;
|
|
107
|
+
seekableDuration?: number;
|
|
108
|
+
displayOverlay?: boolean;
|
|
109
|
+
error: PlayerError | null;
|
|
110
|
+
}
|
|
87
111
|
> {
|
|
88
112
|
public static propTypes = {};
|
|
89
113
|
_root: any;
|
|
@@ -94,7 +118,27 @@ export default class VideoPlayer extends React.Component<
|
|
|
94
118
|
private onVideoLoadCalled: boolean;
|
|
95
119
|
playNextData: PlayNextData;
|
|
96
120
|
|
|
97
|
-
state: QuickBrickPlayer.NativePlayerState
|
|
121
|
+
state: QuickBrickPlayer.NativePlayerState & {
|
|
122
|
+
isCastConnected?: boolean;
|
|
123
|
+
audioTrackId: string | null;
|
|
124
|
+
textTrackId: string | null;
|
|
125
|
+
keyEvent?: any;
|
|
126
|
+
isLive?: boolean;
|
|
127
|
+
seekableDuration?: number;
|
|
128
|
+
displayOverlay?: boolean;
|
|
129
|
+
error: PlayerError | null;
|
|
130
|
+
} = {
|
|
131
|
+
// Base required properties from NativePlayerState
|
|
132
|
+
buffering: false,
|
|
133
|
+
docked: false,
|
|
134
|
+
fullscreen: false,
|
|
135
|
+
inline: false,
|
|
136
|
+
isModal: false,
|
|
137
|
+
isTabletPortrait: false,
|
|
138
|
+
muted: false,
|
|
139
|
+
showPoster: false,
|
|
140
|
+
error: null,
|
|
141
|
+
// Extended properties
|
|
98
142
|
audioTrackId: null,
|
|
99
143
|
textTrackId: null,
|
|
100
144
|
isCasting: this.props.isCasting,
|
|
@@ -140,6 +184,8 @@ export default class VideoPlayer extends React.Component<
|
|
|
140
184
|
: { flexBasis: "auto", flexGrow: 1, flexShrink: 1 };
|
|
141
185
|
|
|
142
186
|
this.playerPluginId = this.props?.playerPluginIdentifier;
|
|
187
|
+
|
|
188
|
+
this.renderPlayerContent = this.renderPlayerContent.bind(this);
|
|
143
189
|
}
|
|
144
190
|
|
|
145
191
|
componentWillUnmount() {
|
|
@@ -422,6 +468,8 @@ export default class VideoPlayer extends React.Component<
|
|
|
422
468
|
|
|
423
469
|
const newError = new PlayerError(error, description);
|
|
424
470
|
|
|
471
|
+
this.setState({ error: newError });
|
|
472
|
+
|
|
425
473
|
return this.props?.listener?.onError(newError);
|
|
426
474
|
};
|
|
427
475
|
|
|
@@ -708,163 +756,233 @@ export default class VideoPlayer extends React.Component<
|
|
|
708
756
|
return this.props.controller.supportNativeCast();
|
|
709
757
|
}
|
|
710
758
|
|
|
711
|
-
|
|
712
|
-
const {
|
|
713
|
-
|
|
714
|
-
entry,
|
|
715
|
-
fullscreen,
|
|
716
|
-
hideTransportControls,
|
|
717
|
-
inline,
|
|
718
|
-
isModal,
|
|
719
|
-
isTabletPortrait,
|
|
720
|
-
muted,
|
|
721
|
-
style,
|
|
722
|
-
castAction,
|
|
723
|
-
startComponentsAnimation,
|
|
724
|
-
} = this.props;
|
|
725
|
-
|
|
726
|
-
const { audioTrackId, keyEvent, paused, seek, textTrackId, rate } =
|
|
727
|
-
this.state;
|
|
759
|
+
renderPlayerContent(playerDimensions: ViewStyle) {
|
|
760
|
+
const { entry, docked, fullscreen } = this.props;
|
|
761
|
+
const { isAd, piped } = this.state;
|
|
728
762
|
|
|
763
|
+
const pluginConfiguration = this.getPluginConfiguration();
|
|
729
764
|
const isAudioItem = isAudioItemUtil(entry);
|
|
730
765
|
|
|
731
|
-
const
|
|
732
|
-
const generalStyles = isAudioItem ? styles.audio : styles.video;
|
|
766
|
+
const backgroundImageKey = pluginConfiguration?.player_preview_image_key;
|
|
733
767
|
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
768
|
+
const shouldRenderBackground =
|
|
769
|
+
!R.isNil(backgroundImageKey) &&
|
|
770
|
+
backgroundImageKey.length > 0 &&
|
|
771
|
+
!this.onVideoLoadCalled &&
|
|
772
|
+
!isAd;
|
|
737
773
|
|
|
738
|
-
|
|
739
|
-
|
|
774
|
+
const shouldRenderNativePlayer =
|
|
775
|
+
!this.props.isCasting || this.supportNativeCast;
|
|
740
776
|
|
|
741
|
-
const
|
|
742
|
-
Object.assign(
|
|
743
|
-
{},
|
|
744
|
-
isAudioItem ? styles.audio : { position: "absolute" },
|
|
745
|
-
dimensions
|
|
746
|
-
);
|
|
777
|
+
const playerContainerStyles = this.getPlayerContainerStyles(isAudioItem);
|
|
747
778
|
|
|
748
|
-
const
|
|
779
|
+
const backgroundImageStyle = this.getBackgroundImageStyle(
|
|
780
|
+
playerDimensions,
|
|
781
|
+
isAudioItem
|
|
782
|
+
);
|
|
749
783
|
|
|
750
|
-
const
|
|
751
|
-
|
|
784
|
+
const playerViewStyle = this.getPlayerViewStyle(
|
|
785
|
+
playerDimensions,
|
|
786
|
+
isAudioItem
|
|
787
|
+
);
|
|
752
788
|
|
|
753
|
-
const
|
|
754
|
-
|
|
789
|
+
const nativeEvents = this.getNativeEvents();
|
|
790
|
+
const nativeProps = this.getNativeProps();
|
|
755
791
|
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
792
|
+
const renderedNativePlayer = this.renderNativePlayer(
|
|
793
|
+
shouldRenderNativePlayer,
|
|
794
|
+
playerViewStyle,
|
|
795
|
+
nativeEvents,
|
|
796
|
+
nativeProps,
|
|
797
|
+
pluginConfiguration
|
|
798
|
+
);
|
|
759
799
|
|
|
760
|
-
const
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
800
|
+
const renderedBackgroundImage = this.renderBackgroundImage(
|
|
801
|
+
shouldRenderBackground,
|
|
802
|
+
backgroundImageKey,
|
|
803
|
+
entry,
|
|
804
|
+
backgroundImageStyle
|
|
805
|
+
);
|
|
765
806
|
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
807
|
+
const renderedAudioPlayer = this.renderAudioPlayer(
|
|
808
|
+
isAudioItem,
|
|
809
|
+
entry,
|
|
810
|
+
pluginConfiguration
|
|
811
|
+
);
|
|
769
812
|
|
|
770
|
-
|
|
771
|
-
|
|
813
|
+
const renderedTransportControls =
|
|
814
|
+
this.renderTransportControls(playerDimensions);
|
|
772
815
|
|
|
773
|
-
const
|
|
816
|
+
const renderedPlayNextOverlay = this.renderPlayNextOverlay(
|
|
817
|
+
piped,
|
|
818
|
+
entry,
|
|
819
|
+
docked,
|
|
820
|
+
pluginConfiguration
|
|
821
|
+
);
|
|
774
822
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
823
|
+
if (this.state.error) {
|
|
824
|
+
return (
|
|
825
|
+
<View style={styles.container}>
|
|
826
|
+
<ErrorOverlay
|
|
827
|
+
error={this.state.error}
|
|
828
|
+
onClose={() => playerManager.close()}
|
|
829
|
+
configuration={pluginConfiguration}
|
|
830
|
+
docked={docked}
|
|
831
|
+
fullscreen={fullscreen}
|
|
832
|
+
/>
|
|
833
|
+
</View>
|
|
834
|
+
);
|
|
835
|
+
}
|
|
780
836
|
|
|
781
|
-
|
|
782
|
-
|
|
837
|
+
return (
|
|
838
|
+
<View style={styles.container}>
|
|
839
|
+
<View style={[playerContainerStyles, playerDimensions]}>
|
|
840
|
+
{renderedAudioPlayer}
|
|
841
|
+
{renderedBackgroundImage}
|
|
842
|
+
{renderedNativePlayer}
|
|
843
|
+
</View>
|
|
783
844
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
845
|
+
{renderedTransportControls}
|
|
846
|
+
{renderedPlayNextOverlay}
|
|
847
|
+
</View>
|
|
848
|
+
);
|
|
849
|
+
}
|
|
787
850
|
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
851
|
+
/* Returns player container style based on platform and content type (audio/video) */
|
|
852
|
+
private getPlayerContainerStyles = (isAudioItem: boolean) =>
|
|
853
|
+
isApplePlatform()
|
|
854
|
+
? styles.playerContainerBlack
|
|
855
|
+
: isTV() && isAudioItem
|
|
856
|
+
? styles.playerContainerTransparent
|
|
857
|
+
: styles.playerContainerBlack;
|
|
793
858
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
859
|
+
private getBackgroundImageStyle = (
|
|
860
|
+
dimensions: ViewStyle,
|
|
861
|
+
isAudioItem: boolean
|
|
862
|
+
): ViewStyle[] => [
|
|
863
|
+
isAudioItem ? styles.audio : { position: "absolute" },
|
|
864
|
+
dimensions,
|
|
865
|
+
];
|
|
866
|
+
|
|
867
|
+
/* Returns player view style based on platform and content type (audio/video) */
|
|
868
|
+
private getPlayerViewStyle = (
|
|
869
|
+
dimensions: ViewStyle,
|
|
870
|
+
isAudioItem: boolean
|
|
871
|
+
): ViewStyle | ViewStyle[] => {
|
|
872
|
+
const generalStyles = isAudioItem ? styles.audio : undefined;
|
|
873
|
+
|
|
874
|
+
if (isAndroidPlatform() && isAudioItem) {
|
|
875
|
+
return generalStyles;
|
|
876
|
+
}
|
|
798
877
|
|
|
799
|
-
|
|
800
|
-
|
|
878
|
+
return [generalStyles, dimensions];
|
|
879
|
+
};
|
|
801
880
|
|
|
802
|
-
|
|
881
|
+
private renderAudioPlayer = (
|
|
882
|
+
isAudioItem: boolean,
|
|
883
|
+
entry: ZappEntry,
|
|
884
|
+
pluginConfiguration: Record<string, any>
|
|
885
|
+
) => {
|
|
886
|
+
if (!isAudioItem) return null;
|
|
887
|
+
|
|
888
|
+
return (
|
|
889
|
+
<AudioPlayer
|
|
890
|
+
style={styles.playerSize}
|
|
891
|
+
audio_item={entry}
|
|
892
|
+
plugin_configuration={pluginConfiguration}
|
|
893
|
+
/>
|
|
894
|
+
);
|
|
895
|
+
};
|
|
803
896
|
|
|
804
|
-
|
|
805
|
-
|
|
897
|
+
private renderBackgroundImage = (
|
|
898
|
+
shouldRender: boolean,
|
|
899
|
+
imageKey: string,
|
|
900
|
+
entry: ZappEntry,
|
|
901
|
+
style: ViewStyle | ViewStyle[]
|
|
902
|
+
) => {
|
|
903
|
+
if (!shouldRender) return null;
|
|
806
904
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
docked,
|
|
812
|
-
enableAutoAudioTrackSelection,
|
|
813
|
-
fullscreen, // TODO: Check fullscreen params not crash
|
|
814
|
-
inline,
|
|
815
|
-
muted,
|
|
816
|
-
nowPlayingEnabled,
|
|
817
|
-
paused,
|
|
818
|
-
seek,
|
|
819
|
-
textTrackId,
|
|
820
|
-
liveSeekingEnabled,
|
|
821
|
-
liveCatchUpEnabled,
|
|
822
|
-
playerId: this.props.playerId,
|
|
823
|
-
pictureInPictureEnabled,
|
|
824
|
-
seekStep:
|
|
825
|
-
(this.props.pluginConfiguration?.seek_duration || SEEK_TIME) * 1000, // Only for Android
|
|
826
|
-
accessibilityProps: getAllAccessibilityProps(
|
|
827
|
-
this.getPluginConfiguration()
|
|
828
|
-
),
|
|
829
|
-
};
|
|
905
|
+
return (
|
|
906
|
+
<PlayerImageBackground imageKey={imageKey} entry={entry} style={style} />
|
|
907
|
+
);
|
|
908
|
+
};
|
|
830
909
|
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
910
|
+
private renderNativePlayer = (
|
|
911
|
+
shouldRender: boolean,
|
|
912
|
+
style: ViewStyle | ViewStyle[],
|
|
913
|
+
nativeEvents: ReturnType<typeof this.getNativeEvents>,
|
|
914
|
+
nativeProps: ReturnType<typeof this.getNativeProps>,
|
|
915
|
+
pluginConfiguration: Record<string, any>
|
|
916
|
+
) => {
|
|
917
|
+
if (!shouldRender) return null;
|
|
918
|
+
const PlayerComponent = this.props.PlayerComponent;
|
|
919
|
+
|
|
920
|
+
return (
|
|
921
|
+
<View style={style}>
|
|
922
|
+
<PlayerComponent
|
|
923
|
+
ref={this._assignRoot}
|
|
924
|
+
{...nativeEvents}
|
|
925
|
+
{...nativeProps}
|
|
926
|
+
listener={this.props.listener}
|
|
927
|
+
style={styles.playerSize}
|
|
928
|
+
pluginConfiguration={pluginConfiguration}
|
|
929
|
+
controller={this.props.controller}
|
|
930
|
+
>
|
|
931
|
+
{this.props.children}
|
|
932
|
+
</PlayerComponent>
|
|
933
|
+
</View>
|
|
934
|
+
);
|
|
935
|
+
};
|
|
837
936
|
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
937
|
+
private renderPlayNextOverlay = (
|
|
938
|
+
piped: boolean,
|
|
939
|
+
entry: ZappEntry,
|
|
940
|
+
docked: boolean,
|
|
941
|
+
pluginConfiguration: Record<string, any>
|
|
942
|
+
) => {
|
|
943
|
+
if (piped) return null;
|
|
944
|
+
|
|
945
|
+
return (
|
|
946
|
+
<PlayNextOverlay
|
|
947
|
+
item={entry}
|
|
948
|
+
playerIsDocked={docked}
|
|
949
|
+
pluginConfiguration={pluginConfiguration}
|
|
950
|
+
playerId={this.props.playerId}
|
|
951
|
+
playNextData={this.getPlayNextData()}
|
|
952
|
+
setNextVideoPreloadThresholdPercentage={
|
|
953
|
+
this.props.setNextVideoPreloadThresholdPercentage
|
|
954
|
+
}
|
|
955
|
+
/>
|
|
956
|
+
);
|
|
957
|
+
};
|
|
958
|
+
|
|
959
|
+
// Extract native events to a separate method for reusability
|
|
960
|
+
getNativeEvents = () => {
|
|
961
|
+
const { keyEvent } = this.state;
|
|
844
962
|
|
|
845
963
|
const adEvents = {
|
|
846
|
-
onAdBegin: this.onAdBegin,
|
|
847
|
-
onAdBreakBegin: this.onAdBreakBegin,
|
|
848
|
-
onAdBreakEnd: this.onAdBreakEnd,
|
|
849
|
-
onAdEnd: this.onAdEnd,
|
|
850
|
-
onAdError: this.onAdError,
|
|
851
|
-
onAdRequest: this.onAdRequest,
|
|
852
|
-
onAdClicked: this.onAdClicked,
|
|
853
|
-
onAdTapped: this.onAdTapped,
|
|
964
|
+
onAdBegin: this.onAdBegin,
|
|
965
|
+
onAdBreakBegin: this.onAdBreakBegin,
|
|
966
|
+
onAdBreakEnd: this.onAdBreakEnd,
|
|
967
|
+
onAdEnd: this.onAdEnd,
|
|
968
|
+
onAdError: this.onAdError,
|
|
969
|
+
onAdRequest: this.onAdRequest,
|
|
970
|
+
onAdClicked: this.onAdClicked,
|
|
971
|
+
onAdTapped: this.onAdTapped,
|
|
854
972
|
};
|
|
855
973
|
|
|
856
974
|
const playbackEvents = {
|
|
857
975
|
onPlaybackRateChange: this.onPlaybackRateChange,
|
|
858
|
-
onPlayerPause: this.onPlayerPause,
|
|
859
|
-
onPlayerResume: this.onPlayerResume,
|
|
860
|
-
onPlayerSeekComplete: this.onPlayerSeekComplete,
|
|
861
|
-
onPlayerSeekStart: this.onPlayerSeekStart,
|
|
976
|
+
onPlayerPause: this.onPlayerPause,
|
|
977
|
+
onPlayerResume: this.onPlayerResume,
|
|
978
|
+
onPlayerSeekComplete: this.onPlayerSeekComplete,
|
|
979
|
+
onPlayerSeekStart: this.onPlayerSeekStart,
|
|
862
980
|
};
|
|
863
981
|
|
|
864
982
|
const lifecycleEvents = {
|
|
865
983
|
onReadyForDisplay: this.unHandledEvent("onReadyForDisplay"),
|
|
866
|
-
onVideoEnd: this.onVideoEnd,
|
|
867
|
-
onVideoError: this.onVideoError,
|
|
984
|
+
onVideoEnd: this.onVideoEnd,
|
|
985
|
+
onVideoError: this.onVideoError,
|
|
868
986
|
onVideoProgress: this.onVideoProgress,
|
|
869
987
|
onVideoFullscreenPlayerDidDismiss: this.onVideoFullscreenPlayerDidDismiss,
|
|
870
988
|
onVideoFullscreenPlayerDidPresent: this.onVideoFullscreenPlayerDidPresent,
|
|
@@ -908,11 +1026,11 @@ export default class VideoPlayer extends React.Component<
|
|
|
908
1026
|
};
|
|
909
1027
|
|
|
910
1028
|
const unsupportedEvents = {
|
|
911
|
-
onBufferComplete: this.onBufferComplete,
|
|
912
|
-
onBufferStart: this.onBufferStart,
|
|
1029
|
+
onBufferComplete: this.onBufferComplete,
|
|
1030
|
+
onBufferStart: this.onBufferStart,
|
|
913
1031
|
};
|
|
914
1032
|
|
|
915
|
-
|
|
1033
|
+
return {
|
|
916
1034
|
...adEvents,
|
|
917
1035
|
...androidPlayerEvents,
|
|
918
1036
|
...lifecycleEvents,
|
|
@@ -921,60 +1039,199 @@ export default class VideoPlayer extends React.Component<
|
|
|
921
1039
|
...unsupportedEvents,
|
|
922
1040
|
...playbackEvents,
|
|
923
1041
|
...androidLifecyclePiPEvents,
|
|
1042
|
+
} as const;
|
|
1043
|
+
};
|
|
1044
|
+
|
|
1045
|
+
// Extract native props to a separate method for reusability
|
|
1046
|
+
getNativeProps = () => {
|
|
1047
|
+
const { entry, docked, fullscreen, inline, muted, castAction } = this.props;
|
|
1048
|
+
const { audioTrackId, textTrackId, paused, seek, rate } = this.state;
|
|
1049
|
+
|
|
1050
|
+
const nativeResizeMode = "ScaleAspectFit";
|
|
1051
|
+
|
|
1052
|
+
const isFullScreenAudioPlayer =
|
|
1053
|
+
this.getPluginConfiguration()?.full_screen_audio_player || false;
|
|
1054
|
+
|
|
1055
|
+
const isAudioItem = isAudioItemUtil(entry);
|
|
1056
|
+
const isAudioPlayer = isFullScreenAudioPlayer && isAudioItem;
|
|
1057
|
+
|
|
1058
|
+
let platformSpecificProps: Record<string, any> = isApplePlatform()
|
|
1059
|
+
? { resizeMode: nativeResizeMode }
|
|
1060
|
+
: {};
|
|
1061
|
+
|
|
1062
|
+
const supportsNativeControls =
|
|
1063
|
+
!!this.props.controller?.supportsNativeControls?.();
|
|
1064
|
+
|
|
1065
|
+
const controls = isTvOS
|
|
1066
|
+
? (supportsNativeControls && !this.isInlineTV()) ||
|
|
1067
|
+
!!this.getPlayNextData()
|
|
1068
|
+
: supportsNativeControls && !this.getPlayNextData();
|
|
1069
|
+
|
|
1070
|
+
const shouldUseNativeControls =
|
|
1071
|
+
controls && !docked && !castAction?.state?.connected;
|
|
1072
|
+
|
|
1073
|
+
platformSpecificProps = {
|
|
1074
|
+
...platformSpecificProps,
|
|
1075
|
+
controls: shouldUseNativeControls,
|
|
924
1076
|
};
|
|
925
1077
|
|
|
1078
|
+
const pictureInPictureEnabled =
|
|
1079
|
+
this.props.pluginConfiguration?.pictureInPictureEnabled && !isAudioPlayer;
|
|
1080
|
+
|
|
1081
|
+
const nowPlayingEnabled =
|
|
1082
|
+
this.props?.pluginConfiguration?.nowPlayingEnabled;
|
|
1083
|
+
|
|
1084
|
+
const enableAutoAudioTrackSelection =
|
|
1085
|
+
this.props.pluginConfiguration?.enable_auto_audio_track_selection;
|
|
1086
|
+
|
|
1087
|
+
const minimumAllowedSeekableDurationInSeconds =
|
|
1088
|
+
this.props?.pluginConfiguration?.minimumAllowedSeekableDurationInSeconds;
|
|
1089
|
+
|
|
1090
|
+
const liveSeekingEnabled =
|
|
1091
|
+
(this.props.pluginConfiguration?.liveSeekingEnabled &&
|
|
1092
|
+
this.state?.seekableDuration >
|
|
1093
|
+
minimumAllowedSeekableDurationInSeconds) ||
|
|
1094
|
+
false;
|
|
1095
|
+
|
|
1096
|
+
const liveCatchUpEnabled =
|
|
1097
|
+
this.props.pluginConfiguration?.liveCatchUpEnabled;
|
|
1098
|
+
|
|
1099
|
+
const nativeProps = {
|
|
1100
|
+
rate: undefined,
|
|
1101
|
+
entry,
|
|
1102
|
+
...platformSpecificProps,
|
|
1103
|
+
audioTrackId,
|
|
1104
|
+
docked,
|
|
1105
|
+
enableAutoAudioTrackSelection,
|
|
1106
|
+
fullscreen,
|
|
1107
|
+
inline,
|
|
1108
|
+
muted,
|
|
1109
|
+
nowPlayingEnabled,
|
|
1110
|
+
paused,
|
|
1111
|
+
seek,
|
|
1112
|
+
textTrackId,
|
|
1113
|
+
liveSeekingEnabled,
|
|
1114
|
+
liveCatchUpEnabled,
|
|
1115
|
+
playerId: this.props.playerId,
|
|
1116
|
+
pictureInPictureEnabled,
|
|
1117
|
+
seekStep:
|
|
1118
|
+
(this.props.pluginConfiguration?.seek_duration || SEEK_TIME) * 1000,
|
|
1119
|
+
accessibilityProps: getAllAccessibilityProps(
|
|
1120
|
+
this.getPluginConfiguration()
|
|
1121
|
+
),
|
|
1122
|
+
};
|
|
1123
|
+
|
|
1124
|
+
if (!isTvOS) {
|
|
1125
|
+
nativeProps.rate = rate;
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
if (
|
|
1129
|
+
this.isReactNativeMethodsSupported() &&
|
|
1130
|
+
RNPlayerManager?.[this.playerPluginId]?.play
|
|
1131
|
+
) {
|
|
1132
|
+
delete nativeProps.paused;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
return nativeProps;
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
// Extract transport controls rendering to a separate method
|
|
1139
|
+
renderTransportControls = (playerDimensions) => {
|
|
1140
|
+
const {
|
|
1141
|
+
hideTransportControls,
|
|
1142
|
+
castAction,
|
|
1143
|
+
docked,
|
|
1144
|
+
fullscreen,
|
|
1145
|
+
isModal,
|
|
1146
|
+
entry,
|
|
1147
|
+
} = this.props;
|
|
1148
|
+
|
|
926
1149
|
const needToShowPlayNextOverlay =
|
|
927
1150
|
isTV() && this.getPlayNextData() && !docked;
|
|
928
1151
|
|
|
1152
|
+
const needsToRender =
|
|
1153
|
+
!hideTransportControls &&
|
|
1154
|
+
!needToShowPlayNextOverlay &&
|
|
1155
|
+
this.props.mode !== "PIP" &&
|
|
1156
|
+
!docked;
|
|
1157
|
+
|
|
1158
|
+
const supportsNativeControls =
|
|
1159
|
+
!!this.props.controller?.supportsNativeControls?.();
|
|
1160
|
+
|
|
1161
|
+
const controls = isTvOS
|
|
1162
|
+
? (supportsNativeControls && !this.isInlineTV()) ||
|
|
1163
|
+
!!this.getPlayNextData()
|
|
1164
|
+
: supportsNativeControls && !this.getPlayNextData();
|
|
1165
|
+
|
|
1166
|
+
const shouldUseNativeControls =
|
|
1167
|
+
controls && !docked && !castAction?.state?.connected;
|
|
1168
|
+
|
|
1169
|
+
if (shouldUseNativeControls) {
|
|
1170
|
+
return null;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
const TransportControls = isTV()
|
|
1174
|
+
? TransportControlsTV
|
|
1175
|
+
: TransportControlsMobile;
|
|
1176
|
+
|
|
929
1177
|
const needToShowDefaultControls = !(
|
|
930
1178
|
(controls && !castAction?.state?.connected) ||
|
|
931
1179
|
this.getPlayNextData()
|
|
932
1180
|
);
|
|
933
1181
|
|
|
934
|
-
const playerContainerStyles = isApplePlatform()
|
|
935
|
-
? styles.playerContainerBlack
|
|
936
|
-
: isTV() && isAudioItem
|
|
937
|
-
? styles.playerContainerTransparent
|
|
938
|
-
: styles.playerContainerBlack;
|
|
939
|
-
|
|
940
1182
|
const isInline = () => {
|
|
941
1183
|
if (isTV()) {
|
|
942
|
-
return inline;
|
|
1184
|
+
return this.props.inline;
|
|
943
1185
|
}
|
|
944
1186
|
|
|
945
|
-
|
|
946
|
-
return fullscreen ? false : inline;
|
|
1187
|
+
return fullscreen ? false : this.props.inline;
|
|
947
1188
|
};
|
|
948
1189
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1190
|
+
return needsToRender ? (
|
|
1191
|
+
<TransportControls
|
|
1192
|
+
playerContent={entry}
|
|
1193
|
+
configuration={this.getPluginConfiguration()}
|
|
1194
|
+
playerDimensions={playerDimensions}
|
|
1195
|
+
inline={isInline()}
|
|
1196
|
+
docked={fullscreen ? false : docked}
|
|
1197
|
+
isModal={isModal}
|
|
1198
|
+
extraInfoText={castAction?.state?.friendlyStatus}
|
|
1199
|
+
controlsAlwaysVisible={castAction?.state?.connected}
|
|
1200
|
+
playNextData={this.getPlayNextData()}
|
|
1201
|
+
needToShowDefaultControls={needToShowDefaultControls}
|
|
1202
|
+
/>
|
|
1203
|
+
) : null;
|
|
1204
|
+
};
|
|
954
1205
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
1206
|
+
// Helper method for inline TV check
|
|
1207
|
+
isInlineTV = () => {
|
|
1208
|
+
const screenData = getTargetScreenDataFromEntry(this.props.playableItem);
|
|
958
1209
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1210
|
+
return isInlineTVUtil(screenData);
|
|
1211
|
+
};
|
|
1212
|
+
|
|
1213
|
+
renderMobile = () => {
|
|
1214
|
+
const {
|
|
1215
|
+
docked,
|
|
1216
|
+
entry,
|
|
1217
|
+
fullscreen,
|
|
1218
|
+
inline,
|
|
1219
|
+
isModal,
|
|
1220
|
+
isTabletPortrait,
|
|
1221
|
+
style,
|
|
1222
|
+
isCasting,
|
|
1223
|
+
PlayerComponent,
|
|
1224
|
+
listener,
|
|
1225
|
+
} = this.props;
|
|
1226
|
+
|
|
1227
|
+
const { piped } = this.state;
|
|
1228
|
+
|
|
1229
|
+
const pluginConfiguration = this.getPluginConfiguration();
|
|
1230
|
+
|
|
1231
|
+
const isAudioItem = isAudioItemUtil(entry);
|
|
1232
|
+
|
|
1233
|
+
const isFullScreenAudioPlayer =
|
|
1234
|
+
pluginConfiguration?.full_screen_audio_player || false;
|
|
978
1235
|
|
|
979
1236
|
const sharedWrapperViewProps = {
|
|
980
1237
|
style,
|
|
@@ -982,199 +1239,174 @@ export default class VideoPlayer extends React.Component<
|
|
|
982
1239
|
inline,
|
|
983
1240
|
docked,
|
|
984
1241
|
isModal,
|
|
985
|
-
pip:
|
|
1242
|
+
pip: piped,
|
|
986
1243
|
layoutState: {
|
|
987
1244
|
inline,
|
|
988
1245
|
docked,
|
|
989
1246
|
isModal,
|
|
990
|
-
pip:
|
|
1247
|
+
pip: piped,
|
|
991
1248
|
},
|
|
992
|
-
configuration:
|
|
1249
|
+
configuration: pluginConfiguration,
|
|
993
1250
|
isTabletPortrait,
|
|
994
1251
|
playNextData: this.getPlayNextData(),
|
|
995
1252
|
};
|
|
996
1253
|
|
|
997
|
-
const
|
|
998
|
-
this.getPluginConfiguration()?.player_preview_image_key;
|
|
999
|
-
|
|
1000
|
-
const shouldRenderNativePlayer =
|
|
1001
|
-
!this.props.isCasting || this.supportNativeCast;
|
|
1254
|
+
const shouldRenderNativePlayer = !isCasting || this.supportNativeCast;
|
|
1002
1255
|
|
|
1003
1256
|
const aspectRatio =
|
|
1004
|
-
!inline && isModal && !
|
|
1005
|
-
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
/>
|
|
1034
|
-
</View>
|
|
1035
|
-
}
|
|
1036
|
-
/>
|
|
1037
|
-
) : (
|
|
1038
|
-
<VideoPlayerModal
|
|
1039
|
-
isTabletPortrait={isTabletPortrait}
|
|
1040
|
-
aspectRatio={aspectRatio}
|
|
1041
|
-
pip={this.state.piped}
|
|
1042
|
-
fullscreen={fullscreen}
|
|
1043
|
-
modal={isModal}
|
|
1044
|
-
style={{
|
|
1045
|
-
tabletLandscapeWidth: getTabletWidth(
|
|
1046
|
-
this.getPluginConfiguration().tablet_landscape_sidebar_width,
|
|
1047
|
-
style
|
|
1048
|
-
),
|
|
1049
|
-
width: style.width,
|
|
1050
|
-
height: style.height,
|
|
1051
|
-
}}
|
|
1052
|
-
content={
|
|
1053
|
-
<PlayerWrapper
|
|
1054
|
-
{...sharedWrapperViewProps}
|
|
1055
|
-
// eslint-disable-next-line react/no-unstable-nested-components
|
|
1056
|
-
playerContent={(playerDimensions) => {
|
|
1057
|
-
const shouldRenderBackground =
|
|
1058
|
-
!R.isNil(backgroundImageKey) &&
|
|
1059
|
-
backgroundImageKey.length > 0 &&
|
|
1060
|
-
!this.onVideoLoadCalled &&
|
|
1061
|
-
!this.state.isAd;
|
|
1062
|
-
|
|
1063
|
-
return (
|
|
1064
|
-
<View style={styles.container}>
|
|
1065
|
-
<View style={[playerContainerStyles, playerDimensions]}>
|
|
1066
|
-
{isAudioItem ? (
|
|
1067
|
-
<AudioPlayer
|
|
1068
|
-
style={styles.playerSize}
|
|
1069
|
-
audio_item={entry}
|
|
1070
|
-
plugin_configuration={this.getPluginConfiguration()}
|
|
1071
|
-
/>
|
|
1072
|
-
) : null}
|
|
1073
|
-
|
|
1074
|
-
{shouldRenderBackground ? (
|
|
1075
|
-
<PlayerImageBackground
|
|
1076
|
-
imageKey={backgroundImageKey}
|
|
1077
|
-
configuration={this.getPluginConfiguration()}
|
|
1078
|
-
entry={entry}
|
|
1079
|
-
style={getBackgroundImageStyle(playerDimensions)}
|
|
1080
|
-
/>
|
|
1081
|
-
) : null}
|
|
1082
|
-
|
|
1083
|
-
{shouldRenderNativePlayer ? (
|
|
1084
|
-
<View style={getStyle(playerDimensions)}>
|
|
1085
|
-
<this.props.PlayerComponent
|
|
1086
|
-
ref={this._assignRoot}
|
|
1087
|
-
{...nativeEvents}
|
|
1088
|
-
{...nativeProps}
|
|
1089
|
-
listener={this.props.listener}
|
|
1090
|
-
style={styles.playerSize}
|
|
1091
|
-
pluginConfiguration={this.getPluginConfiguration()}
|
|
1092
|
-
controller={this.props.controller}
|
|
1093
|
-
>
|
|
1094
|
-
{this.props.children}
|
|
1095
|
-
</this.props.PlayerComponent>
|
|
1096
|
-
</View>
|
|
1097
|
-
) : null}
|
|
1098
|
-
</View>
|
|
1099
|
-
|
|
1100
|
-
{renderTransportControls(playerDimensions)}
|
|
1101
|
-
{!this.state.piped && (
|
|
1102
|
-
<PlayNextOverlay
|
|
1103
|
-
item={entry}
|
|
1104
|
-
playerIsDocked={docked}
|
|
1105
|
-
pluginConfiguration={this.getPluginConfiguration()}
|
|
1106
|
-
playerId={this.props.playerId}
|
|
1107
|
-
playNextData={this.getPlayNextData()}
|
|
1108
|
-
setNextVideoPreloadThresholdPercentage={
|
|
1109
|
-
this.props.setNextVideoPreloadThresholdPercentage
|
|
1110
|
-
}
|
|
1111
|
-
/>
|
|
1112
|
-
)}
|
|
1113
|
-
</View>
|
|
1114
|
-
);
|
|
1115
|
-
}}
|
|
1257
|
+
!inline && isModal && !piped ? getScreenAspectRatio() : 16 / 9;
|
|
1258
|
+
|
|
1259
|
+
const audioPlayerProps = {
|
|
1260
|
+
ref: this._assignRoot,
|
|
1261
|
+
...this.getNativeEvents(),
|
|
1262
|
+
...this.getNativeProps(),
|
|
1263
|
+
};
|
|
1264
|
+
|
|
1265
|
+
return isFullScreenAudioPlayer && isAudioItem ? (
|
|
1266
|
+
// Ensure the View remains in the native hierarchy for proper rendering and interaction
|
|
1267
|
+
<PlayerModal
|
|
1268
|
+
content={
|
|
1269
|
+
<View collapsable={false} style={styles.container}>
|
|
1270
|
+
{shouldRenderNativePlayer ? (
|
|
1271
|
+
<PlayerComponent {...audioPlayerProps} listener={listener} />
|
|
1272
|
+
) : null}
|
|
1273
|
+
<AudioPlayerWrapper {...sharedWrapperViewProps} />
|
|
1274
|
+
</View>
|
|
1275
|
+
}
|
|
1276
|
+
collapsedContent={
|
|
1277
|
+
<View style={styles.container}>
|
|
1278
|
+
<DockedControls
|
|
1279
|
+
entry={entry}
|
|
1280
|
+
aspectRatio={1}
|
|
1281
|
+
layoutState={sharedWrapperViewProps.layoutState}
|
|
1282
|
+
playNextData={sharedWrapperViewProps.playNextData}
|
|
1283
|
+
ImageComponent={
|
|
1284
|
+
<FlexImage entry={entry} style={styles.flexImage} />
|
|
1285
|
+
}
|
|
1116
1286
|
/>
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1287
|
+
</View>
|
|
1288
|
+
}
|
|
1289
|
+
/>
|
|
1290
|
+
) : isModal ? (
|
|
1291
|
+
<VideoPlayerModal
|
|
1292
|
+
isTabletPortrait={isTabletPortrait}
|
|
1293
|
+
aspectRatio={aspectRatio}
|
|
1294
|
+
pip={piped}
|
|
1295
|
+
fullscreen={fullscreen}
|
|
1296
|
+
modal
|
|
1297
|
+
style={{
|
|
1298
|
+
tabletLandscapeWidth: getTabletWidth(
|
|
1299
|
+
this.getPluginConfiguration().tablet_landscape_sidebar_width,
|
|
1300
|
+
style
|
|
1301
|
+
),
|
|
1302
|
+
width: style.width,
|
|
1303
|
+
height: style.height,
|
|
1304
|
+
}}
|
|
1305
|
+
content={
|
|
1306
|
+
<PlayerWrapper
|
|
1307
|
+
{...sharedWrapperViewProps}
|
|
1308
|
+
playerContent={this.renderPlayerContent}
|
|
1309
|
+
/>
|
|
1310
|
+
}
|
|
1311
|
+
extraContent={
|
|
1312
|
+
<PlayerDetails
|
|
1313
|
+
configuration={this.getPluginConfiguration()}
|
|
1314
|
+
style={{ flex: 1 }}
|
|
1315
|
+
entry={entry}
|
|
1316
|
+
isTabletLandscape={!isTabletPortrait}
|
|
1317
|
+
inline={inline}
|
|
1318
|
+
docked={docked}
|
|
1319
|
+
isModal={isModal}
|
|
1320
|
+
pip={piped}
|
|
1321
|
+
/>
|
|
1322
|
+
}
|
|
1323
|
+
collapsedContent={
|
|
1324
|
+
<View style={styles.container}>
|
|
1325
|
+
<DockedControls
|
|
1122
1326
|
entry={entry}
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
isModal={isModal}
|
|
1127
|
-
pip={this.state.piped}
|
|
1327
|
+
aspectRatio={aspectRatio}
|
|
1328
|
+
layoutState={sharedWrapperViewProps.layoutState}
|
|
1329
|
+
playNextData={sharedWrapperViewProps.playNextData}
|
|
1128
1330
|
/>
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
/>
|
|
1138
|
-
</View>
|
|
1139
|
-
}
|
|
1331
|
+
</View>
|
|
1332
|
+
}
|
|
1333
|
+
/>
|
|
1334
|
+
) : (
|
|
1335
|
+
<View style={style} testID={"player-view"}>
|
|
1336
|
+
<PlayerWrapper
|
|
1337
|
+
{...sharedWrapperViewProps}
|
|
1338
|
+
playerContent={this.renderPlayerContent}
|
|
1140
1339
|
/>
|
|
1141
|
-
|
|
1340
|
+
</View>
|
|
1341
|
+
);
|
|
1342
|
+
};
|
|
1343
|
+
|
|
1344
|
+
renderTV = () => {
|
|
1345
|
+
const {
|
|
1346
|
+
docked,
|
|
1347
|
+
entry,
|
|
1348
|
+
listener,
|
|
1349
|
+
controller,
|
|
1350
|
+
PlayerComponent,
|
|
1351
|
+
playerId,
|
|
1352
|
+
setNextVideoPreloadThresholdPercentage,
|
|
1353
|
+
children,
|
|
1354
|
+
} = this.props;
|
|
1355
|
+
|
|
1356
|
+
const isAudioItem = isAudioItemUtil(entry);
|
|
1357
|
+
|
|
1358
|
+
const playerProps = {
|
|
1359
|
+
ref: this._assignRoot,
|
|
1360
|
+
...this.getNativeEvents(),
|
|
1361
|
+
...this.getNativeProps(),
|
|
1362
|
+
listener,
|
|
1363
|
+
style: this.takeParentStyle,
|
|
1364
|
+
controller,
|
|
1365
|
+
};
|
|
1366
|
+
|
|
1367
|
+
const audioPlayerProps = {
|
|
1368
|
+
style: { ...styles.audio, ...this.takeParentStyle },
|
|
1142
1369
|
};
|
|
1143
1370
|
|
|
1144
|
-
|
|
1371
|
+
if (this.state.error) {
|
|
1145
1372
|
return (
|
|
1146
1373
|
<View style={this.takeParentStyle} testID={"player-view"}>
|
|
1147
|
-
<
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
PlayerComponent={this.props.PlayerComponent}
|
|
1153
|
-
nativePlayerIsReady={this.state.nativePlayerIsReady}
|
|
1154
|
-
pluginConfiguration={this.getPluginConfiguration()}
|
|
1155
|
-
playerProps={{
|
|
1156
|
-
ref: this._assignRoot,
|
|
1157
|
-
...nativeEvents,
|
|
1158
|
-
...nativeProps,
|
|
1159
|
-
listener: this.props.listener,
|
|
1160
|
-
style: this.takeParentStyle,
|
|
1161
|
-
controller: this.props.controller,
|
|
1162
|
-
}}
|
|
1163
|
-
audioPlayerProps={{ style: getStyle(styles.playerSize) }}
|
|
1164
|
-
playNextProps={{
|
|
1165
|
-
playerIsDocked: docked,
|
|
1166
|
-
playerId: this.props.playerId,
|
|
1167
|
-
playNextData: this.getPlayNextData(),
|
|
1168
|
-
setNextVideoPreloadThresholdPercentage:
|
|
1169
|
-
this.props.setNextVideoPreloadThresholdPercentage,
|
|
1170
|
-
}}
|
|
1171
|
-
>
|
|
1172
|
-
{this.props.children}
|
|
1173
|
-
</TVPlayerView>
|
|
1374
|
+
<TVErrorOverlay
|
|
1375
|
+
error={this.state.error}
|
|
1376
|
+
onClose={() => playerManager.close()}
|
|
1377
|
+
configuration={this.getPluginConfiguration()}
|
|
1378
|
+
/>
|
|
1174
1379
|
</View>
|
|
1175
1380
|
);
|
|
1176
|
-
}
|
|
1381
|
+
}
|
|
1177
1382
|
|
|
1178
|
-
return
|
|
1383
|
+
return (
|
|
1384
|
+
<View style={this.takeParentStyle} testID={"player-view"}>
|
|
1385
|
+
<TVPlayerView
|
|
1386
|
+
type={isAudioItem ? "audio" : "video"}
|
|
1387
|
+
entry={entry}
|
|
1388
|
+
inline={this.isInlineTV()}
|
|
1389
|
+
transportControls={this.renderTransportControls(this.takeParentStyle)}
|
|
1390
|
+
PlayerComponent={PlayerComponent}
|
|
1391
|
+
nativePlayerIsReady={this.state.nativePlayerIsReady}
|
|
1392
|
+
pluginConfiguration={this.getPluginConfiguration()}
|
|
1393
|
+
playerProps={playerProps}
|
|
1394
|
+
audioPlayerProps={audioPlayerProps}
|
|
1395
|
+
playNextProps={{
|
|
1396
|
+
playerIsDocked: docked,
|
|
1397
|
+
playerId: playerId,
|
|
1398
|
+
playNextData: this.getPlayNextData(),
|
|
1399
|
+
setNextVideoPreloadThresholdPercentage:
|
|
1400
|
+
setNextVideoPreloadThresholdPercentage,
|
|
1401
|
+
}}
|
|
1402
|
+
>
|
|
1403
|
+
{children}
|
|
1404
|
+
</TVPlayerView>
|
|
1405
|
+
</View>
|
|
1406
|
+
);
|
|
1407
|
+
};
|
|
1408
|
+
|
|
1409
|
+
render() {
|
|
1410
|
+
return isTV() ? this.renderTV() : this.renderMobile();
|
|
1179
1411
|
}
|
|
1180
1412
|
}
|