Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem: Why react native video does not play video in full screen?

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:

enter image description here

Please help, What I'm doing wrong ?

like image 719
Sahadev Avatar asked Mar 09 '19 09:03

Sahadev


People also ask

How do you play video in full screen in React Native?

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.

How do you implement full screen in React?

Making something fullscreen in browsers is surprisingly easy. All you have to do is call requestFullscreen() on any DOM node.

Does React Native video support HlS?

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.


2 Answers

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"
/>
like image 136
Sahadev Avatar answered Oct 10 '22 22:10

Sahadev


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.

like image 45
Mudit Gulgulia Avatar answered Oct 10 '22 21:10

Mudit Gulgulia