Videos are not played anymore when running on the final release of iOS 14.
We are using the latest version of react-native-video and the just release iOS 14.
+1 - the controls don鈥檛 even show. The video clearly has loaded in the background but it鈥檚 like it鈥檚 frozen after that.
Same here!
https://github.com/react-native-community/react-native-video/issues/2144 < This issue seems to be related.
Yea. It seems that video can be played, the bug is with the play button that disappear so it gives the impression the video is not loaded.
By default our controls are disabled. And in this case, the video doesn't show at all, I get a white background:
When I turn the controls prop to true, then the video controls show, seem to be playing, but the video is completely black:
And only happens with iOS 14.
Same Here
I have this problem too, here is little hack: if is set paused={true}, controls are not visible and playback cannot be started, but when is set paused={false}, video starts playing automatically and controls are visible after tap...
Anyone who want, here is code I used to wrap the player and add the following:
import React, {useRef, useState, useEffect} from 'react';
import {
View,
StyleSheet,
Pressable,
Animated,
Platform,
StatusBar,
} from 'react-native';
import Modal from 'react-native-modal';
import Video, {OnBufferData} from 'react-native-video';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import {screenSize} from 'resources/metrics';
import AnalyticsService from 'helpers/Analytics';
import Orientation from 'react-native-orientation-locker';
const MIN_NUMBER_OF_SECONDS_TO_TRACK_VIDEO_WATCH = 10;
export interface VideoPlayerViewInterface {
videoUrl: string;
videoTitle: string;
}
const VideoPlayer: React.FC<VideoPlayerViewInterface> = ({
videoUrl,
videoTitle,
}) => {
const [isPaused, setIsPaused] = useState(true);
const [isBuffering, setIsBuffering] = useState(false);
const [isShowModal, setIsShowModal] = useState(false);
const bufferAnimation = useRef(new Animated.Value(0)).current;
const [videoStyle, setVideoStyle] = useState(styles.portraitVideo);
let loopedBufferAnimation: Animated.CompositeAnimation | null = null;
const player = useRef(null);
useEffect(() => {
StatusBar.setHidden(true, 'fade');
Orientation.addDeviceOrientationListener((newOrientation: string) => {
if (
newOrientation === 'PORTRAIT' ||
newOrientation === 'PORTRAIT-UPSIDEDOWN'
) {
//StatusBar.setHidden(false, 'fade');
setVideoStyle(styles.portraitVideo);
} else {
StatusBar.setHidden(true, 'fade');
setVideoStyle(StyleSheet.absoluteFill);
}
});
return () => {
Orientation.removeAllListeners();
Orientation.lockToPortrait();
};
}, []);
const onVideoProgress = (params: {currentTime: number}) => {
const {currentTime} = params;
// Make sure we report a video view to analytics just once.
if (
currentTime > MIN_NUMBER_OF_SECONDS_TO_TRACK_VIDEO_WATCH &&
currentTime < MIN_NUMBER_OF_SECONDS_TO_TRACK_VIDEO_WATCH + 2
) {
AnalyticsService.logVideoView(videoTitle, videoUrl);
}
};
/* Called when the video start or finish buffering */
const onBuffer = (meta: OnBufferData) => {
// Are we starting to buffer?
if (meta.isBuffering && !isBuffering) {
animateBuffer();
}
// Did we just finished buffering?
if (!meta.isBuffering && isBuffering) {
if (loopedBufferAnimation) {
loopedBufferAnimation.stop();
}
}
setIsBuffering(meta.isBuffering);
};
/** Start the loop animation that shows while the video is buffering */
const animateBuffer = () => {
loopedBufferAnimation = Animated.loop(
Animated.timing(bufferAnimation, {
toValue: 1,
duration: 350,
useNativeDriver: true,
}),
).start();
};
const playVideo = () => {
if (Platform.OS === 'ios') {
setIsPaused(false);
} else {
Orientation.unlockAllOrientations();
setIsShowModal(true);
}
};
const pauseVideo = () => {
setIsPaused(true);
};
const getAndroidPlayer = () => {
return (
<View style={styles.portraitVideo}>
<Modal
isVisible={isShowModal}
supportedOrientations={['portrait', 'landscape']}
style={[StyleSheet.absoluteFill, styles.modal]}
onBackButtonPress={() => setIsShowModal(false)}>
<Video
source={{uri: videoUrl}}
ref={player}
style={videoStyle}
controls={true}
ignoreSilentSwitch="ignore"
paused={false}
resizeMode={'contain'}
progressUpdateInterval={
MIN_NUMBER_OF_SECONDS_TO_TRACK_VIDEO_WATCH * 1000
}
onProgress={onVideoProgress}
onBuffer={onBuffer}
/>
</Modal>
</View>
);
};
const getIOSPlayer = () => {
return (
<Video
source={{uri: videoUrl}}
ref={player}
style={videoStyle}
controls={true}
ignoreSilentSwitch="ignore"
paused={isPaused}
resizeMode={'contain'}
progressUpdateInterval={
MIN_NUMBER_OF_SECONDS_TO_TRACK_VIDEO_WATCH * 1000
}
onProgress={onVideoProgress}
onBuffer={onBuffer}
/>
);
};
const interpolatedAnimation = bufferAnimation.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg'],
});
const rotateStyle = {
transform: [{rotate: interpolatedAnimation}],
};
return (
<View style={styles.container}>
{Platform.OS === 'ios' ? getIOSPlayer() : getAndroidPlayer()}
{isBuffering && (
<View style={styles.videoOverlay}>
<Animated.View style={rotateStyle}>
<Pressable onPress={playVideo}>
<Icon name="loading" size={80} color="#000" />
</Pressable>
</Animated.View>
</View>
)}
{isPaused && !isBuffering && (
<View style={styles.videoOverlay}>
<Pressable onPress={playVideo}>
<Icon name="play-circle-outline" size={80} color="#000" />
</Pressable>
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
portraitVideo: {
height: screenSize.height * 0.4,
width: screenSize.width,
},
androidInitialVideo: {
borderColor: '#000',
borderWidth: 100,
borderStyle: 'solid',
},
modal: {
backgroundColor: '#000',
margin: 0,
},
videoOverlay: {
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
backgroundColor: 'transparent',
},
});
export default VideoPlayer;
Edit by n1ru4l: format code
Same issue
Same issue, any solutions?
Bad (but works) solution for me:
<TouchableWithoutFeedback
onPress={() => {
if (!this.video.live) {
this.video.live = true;
this.video.ref.current.playAsync();
}
}}
>
<Video
ref={this.video.ref}
style={{
width: '100%',
height: '100%',
...this.props.styleVideo
}}
source={this.props.source}
resizeMode={Video.RESIZE_MODE_CONTAIN}
rate={1.0}
volume={1.0}
isMuted={false}
shouldPlay={false}
isLooping={false}
useNativeControls={true}
/>
</TouchableWithoutFeedback>
constructor:
this.video = {
ref: React.createRef(),
live: false
};
Hey, iOS 14.2-beta seems to fix the issue.
same problem
Same issue here
Same problem
Same problem on iOS 14.0.1
same here
Same here on 14.1
Same problem on iOS 14.0.1
solution for me
constructor(props) {
super(props);
this.state = {
paused: true
}
}
_onLoad(data = {}) {
this.setState({paused: false});
}
paused={this.state.paused}
resizeMode={"contain"}
fullscreen={true}
controls={true}
source={{uri}}
style={styles.videoPlayer}
onLoad={this._onLoad.bind(this)}
/>
Most helpful comment
Same here!