React Native Expo Camera - ошибка инвариантного нарушения при попытке запустить камеру - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь запустить следующий код, получив сообщение об ошибке инвариантного нарушения:

import React, { Component } from "react";

import { View, Text, TouchableOpacity } from "react-native";

import { Camera, MediaLibrary } from "expo";

import * as Permissions from 'expo-permissions';

class MyCam extends Component {

  state = {

    video: null,

    picture: null,

    recording: false

  };

  _saveVideo = async () => {

    const { video } = this.state;

    const asset = await MediaLibrary.createAssetAsync(video.uri);

    if (asset) {

      this.setState({ video: null });

    }

  };

  _StopRecord = async () => {

    this.setState({ recording: false }, () => {

      this.cam.stopRecording();

    });

  };

  _StartRecord = async () => {

    if (this.cam) {

      this.setState({ recording: true }, async () => {

        const video = await this.cam.recordAsync();

        this.setState({ video });

      });

    }

  };

  toogleRecord = () => {

    const { recording } = this.state;

    if (recording) {

      this._StopRecord();

    } else {

      this._StartRecord();

    }

  };

  render() {

    const { recording, video } = this.state;

    return (

      <Camera

        ref={cam => (this.cam = cam)}

        style={{

          justifyContent: "flex-end",

          alignItems: "center",

          flex: 1,

          width: "100%"

        }}

      >

        {video && (

          <TouchableOpacity

            onPress={this._saveVideo}

            style={{

              padding: 20,

              width: "100%",

              backgroundColor: "#fff"

            }}

          >

            <Text style={{ textAlign: "center" }}>save</Text>

          </TouchableOpacity>

        )}

        <TouchableOpacity

          onPress={this.toogleRecord}

          style={{

            padding: 20,

            width: "100%",

            backgroundColor: recording ? "#ef4f84" : "#4fef97"

          }}

        >

          <Text style={{ textAlign: "center" }}>

            {recording ? "Stop" : "Record"}

          </Text>

        </TouchableOpacity>

      </Camera>

    );

  }

}

class RecVideo extends Component {

  state = {

    showCamera: false

  };

  _showCamera = async () => {

    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);

    if (status === "granted") {

      this.setState({ showCamera: true });

    }

  };

  render() {

    const { showCamera } = this.state;

    return (

      <View

        style={{

          justifyContent: "center",

          alignItems: "center",

          flex: 1,

          width: "100%"

        }}

      >

        {showCamera ? (

          <MyCam />

        ) : (

          <TouchableOpacity onPress={this._showCamera}>

            <Text> Show Camera </Text>

          </TouchableOpacity>

        )}

      </View>

    );

  }

}

export default RecVideo;

Это ошибка: Нарушение инварианта

Invariant Violation

Я нашел этот фрагмент кода здесь: https://forums.expo.io/t/how-to-record-video/18834

Я только внес изменения в то, как импортируются разрешения, но остальное то же самое. Я предполагаю, что ошибка связана с импортом, так как это то, что я нашел в Интернете, но я не знаю, как это исправить, потому что все кажется правильным.

1 Ответ

0 голосов
/ 15 февраля 2020
import React from 'react';
import { Text, View, TouchableOpacity,Vibration } from 'react-native';
import * as Permissions from 'expo-permissions';
import { Camera } from 'expo-camera';
import { AsyncStorage } from 'react-native';
import { ToastAndroid } from 'react-native';
import { widthPercentageToDP as wp, heightPercentageToDP as hp } from 'react-native-responsive-screen';
const PATTERN = [1000, 2000, 3000];
export default class OpenCamera extends React.Component {
    state = {
        hasCameraPermission: null,
        type: Camera.Constants.Type.back,
    };

    async componentDidMount() {
        const { status } = await Permissions.askAsync(Permissions.CAMERA);
        this.setState({ hasCameraPermission: status === 'granted' });
    }


    // get the uri;
    async clicked1() {
         Vibration.vibrate(PATTERN)
        if (this.camera) {
            let photo = await this.camera.takePictureAsync();
            console.log('array>>',photo)
            console.log('image path>>>>>>>', photo.uri)
            await AsyncStorage.setItem('image_path_key', photo.uri);
            if(photo.uri!=null){
                this.props._changeCameraVisbilty(false);
                this.props._setImageData(photo.uri)
            // this.props.navigation.goBack()
            }else{
    ToastAndroid.show('There some problem to taking a photo,please try again', ToastAndroid.SHORT);
}

        }
    };


// _closeCamera=()=>{

// }


// get the photo
async snapPhoto() {       
    console.log('Button Pressed');
    if (this.camera) {
       console.log('Taking photo');
       const options = { quality: 1, base64: true, fixOrientation: true, 
       exif: true};
       await this.camera.takePictureAsync(options).then(photo => {
          photo.exif.Orientation = 1;            
           console.log(photo);            
           });     
     }
    }

    render() {
        //const { navigate } = this.props.navigation;
        const { hasCameraPermission } = this.state;
        if (hasCameraPermission === null) {
            return <View />;
        } else if (hasCameraPermission === false) {
            return <Text>No access to camera</Text>;
        } else {
            return (
                <View style={{ flex: 1 }}>
                    <Camera style={{ flex: 1 }}  
                     ref={ (ref) => {this.camera = ref} }
                      type={this.state.type}  >

                        <View
                            style={{
                                flex: 1,
                                backgroundColor: 'transparent',
                                flexDirection: 'row',
                            }}>
                            <TouchableOpacity
                                style={{
                                    flex: 0.1,
                                    alignSelf: 'flex-end',
                                    alignItems: 'center',
                                }}
                                onPress={() => {
                                    this.setState({
                                        type:
                                            this.state.type === Camera.Constants.Type.back
                                                ? Camera.Constants.Type.front
                                                : Camera.Constants.Type.back,

                                    });
                                }}>
                                <Text style={{ fontSize: 18, marginBottom: 10, color: 'white' }}> Flip </Text>
                            </TouchableOpacity>
                        </View>
                    </Camera>

                    <View style={{flexDirection:'row',alignItems:'center',justifyContent:'center'}}>

<TouchableOpacity
    onPress={this.clicked1.bind(this)} >
    <Text style={{fontSize:hp('3%'),marginTop:hp('2.3%'),marginBottom:hp('2.3%')}}>Take photo</Text>
</TouchableOpacity>

</View>

                </View>
            );
        }
    }
}

Открыть пользовательский код камеры

...