skip to Main Content

I hope you’re doing well. I am facing a peculiar issue in my React Native application related to camera integration. Here’s a detailed explanation of the problem I am facing:

Problem Description:
I am building a video recording app using React Native, where users can switch between front and back cameras. However, I am encountering a problem where the camera doesn’t show up properly on the screen under certain conditions.

Here are the specifics of the issue:

  1. Camera Initialization: The camera doesn’t show up when the app is opened, especially on the initial load. It only starts working when I forcefully re-render the component (e.g., minimizing the app and reopening it).

2.Key Method: I have attempted using the key property to force re-render the camera component, but it didn’t fully resolve the problem.

Additional Information:

  • Camera Package: I am using react-native-vision-camera for camera integration.
  • Permissions: Camera and microphone permissions have been granted and logged correctly.
  • Testing: I have tried different methods, including using the key property, but the issue persists.
  • Package Versions:

{ "@react-native-camera-roll/camera-roll": "^6.0.0", "react": "18.2.0", "react-native": "0.72.6", "react-native-vector-icons": "^10.0.0", "react-native-video": "^5.2.1", "react-native-vision-camera": "^3.6.4" }

Relevant Code:

import React, { useState, useEffect, useRef } from 'react';
import { View, TouchableOpacity, Text, StyleSheet } from 'react-native';
import { Camera, useCameraDevice } from 'react-native-vision-camera';
import Icon from 'react-native-vector-icons/Ionicons';

function App() {
  const [isLoading, setIsLoading] = useState(true);
  const [isRecording, setIsRecording] = useState(false);
  // ... (other state variables and functions)

  useEffect(() => {
    async function getPermissions() {
      // Request camera and microphone permissions
      const cameraPermission = await Camera.requestCameraPermission();
      const microphonePermission = await Camera.requestMicrophonePermission();
      // Handle permissions and loading state
    }
    getPermissions();
  }, []);

  const device = useCameraDevice(/* specify front or back camera */);
  const camera = useRef(null);

  return (
    <View style={{ flex: 1 }}>
      {/* Camera component */}
      <Camera style={StyleSheet.absoluteFill} ref={camera} device={device} isActive={true} video={true} audio={true} videoQuality="1080p" />
      {/* UI elements */}
      {isRecording ? /* Show recording timer */ : null}
      {!isFrontCamera && !isRecording ? /* Toggle flash button */ : null}
      {/* Other UI elements and functionalities */}
    </View>
  );
}

export default App;

2

Answers


  1. This code is working for me please try with this example

    import React, {useEffect, useState, useRef} from 'react';
    import {
      View,
      StyleSheet,
      Button,
      TouchableOpacity,
      Text,
      Linking,
      Image,
    } from 'react-native';
    import {Camera, useCameraDevices} from 'react-native-vision-camera';
    
    function App() {
      const camera = useRef(null);
      const devices = useCameraDevices();
      const device = devices.back;
    
      const [showCamera, setShowCamera] = useState(false);
      const [imageSource, setImageSource] = useState('');
    
      useEffect(() => {
        async function getPermission() {
          const newCameraPermission = await Camera.requestCameraPermission();
          console.log(newCameraPermission);
        }
        getPermission();
      }, []);
    
      const capturePhoto = async () => {
        if (camera.current !== null) {
          const photo = await camera.current.takePhoto({});
          setImageSource(photo.path);
          setShowCamera(false);
          console.log(photo.path);
        }
      };
    
      if (device == null) {
        return <Text>Camera not available</Text>;
      }
    
      return (
        <View style={styles.container}>
          {showCamera ? (
            <>
              <Camera
                ref={camera}
                style={StyleSheet.absoluteFill}
                device={device}
                isActive={showCamera}
                photo={true}
              />
    
              <View style={styles.buttonContainer}>
                <TouchableOpacity
                  style={styles.camButton}
                  onPress={() => capturePhoto()}
                />
              </View>
            </>
          ) : (
            <>
              {imageSource !== '' ? (
                <Image
                  style={styles.image}
                  source={{
                    uri: `file://'${imageSource}`,
                  }}
                />
              ) : null}
    
              <View style={styles.backButton}>
                <TouchableOpacity
                  style={{
                    backgroundColor: 'rgba(0,0,0,0.2)',
                    padding: 10,
                    justifyContent: 'center',
                    alignItems: 'center',
                    borderRadius: 10,
                    borderWidth: 2,
                    borderColor: '#fff',
                    width: 100,
                  }}
                  onPress={() => setShowCamera(true)}>
                  <Text style={{color: 'white', fontWeight: '500'}}>Back</Text>
                </TouchableOpacity>
              </View>
              <View style={styles.buttonContainer}>
                <View style={styles.buttons}>
                  <TouchableOpacity
                    style={{
                      backgroundColor: '#fff',
                      padding: 10,
                      justifyContent: 'center',
                      alignItems: 'center',
                      borderRadius: 10,
                      borderWidth: 2,
                      borderColor: '#77c3ec',
                    }}
                    onPress={() => setShowCamera(true)}>
                    <Text style={{color: '#77c3ec', fontWeight: '500'}}>
                      Retake
                    </Text>
                  </TouchableOpacity>
                  <TouchableOpacity
                    style={{
                      backgroundColor: '#77c3ec',
                      padding: 10,
                      justifyContent: 'center',
                      alignItems: 'center',
                      borderRadius: 10,
                      borderWidth: 2,
                      borderColor: 'white',
                    }}
                    onPress={() => setShowCamera(true)}>
                    <Text style={{color: 'white', fontWeight: '500'}}>
                      Use Photo
                    </Text>
                  </TouchableOpacity>
                </View>
              </View>
            </>
          )}
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      },
      button: {
        backgroundColor: 'gray',
      },
      backButton: {
        backgroundColor: 'rgba(0,0,0,0.0)',
        position: 'absolute',
        justifyContent: 'center',
        width: '100%',
        top: 0,
        padding: 20,
      },
      buttonContainer: {
        backgroundColor: 'rgba(0,0,0,0.2)',
        position: 'absolute',
        justifyContent: 'center',
        alignItems: 'center',
        width: '100%',
        bottom: 0,
        padding: 20,
      },
      buttons: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        width: '100%',
      },
      camButton: {
        height: 80,
        width: 80,
        borderRadius: 40,
        //ADD backgroundColor COLOR GREY
        backgroundColor: '#B2BEB5',
    
        alignSelf: 'center',
        borderWidth: 4,
        borderColor: 'white',
      },
      image: {
        width: '100%',
        height: '100%',
        aspectRatio: 9 / 16,
      },
    });
    

    export default App;

    Login or Signup to reply.
  2. As the example of react-native-vision-camera‘s docs, you should check if camera avaiable before rendering:

    const device = useCameraDevice('back')
    
    if (device == null) return <NoCameraErrorView />
    
    return (
      <Camera
        style={StyleSheet.absoluteFill}
        device={device}
        isActive={true}
      />
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search