Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't CameraX.bindToLifecycle support three cases in 1.0.0-alpha05?

I'm learning CameraX API, and CameraXBasic is a office sample code.

The Code A is based CameraFragment.kt

I add videoCaptureConfig, and bind it to lifecycle using CameraX.bindToLifecycle(viewLifecycleOwner, preview, imageCapture,videoCapture).

But I get the following error, why?

java.lang.IllegalArgumentException: No supported surface combination is found for camera device - Id : 0. May be attempting to bind too many use cases.

Code A

@SuppressLint("RestrictedApi")
private fun bindCameraUseCases() {

    // Get screen metrics used to setup camera for full screen resolution
    val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
    val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)

    // Set up the view finder use case to display camera preview
    val viewFinderConfig = PreviewConfig.Builder().apply {
        setLensFacing(lensFacing)
        // We request aspect ratio but no resolution to let CameraX optimize our use cases
        setTargetAspectRatio(screenAspectRatio)
        // Set initial target rotation, we will have to call this again if rotation changes
        // during the lifecycle of this use case
        setTargetRotation(viewFinder.display.rotation)
    }.build()

    // Use the auto-fit preview builder to automatically handle size and orientation changes
    preview = AutoFitPreviewBuilder.build(viewFinderConfig, viewFinder)


    // Set up the capture use case to allow users to take photos
    val imageCaptureConfig = ImageCaptureConfig.Builder().apply {
        setLensFacing(lensFacing)
        setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY)
        // We request aspect ratio but no resolution to match preview config but letting
        // CameraX optimize for whatever specific resolution best fits requested capture mode
        setTargetAspectRatio(screenAspectRatio)
        // Set initial target rotation, we will have to call this again if rotation changes
        // during the lifecycle of this use case
        setTargetRotation(viewFinder.display.rotation)
    }.build()

    imageCapture = ImageCapture(imageCaptureConfig)


    // Create a configuration object for the video use case
    val videoCaptureConfig = VideoCaptureConfig.Builder().apply {
        setTargetRotation(viewFinder.display.rotation)
        setTargetAspectRatio(screenAspectRatio)
        setLensFacing(lensFacing)
    }.build()
    videoCapture = VideoCapture(videoCaptureConfig)


    CameraX.bindToLifecycle(viewLifecycleOwner, preview, imageCapture,videoCapture)
}
like image 327
HelloCW Avatar asked Sep 18 '25 04:09

HelloCW


1 Answers

You can try to unbind all use cases before to switch to video ( I noticed some crash with old phones when unbinding only the imageCapture use case):

// Listener for button photo
btnPhoto.setOnClickListener( v -> bindCameraUseCases(0));
// Listener for button video
btnVideo.setOnClickListener( v -> bindCameraUseCases(1));

Example with camerax_version = "1.0.0-alpha06" (JAVA)

@SuppressLint("RestrictedApi")
private void bindCameraUseCases(int captureMode) {
    CameraX.unbindAll();

    AspectRatio screenAspectRatio = AspectRatio.RATIO_4_3;

    // Set up the preview use case to display camera preview
    PreviewConfig.Builder previewConfigBuilder = new PreviewConfig.Builder();
    previewConfigBuilder.setLensFacing(lensFacing);
    previewConfigBuilder.setTargetRotation(viewFinder.getDisplay().getRotation());
    previewConfigBuilder.setTargetAspectRatio(screenAspectRatio);
    Preview preview = new Preview(previewConfigBuilder.build());

    preview.setOnPreviewOutputUpdateListener(previewOutput -> {
        ViewGroup parent = (ViewGroup) viewFinder.getParent();
        parent.removeView(viewFinder);
        parent.addView(viewFinder,0);
        viewFinder.setSurfaceTexture(previewOutput.getSurfaceTexture());
    });

    if(captureMode == 0){ // IMAGE
        videoCapture = null;
        // Set up the capture use case to allow users to take photos
        ImageCaptureConfig.Builder imageCaptureConfigBuilder = new ImageCaptureConfig.Builder();
        imageCaptureConfigBuilder.setLensFacing(lensFacing);
        imageCaptureConfigBuilder.setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY);
        imageCaptureConfigBuilder.setTargetRotation(viewFinder.getDisplay().getRotation());
        imageCapture = new ImageCapture(imageCaptureConfigBuilder.build());

        // Apply declared configs to CameraX using the same lifecycle owner
        CameraX.bindToLifecycle(this, preview, imageCapture);
    }else{ // VIDEO
        imageCapture = null;
        // Set up the video capture use case to allow users to take videos
        VideoCaptureConfig.Builder videoCaptureConfigBuilder = new VideoCaptureConfig.Builder();
        videoCaptureConfigBuilder.setLensFacing(lensFacing);
        videoCaptureConfigBuilder.setTargetAspectRatio(screenAspectRatio);
        videoCaptureConfigBuilder.setTargetRotation(viewFinder.getDisplay().getRotation());
        videoCapture = new VideoCapture(videoCaptureConfigBuilder.build());

        // Apply declared configs to CameraX using the same lifecycle owner
        CameraX.bindToLifecycle(this, preview, videoCapture);
    }
}

Example with camerax_version = "1.0.0-alpha07" (JAVA)

@SuppressLint("RestrictedApi")
private void bindCameraUseCases(int captureMode) {
    if(cameraProvider != null) cameraProvider.unbindAll();

    // Set up the preview use case to display camera preview
    Preview preview = new Preview.Builder()
            .setTargetAspectRatio(AspectRatio.RATIO_4_3)
            .setTargetRotation(previewView.getDisplay().getRotation())
            .build();

    preview.setPreviewSurfaceProvider(previewView.getPreviewSurfaceProvider());

    if(captureMode == 0){ // IMAGE
        videoCapture = null;
        // Set up the capture use case to allow users to take photos
        imageCapture = new ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CaptureMode.MINIMIZE_LATENCY)
                .setTargetRotation(previewView.getDisplay().getRotation())
                .build();

        // Apply declared configs using the same lifecycle owner
        cameraProvider.bindToLifecycle(this,cameraSelector, preview, imageCapture);
    }else{ // VIDEO
        imageCapture = null;
        // Set up the video capture use case to allow users to take videos
        VideoCaptureConfig.Builder videoCaptureConfigBuilder = new VideoCaptureConfig.Builder();
        videoCaptureConfigBuilder.setTargetAspectRatio(AspectRatio.RATIO_4_3);
        videoCaptureConfigBuilder.setTargetRotation(previewView.getDisplay().getRotation());
        videoCapture = new VideoCapture(videoCaptureConfigBuilder.getUseCaseConfig());

        // Apply declared configs using the same lifecycle owner
        cameraProvider.bindToLifecycle(this, cameraSelector,preview, videoCapture);
    }
}
like image 62
LaurentP22 Avatar answered Sep 20 '25 21:09

LaurentP22