Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unknown camera handling #1741

Open
alexsafe opened this issue Mar 8, 2025 · 3 comments
Open

Unknown camera handling #1741

alexsafe opened this issue Mar 8, 2025 · 3 comments

Comments

@alexsafe
Copy link

alexsafe commented Mar 8, 2025

Hi,

I think this may be a bug. If I get into a situation where the camera is not available this Exception happens:

java.lang.IllegalArgumentException: getCameraCharacteristics:857: Unable to retrieve camera characteristics for unknown device 163: No such file or directory (-2) at android.hardware.camera2.CameraManager.throwAsPublicException(CameraManager.java:1630) at android.hardware.camera2.CameraManager.getCameraCharacteristics(CameraManager.java:676) at android.hardware.camera2.CameraManager.getCameraCharacteristics(CameraManager.java:617) at com.pedro.encoder.input.video.Camera2ApiManager.getCameraCharacteristics(Camera2ApiManager.kt:265) at com.pedro.encoder.input.video.Camera2ApiManager.enableVideoStabilization(Camera2ApiManager.kt:307) at com.gpxstream2.app.pages.stream.implementations.CameraSource.start(CameraSource.kt:47)

I call it from this block

override fun start(surfaceTexture: SurfaceTexture) { this.surfaceTexture = surfaceTexture if (!isRunning()) { camera.closeCamera(false) try { camera.enableVideoStabilization() camera.enableOpticalVideoStabilization() camera.disableAutoExposure() camera.exposure = 1 surfaceTexture.setDefaultBufferSize(width, height) camera.prepareCamera(surfaceTexture, width, height, fps) camera.openLastCamera() } catch (e: CameraAccessException) { log.e("CameraAccessException: ${e.message}") e.printStackTrace() switchCamera(Cameras.BACK_CAMERA.id) } } }

To me it seems that the Exception thrown by

val cameraCharacteristics: CameraCharacteristics? get() { try { return cameraManager.getCameraCharacteristics(cameraId) } catch (e: Exception) { Log.e(TAG, "Error", e) return null } }

does not get transmitted.

For reproduction, probably setting the camera to 163 before a start() is triggered (if you don;t have an HDMI cam/port connected) should do the trick.

@pedroSG94
Copy link
Owner

Hello,

I will check it

@alexsafe
Copy link
Author

alexsafe commented Mar 11, 2025

Could be prevented with an isAvaiable() check. I did something like this:

fun isCameraAvailable(cameraId: String): Boolean {
        return try {
            val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
            val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId)
            val available = cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
            available != null
        } catch (e: CameraAccessException) {
            log.e("Camera not CameraAccessException: ${e.message}")
            false
        } catch (e: IllegalArgumentException) {
            log.e("Camera not IllegalArgumentException: ${e.message}")
            false
        }
    }

I added it in my own implementation of VideoSource() . Maybe it can be useful in Camera2ApiManager?

@pedroSG94
Copy link
Owner

pedroSG94 commented Mar 11, 2025

Hello,

Instead of use that method you already have this method:
https://github.com/pedroSG94/RootEncoder/blob/master/encoder/src/main/java/com/pedro/encoder/input/sources/video/Camera2Source.kt#L175

Also, I tried to reproduce the error. All methods is working as expected, returning false if fail to do and the camera callback return the camera open error properly.
For example:

  override fun start(surfaceTexture: SurfaceTexture) {
    this.surfaceTexture = surfaceTexture
    if (!isRunning()) {
        camera.closeCamera(false)
        try {
            camera.setCameraId("163")
//print false as expected when fail
            Log.e("Pedro", "VideoStabilization: ${camera.enableVideoStabilization()}")
//print false as expected when fail
            Log.e("Pedro", "OpticalVideoStabilization: ${camera.enableOpticalVideoStabilization()}")
            camera.disableAutoExposure()
            camera.exposure = 1
            surfaceTexture.setDefaultBufferSize(width, height)
            camera.prepareCamera(surfaceTexture, width, height, fps)
//return camera open error properly
            camera.setCameraCallbacks(object: CameraCallbacks{
              override fun onCameraChanged(facing: CameraHelper.Facing) {
              }

              override fun onCameraError(error: String) {
                Log.e("Pedro","CameraAccessException: $error")
              }

              override fun onCameraOpened() {
              }

              override fun onCameraDisconnected() {
              }

            })
            camera.openLastCamera()
        } catch (e: CameraAccessException) {
            Log.e("Pedro","CameraAccessException: ${e.message}")
            e.printStackTrace()
            switchCamera()
        }
    }
  }

How to fix:

            val id = "163"
            val validId = camera.camerasAvailable.find { it == id }
            if (validId != null) {
              camera.setCameraId(validId)
            } else {
              switchCamera() //use front or back or any available camera
            }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants