微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在Android 9.1手机下,React Native Youtube Iframe不断闪烁

如何解决在Android 9.1手机下,React Native Youtube Iframe不断闪烁

视频在Android 9下的华为手机上闪烁。该手机与播放youtube视频的其他应用没有问题,并且经过测试的其他手机也没有此问题。

https://www.youtube.com/watch?v=iEhmZsQz0HM

  • 设备:华为MHA-L29
  • OS +版本:EMUI Android 9.1.0.275
  • “ react-native”:“ ^ 0.63.2”,
  • “ react-native-youtube-iframe”:“ ^ 1.3.0”,
  • “ react-native-webview”:“ ^ 10.8.3”,
  • 没有博览会

以下组件与“ React Navigation”底部选项卡一起传递:

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 = () => {
  /**
   * 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<ViewStyle | null>(null)
  const [playerHeight,setPlayerHeight] = useState(ratio16per9)
  const [playerWidth,setPlayerWidth] = useState(width)

  /** Change the layout when the player goes fullscreen */
  useEffect(() => {
    // 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,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' }],flex: 1,right: -width / 2,top: +width / 2,width: height,height: width,}

    // 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 => {
      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) => {
      setPlayerState(state)
    },// eslint-disable-next-line react-hooks/exhaustive-deps
    [],)

  // When closing with the cross
  const onClose = (): void => {
    onPressstop()
  }

  if (mediaPlayerIsUp && playerMediaInfos.id)
    return (
      <View style={[styles.playerView,playerViewStyle]}>
        {playerFullScreen && <StatusBar hidden={true} />}
        <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 => {
            console.log('ERROR > MediaPlayerBox > YoutubePlayer: ',error)
          }}
          forceAndroidAutoplay={Platform.OS === 'android'}
        />
        <View style={styles.fullScreen}>
          <TouchableOpacity activeOpacity={0.8} onPress={toggleFullScreen}>
            <SvgPath path={paths.mdiFullscreen} round={false} fillColor={colors.darkGrey} size={40} />
          </TouchableOpacity>
        </View>
        <View style={styles.close}>
          <TouchableOpacity activeOpacity={0.8} onPress={onClose}>
            <SvgPath path={paths.mdiClose} round={false} fillColor={colors.darkGrey} size={40} />
          </TouchableOpacity>
        </View>
      </View>
    )

  return null
}

/// Styles ///
const styles = StyleSheet.create({
  close: {
    position: 'absolute',right: 10,top: 10,zIndex: 7,fullScreen: {
    position: 'absolute',left: 10,playerView: {
    bottom: 90,shadowOffset: {
      width: 0,alignItems: 'center',})

export default MediaPlayerBox

解决方法

您的视频在Mate 9手机上运行良好,我使用的是与您在应用中相同的react-native-youtube-iframe和react-native-webview。您可以在here

上找到演示视频。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。