0

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.

TRINA CHAUDHURI
  • 627
  • 1
  • 11
  • 42
  • Do you get to the getDerivedStateFromProps if you debug ? also try paused={this.state.videoPaused && this.props.navigation.isFocused()} instead of derived props – Guruparan Giritharan Sep 09 '20 at 11:48

3 Answers3

1

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.

TRINA CHAUDHURI
  • 627
  • 1
  • 11
  • 42
0

Setting the video screen as "fullScreenModal" worked for me:

("react-native": "0.71.2", "@react-navigation/native": "^6.1.3", "react-native-video": "^5.2.1")

react navigation stack definition:

function Stack() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="SomeScreen" component={SomeScreen} />
      <Stack.Screen
        name="FullScreenVideo"
        component={FullScreenVideo}
        options={{ headerShown: false, presentation: "fullScreenModal" }}
        />
    </Stack.Navigator>;
  )
}

FullScreenVideo.jsx

import React from "react";
import Video from "react-native-video";
import { StyleSheet } from "react-native";

export default function FullScreenVideo({ navigation, route }) {
  const videoUri = route.params.uri;
  return (
    <Video
      source={{ uri: videoUri }}
      controls
      onEnd={() => navigation.pop()}
      style={styles.backgroundVideo}
    />
  );
}
var styles = StyleSheet.create({
  backgroundVideo: {
    position: "absolute",
    top: 0,
    left: 0,
    bottom: 0,
    right: 0,
  },
});
Jepolo
  • 176
  • 5
0

I think you also could killed or paused the video when the component will be unmounted:

// Class component
componentWillUnmount() {
  videoRef.seek(0)
  this.setState({isPaused: true})
}

OR

// functional component
useEffect(() => {
    return () => {
       videoRef.current.seek(0)
       setIsPaused(true)
    }
}, [])

You also can use methods from react native navigation:

Call a function when focused screen changes

I hope it’ll help someone

Boopy
  • 309
  • 3
  • 5