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)
}
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With