mrousavy / react-native-vision-camera

📸 A powerful, high-performance React Native Camera library.
https://react-native-vision-camera.com
MIT License
7.66k stars 1.11k forks source link

❓ Crash on using camera multi times #1958

Closed vahidid closed 10 months ago

vahidid commented 1 year ago

Question

Hi I'm using react native vision camera for capturing video and scan QR codes. As I'm using camera in two different parts of my app, one as a selfie camera and other as the back camera, the first try for opening the camera works without any problem, but as soon as I click back and go for the second camera, the app crashes and i keep getting the error of "TOO_MANY_OPEN_CAMERAS". It seems that the first try for opening the camera does not stop when i close it. Can anyone help me with this problem? and the weird part is that it occurs on some devices in Android.

What I tried

No response

VisionCamera Version

3.3.1

Additional information

vahidid commented 1 year ago

I asked ChatGPT to fix my problem. ChatGPT offers me to update the following method in CameraView.kt:

override fun onDetachedFromWindow() {
    super.onDetachedFromWindow()
    cameraSession.close()
    updateLifecycle()
  }

I'm not sure that is a clean way to close camera when you want to use the back and front camera.

Also i opened a PR #1962

mrousavy commented 1 year ago

Hey, why did you open a question for this? This is clearly a bug report, you even have an error message.

I think I know what's happening here, but I believe this is by design on Android. You could fully unmount the <Camera> component when navigating away, but yea I can see that this is weird. Maybe your PR is a good solution, I need to think about this

vahidid commented 1 year ago

Hey, why did you open a question for this? This is clearly a bug report, you even have an error message.

I think I know what's happening here, but I believe this is by design on Android. You could fully unmount the <Camera> component when navigating away, but yea I can see that this is weird. Maybe your PR is a good solution, I need to think about this

Sorry i wasn't sure that is a bug but after a lot of exploring i found that the problem is in native codes. I'm not sure that is a good solution. I'm not a Kotlin developer.

mrousavy commented 1 year ago

Maybe this fixes your issue? https://github.com/mrousavy/react-native-vision-camera/pull/1972

myeongjae-kim commented 1 year ago

Maybe this fixes your issue? #1972

I encountered the same issue and #1972 have fixed it.

mrousavy commented 1 year ago

Awesome!

mlecoq commented 1 year ago

@mrousavy I have tried to patch vision-camera with #1972 but I have another crash

FATAL EXCEPTION: mrousavy/VisionCamera.main
Process: com.azzapp.azzapp_dev, PID: 7596
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:10871)
    at android.view.ViewRootImpl.requestTransparentRegion(ViewRootImpl.java:4455)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
    at android.view.SurfaceView.onAttachedToWindow(SurfaceView.java:368)
    at android.view.View.dispatchAttachedToWindow(View.java:22016)
    at android.view.ViewGroup.addViewInner(ViewGroup.java:6108)
    at android.view.ViewGroup.addView(ViewGroup.java:5884)
    at android.view.ViewGroup.addView(ViewGroup.java:5824)
    at android.view.ViewGroup.addView(ViewGroup.java:5796)
    at com.mrousavy.camera.CameraView.setupPreviewView(CameraView.kt:156)
mlecoq commented 1 year ago

or

FATAL EXCEPTION: mrousavy/VisionCamera.main
Process: com.azzapp.azzapp_dev, PID: 4368
android.hardware.camera2.CameraAccessException: CAMERA_ERROR (3): endConfigure:605: Camera 0: Error configuring streams: Broken pipe (-32)
    at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:1440)
    at android.hardware.camera2.impl.ICameraDeviceUserWrapper.endConfigure(ICameraDeviceUserWrapper.java:119)
    at android.hardware.camera2.impl.CameraDeviceImpl.configureStreamsChecked(CameraDeviceImpl.java:484)
    at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSessionInternal(CameraDeviceImpl.java:679)
    at android.hardware.camera2.impl.CameraDeviceImpl.createCaptureSession(CameraDeviceImpl.java:644)
    at com.mrousavy.camera.extensions.CameraDevice_createCaptureSessionKt.createCaptureSession(CameraDevice+createCaptureSession.kt:82)
    at com.mrousavy.camera.core.CameraSession.getCaptureSession(CameraSession.kt:438)
    at com.mrousavy.camera.core.CameraSession.startRunning(CameraSession.kt:532)
    at com.mrousavy.camera.core.CameraSession.access$startRunning(CameraSession.kt:49)
FATAL EXCEPTION: mrousavy/VisionCamera.main

Caused by: android.hardware.camera2.legacy.LegacyExceptionUtils$BufferQueueAbandonedException

FATAL EXCEPTION: mrousavy/VisionCamera.main
Process: com.azzapp.azzapp_dev, PID: 7479
java.lang.IllegalArgumentException: Surface was abandoned
    at android.hardware.camera2.utils.SurfaceUtils.getSurfaceSize(SurfaceUtils.java:86)
    at android.hardware.camera2.params.OutputConfiguration.<init>(OutputConfiguration.java:374)
    at android.hardware.camera2.params.OutputConfiguration.<init>(OutputConfiguration.java:146)
    at com.mrousavy.camera.core.outputs.SurfaceOutput.toOutputConfiguration(SurfaceOutput.kt:38)
    at com.mrousavy.camera.extensions.CameraDevice_createCaptureSessionKt.createCaptureSession(CameraDevice+createCaptureSession.kt:57)
fahmiabdulyakub commented 1 year ago

Maybe this fixes your issue? #1972

How to use this one ?

myeongjae-kim commented 1 year ago

Maybe this fixes your issue? #1972

How to use this one ?

@fahmiabdulyakub Try to use https://github.com/ds300/patch-package to patch libraries locally.

fahmiabdulyakub commented 1 year ago

Maybe this fixes your issue? #1972

How to use this one ?

@fahmiabdulyakub Try to use https://github.com/ds300/patch-package to patch libraries locally.

I've create the patch, but I get this error when I running project react-native-vision-camera+3.3.1.patch

react-native-vision-camera+3.3.1.patch

diff --git a/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraView.kt b/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraView.kt
index c4699c3..d68a805 100644
--- a/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraView.kt
+++ b/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraView.kt
@@ -13,7 +13,11 @@ import android.view.Surface
 import android.widget.FrameLayout
 import androidx.core.content.ContextCompat
 import com.facebook.react.bridge.ReadableMap
+import com.facebook.react.bridge.UiThreadUtil
+import com.mrousavy.camera.core.CameraPermissionError
+import com.mrousavy.camera.core.CameraQueues
 import com.mrousavy.camera.core.CameraSession
+import com.mrousavy.camera.core.NoCameraDeviceError
 import com.mrousavy.camera.core.PreviewView
 import com.mrousavy.camera.core.outputs.CameraOutputs
 import com.mrousavy.camera.extensions.bigger
@@ -28,8 +32,8 @@ import com.mrousavy.camera.parsers.PixelFormat
 import com.mrousavy.camera.parsers.ResizeMode
 import com.mrousavy.camera.parsers.Torch
 import com.mrousavy.camera.parsers.VideoStabilizationMode
+import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch

 //
@@ -42,7 +46,9 @@ import kotlinx.coroutines.launch
 // TODO: takePhoto() return with jsi::Value Image reference for faster capture

 @SuppressLint("ClickableViewAccessibility", "ViewConstructor", "MissingPermission")
-class CameraView(context: Context) : FrameLayout(context) {
+class CameraView(context: Context) :
+  FrameLayout(context),
+  CoroutineScope {
   companion object {
     const val TAG = "CameraView"

@@ -104,8 +110,11 @@ class CameraView(context: Context) : FrameLayout(context) {
   internal val outputOrientation: Orientation
     get() = orientation ?: inputOrientation

+  override val coroutineContext: CoroutineContext = CameraQueues.cameraQueue.coroutineDispatcher
+
   init {
     this.installHierarchyFitter()
+    clipToOutline = true
     setupPreviewView()
     cameraSession = CameraSession(context, cameraManager, { invokeOnInitialized() }, { error -> invokeOnError(error) })
   }
@@ -116,12 +125,12 @@ class CameraView(context: Context) : FrameLayout(context) {
       isMounted = true
       invokeOnViewReady()
     }
-    updateLifecycle()
+    launch { updateLifecycle() }
   }

   override fun onDetachedFromWindow() {
     super.onDetachedFromWindow()
-    updateLifecycle()
+    launch { updateLifecycle() }
   }

   private fun getPreviewTargetSize(): Size {
@@ -142,57 +151,62 @@ class CameraView(context: Context) : FrameLayout(context) {

     val previewView = PreviewView(context, this.getPreviewTargetSize(), resizeMode) { surface ->
       previewSurface = surface
-      configureSession()
+      launch { configureSession() }
     }
     previewView.layoutParams = LayoutParams(
       LayoutParams.MATCH_PARENT,
       LayoutParams.MATCH_PARENT,
       Gravity.CENTER
     )
-    addView(previewView)
     this.previewView = previewView
+    UiThreadUtil.runOnUiThread {
+      addView(previewView)
+    }
   }

   fun update(changedProps: ArrayList<String>) {
     Log.i(TAG, "Props changed: $changedProps")
-    try {
-      val shouldReconfigurePreview = changedProps.containsAny(propsThatRequirePreviewReconfiguration)
-      val shouldReconfigureSession = shouldReconfigurePreview || changedProps.containsAny(propsThatRequireSessionReconfiguration)
-      val shouldReconfigureFormat = shouldReconfigureSession || changedProps.containsAny(propsThatRequireFormatReconfiguration)
-      val shouldReconfigureZoom = shouldReconfigureSession || changedProps.contains("zoom")
-      val shouldReconfigureTorch = shouldReconfigureSession || changedProps.contains("torch")
-      val shouldCheckActive = shouldReconfigureFormat || changedProps.contains("isActive")
-      val shouldReconfigureZoomGesture = changedProps.contains("enableZoomGesture")
-
-      if (shouldReconfigurePreview) {
-        setupPreviewView()
-      }
-      if (shouldReconfigureSession) {
-        configureSession()
-      }
-      if (shouldReconfigureFormat) {
-        configureFormat()
-      }
-      if (shouldCheckActive) {
-        updateLifecycle()
-      }
-
-      if (shouldReconfigureZoom) {
-        updateZoom()
-      }
-      if (shouldReconfigureTorch) {
-        updateTorch()
-      }
-      if (shouldReconfigureZoomGesture) {
-        updateZoomGesture()
+    val shouldReconfigurePreview = changedProps.containsAny(propsThatRequirePreviewReconfiguration)
+    val shouldReconfigureSession = shouldReconfigurePreview || changedProps.containsAny(propsThatRequireSessionReconfiguration)
+    val shouldReconfigureFormat = shouldReconfigureSession || changedProps.containsAny(propsThatRequireFormatReconfiguration)
+    val shouldReconfigureZoom = shouldReconfigureSession || changedProps.contains("zoom")
+    val shouldReconfigureTorch = shouldReconfigureSession || changedProps.contains("torch")
+    val shouldCheckActive = shouldReconfigureFormat || changedProps.contains("isActive")
+    val shouldReconfigureZoomGesture = changedProps.contains("enableZoomGesture")
+
+    launch {
+      try {
+        // Expensive Calls
+        if (shouldReconfigurePreview) {
+          setupPreviewView()
+        }
+        if (shouldReconfigureSession) {
+          configureSession()
+        }
+        if (shouldReconfigureFormat) {
+          configureFormat()
+        }
+        if (shouldCheckActive) {
+          updateLifecycle()
+        }
+        // Fast Calls
+        if (shouldReconfigureZoom) {
+          updateZoom()
+        }
+        if (shouldReconfigureTorch) {
+          updateTorch()
+        }
+        if (shouldReconfigureZoomGesture) {
+          updateZoomGesture()
+        }
+      } catch (e: Throwable) {
+        Log.e(TAG, "update() threw: ${e.message}")
+        invokeOnError(e)
       }
-    } catch (e: Throwable) {
-      Log.e(TAG, "update() threw: ${e.message}")
-      invokeOnError(e)
     }
   }

-  private fun configureSession() {
+  private suspend fun configureSession() {
     try {
       Log.i(TAG, "Configuring Camera Device...")

@@ -236,22 +250,20 @@ class CameraView(context: Context) : FrameLayout(context) {
     }
   }

-  private fun configureFormat() {
+  private suspend fun configureFormat() {
     cameraSession.configureFormat(fps, videoStabilizationMode, hdr, lowLightBoost)
   }

-  private fun updateLifecycle() {
+  private suspend fun updateLifecycle() {
     cameraSession.setIsActive(isActive && isAttachedToWindow)
   }

-  private fun updateZoom() {
+  private suspend fun updateZoom() {
     cameraSession.setZoom(zoom)
   }

-  private fun updateTorch() {
-    CoroutineScope(Dispatchers.Default).launch {
-      cameraSession.setTorchMode(torch == Torch.ON)
-    }
+  private suspend fun updateTorch() {
+    cameraSession.setTorchMode(torch == Torch.ON)
   }

   @SuppressLint("ClickableViewAccessibility")
@@ -262,7 +274,7 @@ class CameraView(context: Context) : FrameLayout(context) {
         object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
           override fun onScale(detector: ScaleGestureDetector): Boolean {
             zoom *= detector.scaleFactor
-            cameraSession.setZoom(zoom)
+            launch { updateZoom() }
             return true
           }
         }
diff --git a/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt b/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt
index ff306e0..0be619f 100644
--- a/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt
+++ b/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt
@@ -16,15 +16,7 @@ import android.os.Build
 import android.util.Log
 import android.util.Range
 import android.util.Size
-import com.mrousavy.camera.CameraNotReadyError
-import com.mrousavy.camera.CameraQueues
 import com.mrousavy.camera.CameraView
-import com.mrousavy.camera.CaptureAbortedError
-import com.mrousavy.camera.NoRecordingInProgressError
-import com.mrousavy.camera.PhotoNotEnabledError
-import com.mrousavy.camera.RecorderError
-import com.mrousavy.camera.RecordingInProgressError
-import com.mrousavy.camera.VideoNotEnabledError
 import com.mrousavy.camera.core.outputs.CameraOutputs
 import com.mrousavy.camera.extensions.capture
 import com.mrousavy.camera.extensions.createCaptureSession
@@ -40,9 +32,6 @@ import com.mrousavy.camera.parsers.VideoFileType
 import com.mrousavy.camera.parsers.VideoStabilizationMode
 import java.io.Closeable
 import java.util.concurrent.CancellationException
-import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.launch
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock

@@ -52,7 +41,6 @@ class CameraSession(
   private val onInitialized: () -> Unit,
   private val onError: (e: Throwable) -> Unit
 ) : CameraManager.AvailabilityCallback(),
-  CoroutineScope,
   Closeable,
   CameraOutputs.Callback {
   companion object {
@@ -112,8 +100,6 @@ class CameraSession(
       updateVideoOutputs()
     }

-  override val coroutineContext: CoroutineContext = CameraQueues.cameraQueue.coroutineDispatcher
-
   init {
     cameraManager.registerAvailabilityCallback(this, CameraQueues.cameraQueue.handler)
   }
@@ -135,7 +121,7 @@ class CameraSession(
       return Orientation.fromRotationDegrees(sensorRotation)
     }

-  fun configureSession(
+  suspend fun configureSession(
     cameraId: String,
     preview: CameraOutputs.PreviewOutput? = null,
     photo: CameraOutputs.PhotoOutput? = null,
@@ -165,12 +151,10 @@ class CameraSession(
     updateVideoOutputs()

     this.cameraId = cameraId
-    launch {
-      startRunning()
-    }
+    startRunning()
   }

-  fun configureFormat(
+  suspend fun configureFormat(
     fps: Int? = null,
     videoStabilizationMode: VideoStabilizationMode? = null,
     hdr: Boolean? = null,
@@ -186,6 +170,7 @@ class CameraSession(
     val currentOutputs = outputs
     if (currentOutputs != null && currentOutputs.enableHdr != hdr) {
       // Update existing HDR for Outputs
+      this.outputs?.close()
       this.outputs = CameraOutputs(
         currentOutputs.cameraId,
         cameraManager,
@@ -198,29 +183,25 @@ class CameraSession(
       )
       needsReconfiguration = true
     }
-    launch {
-      if (needsReconfiguration) {
-        startRunning()
-      } else {
-        updateRepeatingRequest()
-      }
+    if (needsReconfiguration) {
+      startRunning()
+    } else {
+      updateRepeatingRequest()
     }
   }

   /**
    * Starts or stops the Camera.
    */
-  fun setIsActive(isActive: Boolean) {
+  suspend fun setIsActive(isActive: Boolean) {
     Log.i(TAG, "Setting isActive: $isActive (isRunning: $isRunning)")
     this.isActive = isActive
     if (isActive == isRunning) return

-    launch {
-      if (isActive) {
-        startRunning()
-      } else {
-        stopRunning()
-      }
+    if (isActive) {
+      startRunning()
+    } else {
+      stopRunning()
     }
   }

@@ -328,12 +309,10 @@ class CameraSession(
     }
   }

-  fun setZoom(zoom: Float) {
+  suspend fun setZoom(zoom: Float) {
     if (this.zoom != zoom) {
       this.zoom = zoom
-      launch {
-        updateRepeatingRequest()
-      }
+      updateRepeatingRequest()
     }
   }

@@ -503,6 +482,9 @@ class CameraSession(
     cameraDevice?.close()
     cameraDevice = null

+    outputs?.close()
+    outputs = null
+
     isRunning = false
   }

@@ -575,8 +557,9 @@ class CameraSession(
       val videoStabilizationMode = videoStabilizationMode
       val lowLightBoost = lowLightBoost
       val hdr = hdr
+      val enableTorch = enableTorch

-      val repeatingRequest = getPreviewCaptureRequest(fps, videoStabilizationMode, lowLightBoost, hdr)
+      val repeatingRequest = getPreviewCaptureRequest(fps, videoStabilizationMode, lowLightBoost, hdr, enableTorch)
       Log.d(TAG, "Setting Repeating Request..")
       session.setRepeatingRequest(repeatingRequest, null, null)
     }

Error

> Task :react-native-vision-camera:compileDebugKotlin FAILED

Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.

You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.

See https://docs.gradle.org/8.0.1/userguide/command_line_interface.html#sec:command_line_warnings
615 actionable tasks: 8 executed, 607 up-to-date

info 💡 Tip: Make sure that you have set up your development environment correctly, by running react-native doctor. To read more about doctor command visit: https://github.com/react-native-community/cli/blob/main/packages/cli-doctor/README.md#doctor 

e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraView.kt:17:33 Unresolved reference: CameraPermissionError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraView.kt:18:33 Unresolved reference: CameraQueues
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraView.kt:20:33 Unresolved reference: NoCameraDeviceError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:104:54 Unresolved reference: CameraQueues
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:222:50 Unresolved reference: CameraNotReadyError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:223:36 Unresolved reference: CameraNotReadyError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:225:52 Unresolved reference: PhotoNotEnabledError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:253:13 Unresolved reference: CaptureAbortedError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:268:22 Unresolved reference: RecorderError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:271:36 Unresolved reference: RecordingInProgressError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:272:38 Unresolved reference: CameraNotReadyError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:273:54 Unresolved reference: VideoNotEnabledError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:284:42 Unresolved reference: NoRecordingInProgressError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:293:42 Unresolved reference: NoRecordingInProgressError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:300:42 Unresolved reference: NoRecordingInProgressError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:320:50 Unresolved reference: CameraNotReadyError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:321:57 Unresolved reference: CameraNotReadyError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:345:52 Unresolved reference: CameraNotReadyError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:346:45 Unresolved reference: CameraNotReadyError
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:398:8 Unresolved reference: CameraQueues
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:426:8 Unresolved reference: CameraQueues
e: file:///Users/ReactNative/klikoov2/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/core/CameraSession.kt:443:50 Unresolved reference: CameraNotReadyError

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':react-native-vision-camera:compileDebugKotlin'.
> A failure occurred while executing org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction
   > Compilation error. See log for more details

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 36s
error Failed to install the app.
myeongjae-kim commented 1 year ago

@mrousavy This is a patch I created: react-native-vision-camera+3.3.1.patch. Try this one. I diffed it with your patch and It is slightly different with your patch.

fahmiabdulyakub commented 1 year ago

@mrousavy This is a patch I created: react-native-vision-camera+3.3.1.patch. Try this one. I diffed it with your patch and It is slightly different with your patch.

It's run but I get this crash after using your patch

FATAL EXCEPTION: mrousavy/VisionCamera.main
Process: com.pvp.klikoo.original, PID: 29126
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:11586)
    at android.view.ViewRootImpl.requestTransparentRegion(ViewRootImpl.java:5042)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:7668)
    at android.view.SurfaceView.onAttachedToWindow(SurfaceView.java:349)
    at android.view.View.dispatchAttachedToWindow(View.java:22479)
    at android.view.ViewGroup.addViewInner(ViewGroup.java:5520)
    at android.view.ViewGroup.addView(ViewGroup.java:5296)
    at android.view.ViewGroup.addView(ViewGroup.java:5236)
    at android.view.ViewGroup.addView(ViewGroup.java:5208)
    at com.mrousavy.camera.CameraView.setupPreviewView(CameraView.kt:156)
    at com.mrousavy.camera.CameraView.access$setupPreviewView(CameraView.kt:44)
    at com.mrousavy.camera.CameraView$update$1.invokeSuspend(CameraView.kt:174)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at android.os.Handler.handleCallback(Handler.java:942)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:226)
    at android.os.Looper.loop(Looper.java:313)
    at android.os.HandlerThread.run(HandlerThread.java:67)
    Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}@351dfa6, mrousavy/VisionCamera.main]
mrousavy commented 1 year ago

This has been fixed in the latest commit. I'll release this to npm later today

edritech93 commented 1 year ago

@mrousavy I have tried to patch vision-camera with #1972 but I have another crash

FATAL EXCEPTION: mrousavy/VisionCamera.main
Process: com.azzapp.azzapp_dev, PID: 7596
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
  at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:10871)
  at android.view.ViewRootImpl.requestTransparentRegion(ViewRootImpl.java:4455)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.ViewGroup.requestTransparentRegion(ViewGroup.java:8297)
  at android.view.SurfaceView.onAttachedToWindow(SurfaceView.java:368)
  at android.view.View.dispatchAttachedToWindow(View.java:22016)
  at android.view.ViewGroup.addViewInner(ViewGroup.java:6108)
  at android.view.ViewGroup.addView(ViewGroup.java:5884)
  at android.view.ViewGroup.addView(ViewGroup.java:5824)
  at android.view.ViewGroup.addView(ViewGroup.java:5796)
  at com.mrousavy.camera.CameraView.setupPreviewView(CameraView.kt:156)

same issue for me, I use Samsung A14 react-native 0.72.6 react-native-vision-camera 3.6.4 react-native-worklets-core 0.2.2

xseignard commented 1 year ago

Aaaaannd still happening with:

react-native 0.72.5
react-native-vision-camera 3.6.4
react-native-worklets-core 0.2.4
xseignard commented 1 year ago

~Looking at the code closely:~

~- First, look at CameraManager.openCamera: https://developer.android.com/reference/android/hardware/camera2/CameraManager#openCamera(java.lang.String,%20android.hardware.camera2.CameraDevice.StateCallback,%20android.os.Handler)~ ~- It throws a CameraAccessException: https://developer.android.com/reference/android/hardware/camera2/CameraAccessException~ ~- The CameraManager.openCamera extension (here) derives the thrown error with CameraDeviceError.fromCameraDeviceError~ ~- Looking at the code of CameraDeviceError.fromCameraDeviceError (here) you'll see it compares with CameraDevice.StateCallback and not with CameraAccessException~ ~- ERROR_MAX_CAMERAS_IN_USE has value 2, but the real value 2 we want is the one from CameraAccessException which corresponds to CAMERA_DISCONNECTED~

mrousavy commented 1 year ago

@xseignard wait what? That's weird - the Android documentation of the onError(.., code) method says that we need to compare to the CameraDevice.StateCallback.____ error codes:

image
mrousavy commented 1 year ago

Maybe ERROR_MAX_CAMERAS_IN_USE means we didn't properly close the previous camera before opening a new one? Not sure but I think the way we read the error here is correct, at least that's what the docs say.

xseignard commented 1 year ago

MMM, you're right, sorry for the confusion. That's weird they transform error codes in between the call to openCamera and the onError handler 🤔

I do reproduce the inital error navigating between 2 screens using a different camera (e.g. front and back)

dante-cervantes-rocketlab commented 1 year ago

im still getting this issue with latest version, any updates?

mrousavy commented 10 months ago

This is related to #2378 (new issue with logs)