full screen video exit messes up layout in Webview

When I play video in full screen with device on portrait position and exit, it’s all fine. However, when I play video in full screen, turn the device to landscape and exit, the layout of the whole app gets completely messed up.

package.json

{
“main”: “node_modules/expo/AppEntry.js”,
“scripts”: {
“start”: “expo start”,
“android”: “expo start --android”,
“ios”: “expo start --ios”,
“web”: “expo start --web”,
“eject”: “expo eject”
},
“dependencies”: {
@react-native-community/netinfo”: “^4.6.0”,
“expo”: “^35.0.0”,
“expo-av”: “^7.0.1”,
“expo-barcode-scanner”: “~7.0.0”,
“expo-constants”: “~7.0.0”,
“expo-device”: “^1.0.0”,
“expo-font”: “~7.0.0”,
“expo-image-picker”: “~7.0.0”,
“expo-intent-launcher”: “~7.0.0”,
“expo-localization”: “^7.0.0”,
“expo-permissions”: “~7.0.0”,
“expo-speech”: “^7.0.0”,
“expo-task-manager”: “~7.0.0”,
“expo-video-player”: “^1.5.1”,
“firebase”: “^6.3.3”,
“native-base”: “^2.13.5”,
“prop-types”: “^15.7.2”,
“react”: “16.8.3”,
“react-dom”: “16.8.3”,
“react-native”: “0.59.10”,
“react-native-animatable”: “^1.3.3”,
“react-native-animated-flatlist”: “0.0.3”,
“react-native-app-intro-slider”: “^2.0.1”,
“react-native-button”: “^2.4.0”,
“react-native-camera-kit”: “^8.0.0”,
“react-native-device-info”: “^2.3.2”,
“react-native-elements”: “^1.1.0”,
“react-native-gesture-handler”: “~1.3.0”,
“react-native-htmlview”: “^0.15.0”,
“react-native-image-gallery”: “^2.1.5”,
“react-native-modal”: “^11.4.0”,
“react-native-modal-datetime-picker”: “^7.6.0”,
“react-native-parallax-swiper”: “^1.1.7”,
“react-native-parsed-text”: “0.0.21”,
“react-native-picker-select”: “^6.3.0”,
“react-native-reanimated”: “~1.2.0”,
“react-native-render-html”: “^4.1.2”,
“react-native-scalable-image”: “^1.0.0”,
“react-native-scrollable-tab-view”: “^0.10.0”,
“react-native-simple-animations”: “^0.2.1”,
“react-native-tts”: “^3.0.0”,
“react-native-unimodules”: “0.6.0”,
“react-native-vector-icons”: “^6.6.0”,
“react-native-web”: “^0.11.7”,
“react-native-webbrowser-with-back”: “^1.0.36”,
“react-native-webview”: “^7.5.1”,
“react-navigation”: “^4.0.6”,
“react-navigation-drawer”: “^2.0.0”,
“react-navigation-stack”: “^1.10.2”,
“react-navigation-tabs”: “^2.5.6”,
“react-redux”: “^7.1.0”,
“redux”: “^4.0.4”,
“shorthash”: “0.0.2”
},
“devDependencies”: {
“babel-preset-expo”: “^7.0.0”
},
“private”: true
}

app.json

{
“expo”: {
“privacy”: “public”,
“sdkVersion”: “35.0.0”,
“platforms”: [
“ios”,
“android”,
“web”
],
“version”: “1.0.0”,
“orientation”: “portrait”,
“icon”: “./assets/icon.png”,
“splash”: {
“image”: “./assets/splash.png”,
“resizeMode”: “cover”,
“backgroundColor”: “#156aa7
},
“updates”: {
“fallbackToCacheTimeout”: 0
},
“assetBundlePatterns”: [
“**/*”
],
“ios”: {
“supportsTablet”: true,
“bundleIdentifier”: “com.revert.project”
},
“description”: “”,
“androidStatusBar”: {
“barStyle”: “light-content”,
“backgroundColor”: “#000
},
“androidNavigationBar”: {
“visible”: false,
“barStyle”: “light-content”,
“backgroundColor”: “#000
}
}
}

Can you provide more information like screenshots or webview code?
I am facing the same issue on iOS.
After rotating device to landscape and exit, app header overlays status bar.
I haven’t found a proper way to fix this yet, I just simply set marginTop for app header.

Yup! That’s the same problem. So I increased the height of the header (i’m using react navigation) in order to be able to hit the back arrow. It worked but the previous layout was also completely messed up, from headers to the bottom nav. bar

I believe it has something to do with the orientation but I don’t know how to fix it. Setting to Portrait after exiting full screen might help… I don’t know.

I include a video to the page, using Webview:

   <View
          style={{
            justifyContent: "flex-start"
          }}
        >
          <WebView
            decelerationRate="normal"
            originWhitelist={["*"]}
            source={{ uri: video }}
            style={{
              width: widthp,
              height: heightp
            }}
          />
        </View>
1 Like

I think you should consider using expo-av Video instead. The hardest part is to find the direct link to the .mp4 file of your video. It will not mess up your layout but you might not be able to use the original video controller from the web.

The problem with expo AV is its lack of controls (designs). I also tried “expo-video-player” but the fullscreen function doesn’t work properly. The video remains within , plus I had to change orientation.

Are you aware, by any chance, of any repo that would offer a better option than using the one using webview?

Thanks!

1 Like

Additional piece of information:

I checked the width Dimension before and after I exited the full screen mode and they are indeed different.
Before I started the video, the width was 375 but when I played it in full screen, turned the device and exited full screen in landscape mode, width was 812.

So, even though I set "orientation": "portrait" in app.json, I need to lock the orientation again in every page?

Check out my project at https://gitlab.com/Minho1/my-expo-video-player-test

It might help.

After you run npm install or yarn install, change 2 lines(361 and 365) in node_modules->expo-video-player->dist->index.js like this:
let videoHeight = height; → let videoHeight = height +60;
videoHeight = videoWidth / screenRatio; → videoHeight = videoWidth / screenRatio + 60;

expo-video-player’s fullscreen is not really fullscreen though, it’s just changing video’s width and height.

This is really painful. I thought about using react-native-community/ react-native-video but ejecting expo to ExpoKit is even more painful linking all dependencies and I don’t know if it will be better.

Has someone found a workaround?

Not that I’m aware of. Funny you ask, I’ve been working on that issue since this morning!

The problem, as I understand it, is because you probably set the orientation to “portrait” in app.json. Therefore, no matter the position of the device will remain in portrait, as intended.

However, when you play a video through webview, iOS will not respect the default orientation in app.json and will update the screen orientation anyway. When played in portrait and exited in portrait, that’s fine but if you turn your device in landscape and exit full screen then the orientation will be stuck in landscape.

Here is the closest solution I found:

import { ScreenOrientation } from "expo";

  componentDidMount() {
    ScreenOrientation.unlockAsync();
    ScreenOrientation.addOrientationChangeListener(async event => {
      if (event.orientationInfo.orientation === "LANDSCAPE") {
        //Alert.alert("landscape");
        await ScreenOrientation.lockAsync(
          ScreenOrientation.OrientationLock.PORTRAIT_UP
        );
      } else {
// Because sometimes it get stuck
        await ScreenOrientation.lockAsync(
          ScreenOrientation.OrientationLock.PORTRAIT_UP
        );
      }
    });
}

The first time you play the video in fullscreen and move from portrait position to landscape, it will go back to portrait mode. Try one more time and it should work.

I know it’s clumsy and hackish but that’s all I got so far… Unless you know how to make iOS communicate the actual screen orientation to react.

1 Like

I have been playing with your script but I’m getting a warning related to the unmounted component.

How do you unmounted this:

componentDidMount() {
    ScreenOrientation.addOrientationChangeListener(async event => {
        if (event.orientationInfo.orientation === 'PORTRAIT' || 
        event.orientationInfo.orientation === 'PORTRAIT_UP' || 
        event.orientationInfo.orientation === 'PORTRAIT_DOWN') {
            this.setState({
                inFullscreen: false
            })
        } else {
            this.setState({
                inFullscreen: true
            })
        }
    })
}

I tried different options, including
ScreenOrientation.removeOrientationChangeListener()

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.