问题描述
视频在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
上找到演示视频。