I confirm this is a Feature Request and NOT a support/technical query. Please use your Bitmovin Dashboard for raising support tickets.
on
Which product is your request related to?
Player
Description
On the react native bitmovin fullscreen player example, we found out that the implementation does not reflect a realistic use case.
Indeed, the strategy to go fullscreen is to hide everything around the player (navigation menu etc) and putting the player absolutely above the rest.
It is not realistic because:
- usually, there are other elements in a player page, and nothing here is present in the example. It makes it even trickier to make the layout work. Especially since the player will be in a scroll view among other elements.
- usually, you have a bottom bar as well. There’s no way to hide the bottom bar by default (maybe by triggering a state up the tree to the bottom tab bar declaration but it seems very brittle)
We’d expect a solution where the player fullscreen is completely independent of the rest of the layout.
One solution for that is to move the player view to a fullscreen modal and go to landscape mode. We did it and it works very well. It allows to have other elements and have the fullscreen always work, no matter what is next to it.
We have a patch for the example that we can share with you ![]()
diff --git a/example/src/screens/LandscapeFullscreenHandling.tsx b/example/src/screens/LandscapeFullscreenHandling.tsx
index 1d040ba6..ce23d438 100644
--- a/example/src/screens/LandscapeFullscreenHandling.tsx
+++ b/example/src/screens/LandscapeFullscreenHandling.tsx
@@ -1,5 +1,12 @@
import React, { useCallback, useRef, useState } from 'react';
-import { Platform, StatusBar, StyleSheet, View } from 'react-native';
+import {
+ Modal,
+ Platform,
+ ScrollView,
+ StatusBar,
+ StyleSheet,
+ View,
+} from 'react-native';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { useFocusEffect } from '@react-navigation/native';
import {
@@ -82,12 +89,7 @@ export default function LandscapeFullscreenHandling({
const [fullscreenMode, setFullscreenMode] = useState(true);
const fullscreenHandler = useRef(
new SampleFullscreenHandler(fullscreenMode, (isFullscreen: boolean) => {
- console.log('on fullscreen change');
setFullscreenMode(isFullscreen);
- navigation.setOptions({
- headerShown: !isFullscreen, // show/hide top bar
- autoHideHomeIndicator: isFullscreen, // show/hide home indicator on iOS
- });
})
).current;
useFocusEffect(
@@ -136,20 +138,50 @@ export default function LandscapeFullscreenHandling({
setFullscreenMode(false);
}, []);
+ const playerView = (
+ <PlayerView
+ player={player}
+ isFullscreenRequested={fullscreenMode}
+ style={fullscreenMode ? styles.playerFullscreen : styles.player}
+ fullscreenHandler={fullscreenHandler}
+ onFullscreenEnter={onEvent}
+ onFullscreenExit={onEvent}
+ onFullscreenEnabled={onEvent}
+ onFullscreenDisabled={onEvent}
+ onPlayerError={onError}
+ onSourceError={onError}
+ />
+ );
+
return (
- <View style={styles.container}>
- <PlayerView
- player={player}
- isFullscreenRequested={fullscreenMode}
- style={fullscreenMode ? styles.playerFullscreen : styles.player}
- fullscreenHandler={fullscreenHandler}
- onFullscreenEnter={onEvent}
- onFullscreenExit={onEvent}
- onFullscreenEnabled={onEvent}
- onFullscreenDisabled={onEvent}
- onPlayerError={onError}
- onSourceError={onError}
- />
+ <View style={styles.page}>
+ <ScrollView>
+ <View style={styles.container}>{!fullscreenMode && playerView}</View>
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ <View style={styles.dumbContent} />
+ </ScrollView>
+ <Modal
+ visible={fullscreenMode}
+ animationType="none"
+ style={{ backgroundColor: 'red', padding: 20 }}
+ onRequestClose={() => fullscreenHandler.exitFullscreen()}
+ >
+ {playerView}
+ </Modal>
</View>
);
}
@@ -160,6 +192,8 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'white',
+ width: '100%',
+ aspectRatio: 16 / 9,
padding: 20,
},
player: {
@@ -174,4 +208,13 @@ const styles = StyleSheet.create({
left: 0,
backgroundColor: 'black',
},
+ page: {
+ flex: 1,
+ },
+ dumbContent: {
+ height: 200,
+ backgroundColor: 'pink',
+ width: 200,
+ margin: 10,
+ },
});