react-nativereact-navigationreact-navigation-stackreact-native-video

video keeps playing when I navigate to another screen


when I upload a video from my gallery and then try to navigate to the next screen,the video keeps playing in the background.

below is my code:

import React, {PureComponent} from 'react';
import {
  StyleSheet,
  Text,
  TouchableOpacity,
  View,
  Animated,
  ProgressBarAndroid,
} from 'react-native';
import {RNCamera} from 'react-native-camera';
import Icon from 'react-native-vector-icons/Entypo';
import ImagePicker from 'react-native-image-crop-picker';
import Video from 'react-native-video';
import { withNavigationFocus } from 'react-navigation';

class Shoot extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      recording: false,
      processing: true,
      upload: false,
      galleryVideo: '',
      progress30: '',
      progress60: '',
      progress15: 0,
      video: '',
      progressStatus: 0,
      progressStatus60: 0,
      progressStatus15: 0,
      videoPaused: false
    };
  }
  render() {
    return (
      <View style={styles.container}>
        {this.state.upload == true && (
          <TouchableOpacity
            style={{
              backgroundColor: '#e75480',
              position: 'absolute',
              width: 80,
              height: 30,
              zIndex: 2,
              padding: 5,
              borderRadius: 5,
              right: 0,
              justifyContent: 'center',
              alignContent: 'center',
            }}
            onPress={() => this.props.navigation.navigate('Post', {key: 1})}>
            <Text style={{color: 'white', textAlign: 'center'}}>Next</Text>
          </TouchableOpacity>
        )}

        {this.state.upload == false && (
          <TouchableOpacity
            style={{
              position: 'absolute',
              bottom: 0,
              right: '15%',
              justifyContent: 'center',
              alignItems: 'center',
            }}
            onPress={this.video.bind(this)}>
            <Icon name="image" size={30} color="white" />
            <Text style={{color: 'white', fontWeight: 'bold'}}>Upload</Text>
          </TouchableOpacity>
        )}

        <TouchableOpacity
          onPress={this.take60sVideo.bind(this)}
          style={{
            width: 60,
            height: 60,
            justifyContent: 'center',
            alignContent: 'center',
            position: 'absolute',
            bottom: 0,
            left: '25%',
          }}>
          <Text style={{textAlign: 'center', color: 'red', fontSize: 15}}>
            60s
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          onPress={this.take15sVideo.bind(this)}
          style={{
            width: 60,
            height: 60,
            justifyContent: 'center',
            alignContent: 'center',
            position: 'absolute',
            bottom: 0,
            left: '5%',
          }}>
          <Text style={{textAlign: 'center', color: 'red', fontSize: 15}}>
            15s
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          onPress={this.take30sVideo.bind(this)}
          style={styles.capture}></TouchableOpacity>

        {this.state.progress30 === true && (
          <View
            style={{
              width: '100%',
              height: 15,
              top: 0,
              position: 'absolute',
              bottom: 0,
              zIndex: 2,
            }}>
            {/* <Animated.View
              style={
                ([StyleSheet.absoluteFill],
                {backgroundColor: '#8BED4F', width: '50%', height: 10})
              }
            /> */}
            <ProgressBarAndroid
              styleAttr="Horizontal"
              progress={this.state.progressStatus}
              indeterminate={false}
              color="#e75480"
            />
          </View>
        )}
        {this.state.progress60 === true && (
          <View
            style={{
              width: '100%',
              height: 15,
              top: 0,
              position: 'absolute',
              bottom: 0,
              zIndex: 2,
            }}>
            {/* <Animated.View
              style={
                ([StyleSheet.absoluteFill],
                {backgroundColor: '#8BED4F', width: '50%', height: 10})
              }
            /> */}
            <ProgressBarAndroid
              styleAttr="Horizontal"
              progress={this.state.progressStatus60}
              indeterminate={false}
              color="#e75480"
            />
          </View>
        )}

        {this.state.progress15 === true && (
          <View
            style={{
              width: '100%',
              height: 15,
              top: 0,
              position: 'absolute',
              bottom: 0,
              zIndex: 2,
            }}>
            {/* <Animated.View
              style={
                ([StyleSheet.absoluteFill],
                {backgroundColor: '#8BED4F', width: '50%', height: 10})
              }
            /> */}
            <ProgressBarAndroid
              styleAttr="Horizontal"
              progress={this.state.progressStatus15}
              indeterminate={false}
              color="#e75480"
            />
          </View>
        )}
        {this.state.video == '' ? (
          <RNCamera
            ref={(ref) => {
              this.camera = ref;
            }}
            style={styles.preview}
            type={RNCamera.Constants.Type.back}
            flashMode={RNCamera.Constants.FlashMode.on}
            androidCameraPermissionOptions={{
              title: 'Permission to use camera',
              message: 'We need your permission to use your camera',
              buttonPositive: 'Ok',
              buttonNegative: 'Cancel',
            }}
            androidRecordAudioPermissionOptions={{
              title: 'Permission to use audio recording',
              message: 'We need your permission to use your audio',
              buttonPositive: 'Ok',
              buttonNegative: 'Cancel',
            }}
            captureAudio={true}
          />
        ) : (
          <Video
            source={{uri: this.state.video}}
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              alignItems: 'stretch',
              bottom: 0,
              right: 0,
              height: '90%',
            }}
            resizeMode="cover"
            repeat={true}
            paused={this.state.videoPaused}
          />
        )}
      </View>
    );
  }
  static getDerivedStateFromProps(nextProps, prevState) {
    return {
      ...prevState,
      videoPaused: !nextProps.navigation.isFocused()
    }
  }
  video = () => {
    ImagePicker.openPicker({
      mediaType: 'video',
    }).then((video) => {
      this.setState({
        galleryVideo: 1,
        video: video.path,
        upload: true,
      });
    });
  };

  take30sVideo = async () => {
    if (this.camera) {
      try {
        const options = {
          quality: 2,
          videoBitrate: 8000000,
          maxDuration: 30,
        };
        const promise = this.camera.recordAsync(options);
        this.setState({progress30: true});
        this.value = setInterval(() => {
          if (this.state.progressStatus <= 1) {
            this.setState({progressStatus: this.state.progressStatus + 0.01});
          }
        }, 100);
        if (promise) {
          this.setState({recording: true});
          const data = await promise;
          this.setState({recording: false, upload: true, progress30: false});
          console.log(data);
          console.log('upload', this.state.upload);
        }
      } catch (error) {
        console.log(error);
      }
    }
  };

  take60sVideo = async () => {
    if (this.camera) {
      try {
        const options = {
          quality: 2,
          videoBitrate: 8000000,
          maxDuration: 60,
        };
        const promise = this.camera.recordAsync(options);
        this.setState({progress60: true});
        this.value = setInterval(() => {
          if (this.state.progressStatus60 <= 1) {
            this.setState({
              progressStatus60: this.state.progressStatus60 + 0.01,
            });
          }
        }, 100);
        if (promise) {
          this.setState({recording: true});
          const data = await promise;
          this.setState({recording: false, upload: true, progress60: false});
          console.log(data);
          console.log('upload', this.state.upload);
        }
      } catch (error) {
        console.log(error);
      }
    }
  };
  take15sVideo = async () => {
    if (this.camera) {
      try {
        const options = {
          quality: 2,
          videoBitrate: 8000000,
          maxDuration: 15,
        };
        const promise = this.camera.recordAsync(options);
        this.setState({progress15: true});
        this.value = setInterval(() => {
          if (this.state.progressStatus15 <= 1) {
            this.setState({
              progressStatus15: this.state.progressStatus15 + 0.01,
            });
          }
        }, 100);
        if (promise) {
          this.setState({recording: true});
          const data = await promise;
          this.setState({recording: false, upload: true, progress15: false});
          console.log(data);
          console.log('upload', this.state.upload);
        }
      } catch (error) {
        console.log(error);
      }
    }
  };
}
export default withNavigationFocus(Shoot);
const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
    backgroundColor: 'black',
  },
  preview: {
    height: '90%',
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  capture: {
    backgroundColor: '#e75480',
    borderRadius: 40,
    borderWidth: 3,
    borderColor: 'red',
    width: 60,
    height: 60,
    position: 'absolute',
    bottom: 0,
    justifyContent: 'center',
    left: '45%',
    alignContent: 'center',
  },
});

I have already tried withNavigationFocus but it is not working,let me know if any other way is there,also let me know if anything else is required for clarification.

Any suggestion would be great.


Solution

  • I have finally resolved this issue by creating a function for next button and setting the state of paused to true whenever the screen navigates to the other screen. Hope,that helps.