title: React Native Youtube Iframe is flickering constantly under an Android 9.1 phone
body: <p>The video is flickering on a Huawei phone under Android 9. The phone does not have issues with other apps playing youtube videos and the other phones tested do not have this issue.</p>
  <p><a href="https://www.youtube.com/watch?v=iEhmZsQz0HM" rel="nofollow noreferrer">https://www.youtube.com/watch?v=iEhmZsQz0HM</a></p>
  <ul>
  <li>Device: HUAWEI MHA-L29</li>
  <li>OS + version: EMUI Android 9.1.0.275</li>
  <li>&quot;react-native&quot;: &quot;^0.63.2&quot;,</li>
  <li>&quot;react-native-youtube-iframe&quot;: &quot;^1.3.0&quot;,</li>
  <li>&quot;react-native-webview&quot;: &quot;^10.8.3&quot;,</li>
  <li>No expo</li>
  </ul>
  <p>The following component is passed along with the React Navigation bottom tab:</p>
  <pre class="lang-js prettyprint-override"><code>import React, { FC, useCallback, useContext, useEffect, useState } from 'react'
  import { PixelRatio, Platform, StatusBar, StyleSheet, TouchableOpacity, View, ViewStyle } from 'react-native'
  import YoutubePlayer from 'react-native-youtube-iframe'
  import { colors, MediaContext, paths } from '../../apps'
  import SvgPath from '../../components/SvgPath'
  import Orientation from 'react-native-orientation-locker'
  import useOrientation from '../orientation/useOrientation'
  import { useDimensions } from '@react-native-community/hooks'
  
  // Due to React Native issue the Dimension API crash randomly in React Native 0.63
  // The workaround is:
  // - not to use useWindowsDimensions
  // - use instead useDimensions.screen
  // https://github.com/facebook/react-native/issues/29451
  // https://github.com/wonday/react-native-orientation-locker/issues/71
  
  /**
   * Drawer that holds the media when not full screen
   */
  const MediaPlayerBox: FC = () =&gt; {
    /**
     * This is just a classical Context API
     */
    const {
      postMediaUrl,
      setPostMediaUrl,
      postMediaInfos,
      setPostMediaInfos,
      postMediaInfosChecked,
      setPostMediaInfosChecked,
      postMediaButton,
      setPostMediaButton,
      playerMediaInfos,
      setPlayerMediaInfos,
      mediaPlayerIsUp,
      setMediaPlayerIsUp,
      playerFullScreen,
      setPlayerFullScreen,
      getInfosFromUrl,
      onPressPlay,
      onPressStop,
      playerState,
      setPlayerState,
      toggleFullScreen,
    } = useContext(MediaContext)
  
    /** This is an interface to React Native Orientation Locker */
    const {
      requestedOrientationLock,
      setRequestedOrientationLock,
      orientation,
      deviceOrientation,
      orientationLock,
      androidRotationLock,
      lockToPortrait,
      lockToLandscape,
      isLocked,
      unlockAllOrientations,
      fixDimensions,
    } = useOrientation()
  
    /** settle the dimensions according to the screen */
    const { width, height } = useDimensions().screen
    const ratio16per9 = PixelRatio.roundToNearestPixel(width / (16 / 9))
  
    const [playerViewStyle, setPlayerViewStyle] = useState&lt;ViewStyle | null&gt;(null)
    const [playerHeight, setPlayerHeight] = useState(ratio16per9)
    const [playerWidth, setPlayerWidth] = useState(width)
  
    /** Change the layout when the player goes fullscreen */
    useEffect(() =&gt; {
      // un mount protection
      let mounted = true
  
      // constants
      const boxedViewStyle: ViewStyle = {
        bottom: 90,
        elevation: 5,
        position: 'absolute',
        right: 0,
        left: 0,
        shadowColor: colors.shadow,
        shadowOffset: {
          width: 0,
          height: 2,
        },
        shadowOpacity: 0.25,
        shadowRadius: 3.84,
        zIndex: 1,
      }
  
      const fullscreenViewStyle: ViewStyle = {
        position: 'absolute',
        top: 0,
        right: 0,
        left: 0,
        bottom: 0,
        zIndex: 2,
        elevation: 6,
        backgroundColor: colors.deepBlack,
      }
  
      // This was tested but there is some bugs lefts regarding size and positioning
      const fullscreenViewStyleRotated: ViewStyle = {
        transform: [{ rotate: '90deg' }],
        position: 'absolute',
        flex: 1,
        right: -width / 2,
        top: +width / 2,
        width: height,
        height: width,
        zIndex: 2,
        elevation: 6,
        backgroundColor: colors.deepBlack,
      }
  
      // Do the magic trick to change everything
      if (mounted) {
        if (playerFullScreen) {
          lockToLandscape() // View horizontal
          setPlayerViewStyle(fullscreenViewStyle)
          setPlayerWidth(PixelRatio.roundToNearestPixel(width / (9 / 16)))
          setPlayerHeight(height)
        } else {
          lockToPortrait() // View
          setPlayerViewStyle(boxedViewStyle)
          setPlayerWidth(width)
          setPlayerHeight(PixelRatio.roundToNearestPixel(width / (16 / 9)))
        }
      }
  
      return (): void =&gt; {
        Orientation.lockToPortrait()
        mounted = false
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [playerFullScreen, height, width])
  
    /** Listen to state changes of the player */
    const onStateChange = useCallback(
      (state) =&gt; {
        setPlayerState(state)
      },
      // eslint-disable-next-line react-hooks/exhaustive-deps
      [],
    )
  
    // When closing with the cross
    const onClose = (): void =&gt; {
      onPressStop()
    }
  
    if (mediaPlayerIsUp &amp;&amp; playerMediaInfos.id)
      return (
        &lt;View style={[styles.playerView, playerViewStyle]}&gt;
          {playerFullScreen &amp;&amp; &lt;StatusBar hidden={true} /&gt;}
          &lt;YoutubePlayer
            videoId={playerMediaInfos.id || 'xuCn8ux2gbs'} // The YouTube video ID}
            play={mediaPlayerIsUp} // control playback of video with true/false
            onChangeState={onStateChange} // detects state change
            height={playerHeight}
            width={playerWidth}
            initialPlayerParams={{
              // eslint-disable-next-line @typescript-eslint/camelcase
              iv_load_policy: 3,
              modestbranding: true,
              preventFullScreen: true,
            }}
            onError={(error): void =&gt; {
              console.log('ERROR &gt; MediaPlayerBox &gt; YoutubePlayer: ', error)
            }}
            forceAndroidAutoplay={Platform.OS === 'android'}
          /&gt;
          &lt;View style={styles.fullScreen}&gt;
            &lt;TouchableOpacity activeOpacity={0.8} onPress={toggleFullScreen}&gt;
              &lt;SvgPath path={paths.mdiFullscreen} round={false} fillColor={colors.darkGrey} size={40} /&gt;
            &lt;/TouchableOpacity&gt;
          &lt;/View&gt;
          &lt;View style={styles.close}&gt;
            &lt;TouchableOpacity activeOpacity={0.8} onPress={onClose}&gt;
              &lt;SvgPath path={paths.mdiClose} round={false} fillColor={colors.darkGrey} size={40} /&gt;
            &lt;/TouchableOpacity&gt;
          &lt;/View&gt;
        &lt;/View&gt;
      )
  
    return null
  }
  
  /// Styles ///
  const styles = StyleSheet.create({
    close: {
      position: 'absolute',
      right: 10,
      top: 10,
      zIndex: 7,
    },
    fullScreen: {
      position: 'absolute',
      left: 10,
      top: 10,
      zIndex: 7,
    },
    playerView: {
      bottom: 90,
      elevation: 5,
      position: 'absolute',
      shadowColor: colors.shadow,
      shadowOffset: {
        width: 0,
        height: 2,
      },
      shadowOpacity: 0.25,
      shadowRadius: 3.84,
      zIndex: 1,
      alignItems: 'center',
    },
  })
  
  export default MediaPlayerBox
  </code></pre>