I am creating an application for android and ios in react-native(0.57.7) and using react-native-video to play videos uploaded into vimeo. After integrate react video plugin, tested in both device. In ios it works perfectly but in android, I am not able to play video in full-screen mode. Here is my code for Android:
import React, { PureComponent } from 'react';
import {
View,
Text,
Image,
ImageBackground,
StyleSheet,
SafeAreaView,
TouchableOpacity,
ActivityIndicator
} from 'react-native';
import PropTypes from 'prop-types'
import Video from "react-native-video";
import Orientation from 'react-native-orientation-locker';
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from '../components/Resposive';
import RF from "react-native-responsive-fontsize"
export default class Videoplayer extends PureComponent {
constructor(props){
super(props);
this.state = {
loading: true,
videoFileArr:[],
showPlayer:false,
playing:false
}
}
componentDidMount() {
Orientation.lockToLandscape();
this.fetchVimeoVideo();
}
componentWillUnmount() {
Orientation.lockToPortrait();
}
goToHome(){
Orientation.lockToPortrait();
this.props.navigation.goBack();
}
fetchVimeoVideo = async () => {
await this.setState({ loading: true });
const { navigation } = this.props;
const jsonReceived = navigation.getParam('item', {})
const url = "https://api.vimeo.com/me/videos/" + jsonReceived.video_link
console.log(url)
const response = await fetch(
url, {
method: "get",
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization:"Bearer f9e937d64037e657addcf088f28e6cb5"
}
});
const jsonResponse = await response.json();
const { files} = jsonResponse;
if (response.status != 200) {
alert(response.status)
}
console.log(files)
await this.setState({ videoFileArr:files, loading: false });
};
renderOptions = () => {
if (this.state.loading === true) {
return (
<View style={{
flex: 1,
alignItems: "center",
justifyContent: "center"
}}>
<ActivityIndicator size="large" color="#00ff00" />
<Text style={{ fontFamily: "Futura Std", fontSize: RF(3.0), fontWeight: "900", color: "#244E25", textAlign: "center" }}>Please wait while we are loading questions for you</Text>
</View>
)
}else if (this.state.videoFileArr.length> 0 && this.state.playing === false) {
const { navigation } = this.props;
const jsonReceived = navigation.getParam('item', {})
return(
<ImageBackground style={{width:"100%",height:"100%",alignItems:"center",justifyContent:"center"}} source={{uri:jsonReceived.video_banner}}>
<TouchableOpacity
onPress={() => {
this.setState({playing:true})
}}
>
<Image source={require("../assets/Common/Play/playIcon.png")}/>
</TouchableOpacity>
</ImageBackground>
)
} else if (this.state.videoFileArr.length > 0 && this.state.playing === true) {
return (
<View style={styles.container}>
<Video source={{ uri:this.state.videoFileArr[0].link}} // Can be a URL or a local file.
ref={ ref =>
this.player = ref
} // Store reference
onBuffer={this.onBuffer} // Callback when remote video is buffering
onError={this.videoError} // Callback when video cannot be loaded
style={styles.backgroundVideo}
controls={true}
paused={false}
fullscreen={true}
/>
</View>
)
}
}
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ flex: 1, overflow: "hidden" }}>
<View style={{ flex: 1, backgroundColor: "green" }}>
{this.renderOptions()}
</View>
{/* top navigationBar */}
<View
style={{
position: "absolute",
top: 0,
left: 0,
right: 0,
width: "100%",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
height: 80,
backgroundColor: null
}}
>
<TouchableOpacity onPress={
()=>this.goToHome()
}>
<Image style={{ margin: 8 }} source={require("../assets/Common/goBack/goBack.png")} />
</TouchableOpacity>
<TouchableOpacity>
<Image style={{ margin: 8 }} source={require("../assets/Common/Star/starOff.png")} />
</TouchableOpacity>
</View>
</View>
</SafeAreaView>
)
}
}
const styles = StyleSheet.create({
container:{ flex: 1, justifyContent: "center"},
backgroundVideo: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
});
and this is the output screen where I can not play video in full screen:
Please help, What I'm doing wrong ?
By tapping on the TouchableOpacity component (or your own desired component), the full-screen video component would slide in and play the video in full-screen.
Making something fullscreen in browsers is surprisingly easy. All you have to do is call requestFullscreen() on any DOM node.
Supports formats such as MP4, M4A, FMP4, WebM, MKV, MP3, Ogg, WAV, MPEG-TS, MPEG-PS, FLV and ADTS (AAC). Support DASH, HlS and SmoothStreaming adaptive streaming.
I have solved fullscreen of video frame just adding resizeMode on Video component:
<Video source={{ uri:this.state.videoFileArr[0].link}} // Can be a URL or a local file.
ref={ ref =>
this.player = ref
} // Store reference
onBuffer={this.onBuffer} // Callback when remote video is buffering
onError={this.videoError} // Callback when video cannot be loaded
style={styles.backgroundVideo}
controls={true}
paused={false}
fullscreen={true}
resizeMode="cover"
/>
I was struggling with the same problem couple of days ago but I made it work for me in android. I hope this will help you also.
You will need to install some other package as well that is 1. react-native-video-controls 2. react-native-orientation
now In your Screen where the video will be played.
import React, { Component } from 'react'
import {
Text,
StyleSheet,
StatusBar,
Dimensions,
Alert,
Modal,
BackHandler,
TouchableOpacity,
ToastAndroid,
} from 'react-native'
import { Container, View, Button, Icon, List, ListItem } from 'native-base';
import Video from 'react-native-video';
import Orientation from 'react-native-orientation';
const sample = require('../assets/demo.mp4');
export default class Player extends Component {
constructor(props) {
super(props);
this.onLoad = this.onLoad.bind(this);
this.onProgress = this.onProgress.bind(this);
}
state = {
rate: 1,
volume: 1,
muted: false,
resizeMode: 'contain',
duration: 0.0,
currentTime: 0.0,
active: false,
modalVisible: false,
fullScreen: true,
};
onLoad(data) {
this.setState({ duration: data.duration });
}
onProgress(data) {
this.setState({ currentTime: data.currentTime });
}
getCurrentTimePercentage() {
if (this.state.currentTime > 0) {
return parseFloat(this.state.currentTime) / parseFloat(this.state.duration);
} else {
return 0;
}
}
renderRateControl(rate) {
const isSelected = (this.state.rate == rate);
return (
<ListItem>
<TouchableOpacity onPress={() => { this.setState({ rate: rate }) }}>
<Text style={{ fontWeight: isSelected ? "bold" : "normal" }}>
{rate}x
</Text>
</TouchableOpacity>
</ListItem>
)
}
renderResizeModeControl(resizeMode) {
const isSelected = (this.state.resizeMode == resizeMode);
return (
<TouchableOpacity onPress={() => { this.setState({ resizeMode: resizeMode })
}}>
<Text style={[styles.controlOption, { fontWeight: isSelected ? "bold" :
"normal" }]}>
{resizeMode}
</Text>
</TouchableOpacity>
)
}
setModalVisible = (visible) => {
this.setState({ modalVisible: visible });
}
fullScreen = () => {
Orientation.getOrientation((err, orientation) => {
if (orientation == 'LANDSCAPE') {
Orientation.lockToPortrait();
} else {
Orientation.lockToLandscape();
}
});
}
backAction = () => {
Orientation.getOrientation((err, orientation) => {
if (orientation == 'LANDSCAPE') {
Orientation.lockToPortrait();
}
});
};
componentDidMount() {
this.backHandler = BackHandler.addEventListener(
"hardwareBackPress",
this.backAction
);
}
componentWillUnmount() {
this.backHandler.remove();
}
render() {
const { modalVisible, paused } = this.state
const url = `https://www.sample-
videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4`;
const flexCompleted = this.getCurrentTimePercentage() * 100;
const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100;
return (
<View style={styles.container}>
<StatusBar hidden={true} />
<Video source={sample}
style={styles.fullScreen}
rate={this.state.rate}
paused={this.state.paused}
volume={this.state.volume}
muted={this.state.muted}
resizeMode={this.state.resizeMode}
onLoad={this.onLoad}
onProgress={this.onProgress}
onEnd={() => { alert('Done!') }}
controls
repeat={true} />
<View style={[{ left: 0 }, styles.rateControl]}>
<Button
transparent
onPress={() => {
this.fullScreen();
}}
>
<Icon type="FontAwesome5" name="compress" style={{ color: "#fff",
fontSize: 15 }} />
</Button>
</View>
<View style={styles.rateControl}>
<Button
transparent
onPress={() => {
this.setModalVisible(true);
}}
>
<Icon type="FontAwesome5" name="ellipsis-v" style={{ color:
"#fff", fontSize: 15 }} />
</Button>
</View>
{/* <View style={styles.controls}>
<View style={styles.generalControls}>
<View style={styles.resizeModeControl}>
{this.renderResizeModeControl('cover')}
{this.renderResizeModeControl('contain')}
{this.renderResizeModeControl('stretch')}
</View>
</View>
<View style={styles.trackingControls}>
<View style={styles.progress}>
<View style={[styles.innerProgressCompleted, { flex: flexCompleted }]} />
<View style={[styles.innerProgressRemaining, { flex: flexRemaining }]} />
</View>
</View>
</View> */}
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<View style={styles.closeModal}>
<Button
transparent
onPress={() => { this.setModalVisible(!modalVisible);
}}
>
<Icon name="close" />
</Button>
</View>
<View>
<Text style={{ textAlign: 'center', fontWeight: 'bold'
}}>Play Rate</Text>
<List style={{ flexDirection: 'row', justifyContent:
'space-between', alignItems: 'center' }}>
{this.renderRateControl(0.25)}
{this.renderRateControl(0.5)}
{this.renderRateControl(1.0)}
{this.renderRateControl(1.5)}
{this.renderRateControl(2.0)}
</List>
</View>
</View>
</View>
</Modal>
</View >
)
}
}
const styles = StyleSheet.create({
backgroundVideo: {
// position: 'absolute',
// top: 0,
// left: 0,
// bottom: 0,
// right: 0,
width: Dimensions.get('window').width,
height: Dimensions.get('window').width * .6,
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'black',
},
fullScreen: {
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
},
controls: {
backgroundColor: "transparent",
borderRadius: 5,
position: 'absolute',
bottom: 20,
left: 20,
right: 20,
},
progress: {
flex: 1,
flexDirection: 'row',
borderRadius: 3,
overflow: 'hidden',
},
innerProgressCompleted: {
height: 20,
backgroundColor: '#cccccc',
},
innerProgressRemaining: {
height: 20,
backgroundColor: '#2C2C2C',
},
generalControls: {
flex: 1,
// flexDirection: 'row',
borderRadius: 4,
overflow: 'hidden',
paddingBottom: 10,
},
rateControl: {
flexDirection: 'row',
position: 'absolute',
top: 10,
right: 10
},
volumeControl: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
},
resizeModeControl: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
controlOption: {
alignSelf: 'center',
fontSize: 11,
color: "white",
paddingLeft: 2,
paddingRight: 2,
lineHeight: 12,
},
centeredView: {
flex: 1,
marginTop: '22%'
},
modalView: {
width: '100%',
padding: '5%',
backgroundColor: "white",
position: 'absolute',
bottom: 10,
},
openButton: {
backgroundColor: "#F194FF",
borderRadius: 20,
padding: 10,
elevation: 2
},
closeModal: {
alignItems: 'flex-end',
margin: -10
},
textStyle: {
color: "white",
fontWeight: "bold",
textAlign: "center"
},
modalText: {
marginBottom: 15,
textAlign: "center"
}
});
I hope this will help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With