react-native-vision-camera icon indicating copy to clipboard operation
react-native-vision-camera copied to clipboard

🐛 Taking a photo throws `[session/recoverable-error]: An unknown error occurred while creating the Camera Session, but the Camera can recover from it`

Open brunosp-49 opened this issue 1 year ago • 1 comments

What's happening?

Hi guys, I'm having some problems to take pictures using react-native-vision-camera, the video works just fine, but when I try to take some picture, i just give an error "Camera.onError(session/recoverable-error): An unknown error occurred while creating the Camera Session, but the Camera can recover from it.", I do not know why, I tried to add the property onInitialized, to just let the camera take photo when it is ready, but then it never send the asnwer, I'm trying to findo the solution for days, that is my code:

Reproduceable Code

import React, { FC, useEffect, useRef, useState } from 'react';
import { Modal, StyleSheet, View } from 'react-native';
import { Camera, useCameraDevice, useCameraPermission, useMicrophonePermission } from 'react-native-vision-camera';
import { VideoButton } from './components/videoButton';
import { PhotoButton } from './components/photoButton';
import { ModeSwitch } from './components/modeSwitch';
import { CloseButton } from './components/closeButton';
import VideoOrImage from '../inputFom/diplay/vieoOrImage';

interface Props {
    isVisible: boolean;
    onClose: () => void;
}

export const CameraComponent: FC<Props> = ({ isVisible, onClose }) => {
    const device = useCameraDevice('back');
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { hasPermission, requestPermission } = useCameraPermission();
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    const { hasPermission: hasMicPermission, requestPermission: requestMicPermission } = useMicrophonePermission();
    const [permission, setPermission] = useState<null | boolean>(null);
    const [cameraMode, setCameraMode] = useState<1 | 2>(1);
    const [isRecording, setIsRecording] = useState(false);
    const [preview, setPreview] = useState(false);
    const [uriPreview, setUriPreview] = useState<string | undefined>();
    // const [flashIsActive, setFlashIsActive] = useState(false);

    const cameraRef = useRef<Camera>(null);

    const startRecording = () => {
        if (!cameraRef.current || !device) { return; }
        setIsRecording(true);

        cameraRef.current.startRecording({
            videoCodec: 'h265',
            fileType: 'mp4',
            videoBitRate: 'normal',
            onRecordingFinished: (video) => {
                setUriPreview(video.path);
                setPreview(true);
            },
            onRecordingError: (error) => {
                console.log(error);
            },
        });
    };

    const stopRecording = async () => {
        if (!cameraRef.current || !device) { return; }
        await cameraRef.current.stopRecording();
        setIsRecording(false);
    };

    const takePhoto = async () => {
        if (!cameraRef.current || !device) { return; }
        const photo = await cameraRef.current.takePhoto();
        setUriPreview(photo.path);
        setPreview(true);
    };

    useEffect(() => {
        (async () => {
            const status = await requestPermission();
            const statusMic = await requestMicPermission();

            if (status && statusMic) {
                setPermission(true);
            }
        })();
    }, []);

    return (
        <Modal visible={isVisible} statusBarTranslucent>
            <View style={[StyleSheet.absoluteFill, styles.cameraContainer]}>
                {permission && device && !preview ? (
                    <>
                        <>
                            {cameraMode === 1
                                ?
                                (
                                    <Camera
                                        ref={cameraRef}
                                        device={device}
                                        isActive={isVisible && !preview && cameraMode === 1}
                                        photo
                                        style={StyleSheet.absoluteFill}
                                        orientation="portrait"
                                        resizeMode="cover"
                                    />
                                )
                                :
                                (
                                    <Camera
                                        ref={cameraRef}
                                        device={device}
                                        isActive={isVisible && !preview  && cameraMode === 2}
                                        video
                                        audio
                                        style={StyleSheet.absoluteFill}
                                        orientation="portrait"
                                        resizeMode="cover"
                                    />
                                )
                            }
                        </>
                        {cameraMode === 2
                            ?
                            (<VideoButton isRecording={isRecording} onStartRecording={startRecording} onStopRecording={stopRecording} />)
                            :
                            (<PhotoButton onPress={takePhoto} />)
                        }
                        <ModeSwitch onChange={(e: 1 | 2) => setCameraMode(e)} state={cameraMode} />
                        <CloseButton onPress={onClose} />
                    </>
                )
                    :
                    <VideoOrImage type={cameraMode === 2 ? 'video' : 'image'} uri={uriPreview} fullScreen goBackVideo={() => setPreview(false)} />}
            </View>
        </Modal>
    );
};


const styles = StyleSheet.create({
    cameraContainer: {
        backgroundColor: 'black',
    },
});

Relevant log output

ERROR  Camera.onError(session/recoverable-error): An unknown error occurred while creating the Camera Session, but the Camera can recover from it. [session/recoverable-error: An unknown error occurred while creating the Camera Session, but the Camera can recover from it.]
 LOG  true
 LOG  false
 WARN  Possible Unhandled Promise Rejection (id: 0):
unknown/unknown: Camera is closed.
[unknown/unknown]: Camera is closed.
    at construct (native)
    at Wrapper (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:19628:64)
    at construct (native)
    at _createSuperInternal (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:149303:322)
    at call (native)
    at CameraError (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:149311:26)
    at construct (native)
    at _createSuperInternal (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:149303:322)
    at apply (native)
    at CameraRuntimeError (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:149358:27)
    at tryParseNativeCameraError (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:149373:38)
    at ?anon_0_ (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:148925:98)
    at throw (native)
    at asyncGeneratorStep (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:20664:26)
    at _throw (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:20686:29)
    at tryCallOne (/root/react-native/ReactAndroid/hermes-engine/.cxx/Release/4b1t586k/x86_64/lib/InternalBytecode/InternalBytecode.js:53:16)
    at anonymous (/root/react-native/ReactAndroid/hermes-engine/.cxx/Release/4b1t586k/x86_64/lib/InternalBytecode/InternalBytecode.js:139:27)
    at apply (native)
    at anonymous (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:26222:26)
    at _callTimer (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:26141:17)
    at _callReactNativeMicrotasksPass (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:26171:17)
    at callReactNativeMicrotasks (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:26334:44)
    at __callReactNativeMicrotasks (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:2403:46)
    at anonymous (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:2215:45)
    at __guard (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:2387:15)
    at flushedQueue (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:2214:21)
    at invokeCallbackAndReturnFlushedQueue (http://localhost:8081/index.bundle//&platform=android&dev=true&minify=false&app=com.tech_gym_coach&modulesOnly=false&runModule=true:2208:33)
 LOG  true
 LOG  false
 MAP  ./index.js

 MAP  src\components\cameraComponent/index.tsx

 ERROR  Camera.onError(session/recoverable-error): An unknown error occurred while creating the Camera Session, but the Camera can recover from it. [session/recoverable-error: An unknown error occurred while creating the Camera Session, but the Camera can recover from it.]

Camera Device

{
  "formats": [],
  "sensorOrientation": "landscape-left",
  "hardwareLevel": "limited",
  "maxZoom": 10,
  "minZoom": 1,
  "maxExposure": 9,
  "supportsLowLightBoost": false,
  "neutralZoom": 1,
  "physicalDevices": [
    "telephoto-camera"
  ],
  "supportsFocus": true,
  "supportsRawCapture": false,
  "isMultiCam": false,
  "minFocusDistance": 0,
  "minExposure": -9,
  "name": "0 (BACK) androidx.camera.camera2",
  "hasFlash": false,
  "hasTorch": false,
  "position": "back",
  "id": "0"
}

Device

Pixel 6

VisionCamera Version

4.0.3

Can you reproduce this issue in the VisionCamera Example app?

No, I cannot reproduce the issue in the Example app

Additional information

brunosp-49 avatar May 17 '24 07:05 brunosp-49

I am also facing this issue with XIaoMi MIX 2S(Android 10) with props video=true, with video=false it`s ok

moi-xiey avatar May 17 '24 12:05 moi-xiey

Try to set photoQualityBalance="quality" or "speed"

mrousavy avatar May 21 '24 15:05 mrousavy

Hey - just created a PR to temporarily fix this - can you test if that works for you? https://github.com/mrousavy/react-native-vision-camera/pull/2897 🙏

mrousavy avatar May 21 '24 15:05 mrousavy

Ok I'm gonna try, just a second

brunosp-49 avatar May 21 '24 17:05 brunosp-49

Try to set photoQualityBalance="quality" or "speed"

Works for me!

"react-native": "0.73.6", "react-native-vision-camera": "^4.0.3"

const myCameraScreen()=>{
// ... more code
  const devices = useCameraDevices();
  const device = devices.find(dvc => dvc.position === 'front');
  const format = useCameraFormat(device, [{ photoResolution: 'max' }]);
//... more code
return(
<Camera
          ref={cameraRef}
          onInitialized={() => console.log('Camera is ready!')}
          device={device}
          isActive={true}
          photoQualityBalance="quality"
          style={styles.camera}
          photo
        />
)
}