为什么 CameraX.bindToLifecycle 在 1.0.0-alpha05 中不支持三例?
Why doesn't CameraX.bindToLifecycle support three cases in 1.0.0-alpha05?
正在学习CameraXAPI,CameraXBasic是office示例代码
代码A基于CameraFragment.kt
我添加 videoCaptureConfig
,并使用 CameraX.bindToLifecycle(viewLifecycleOwner, preview, imageCapture,videoCapture).
将其绑定到生命周期
但是我得到以下错误,为什么?
java.lang.IllegalArgumentException:未找到相机设备支持的表面组合 - ID:0。可能试图绑定太多用例。
代码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)
}
您尝试向同一个摄像头会话添加太多用例。你可以检查这个 github-issue about that. For understand limitations of camera sessions you can check documentation.
您可以尝试在切换到视频之前解绑所有用例(我注意到仅解绑 imageCapture 用例时旧手机会崩溃):
// Listener for button photo
btnPhoto.setOnClickListener( v -> bindCameraUseCases(0));
// Listener for button video
btnVideo.setOnClickListener( v -> bindCameraUseCases(1));
示例 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);
}
}
示例 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);
}
}
正在学习CameraXAPI,CameraXBasic是office示例代码
代码A基于CameraFragment.kt
我添加 videoCaptureConfig
,并使用 CameraX.bindToLifecycle(viewLifecycleOwner, preview, imageCapture,videoCapture).
但是我得到以下错误,为什么?
java.lang.IllegalArgumentException:未找到相机设备支持的表面组合 - ID:0。可能试图绑定太多用例。
代码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)
}
您尝试向同一个摄像头会话添加太多用例。你可以检查这个 github-issue about that. For understand limitations of camera sessions you can check documentation.
您可以尝试在切换到视频之前解绑所有用例(我注意到仅解绑 imageCapture 用例时旧手机会崩溃):
// Listener for button photo
btnPhoto.setOnClickListener( v -> bindCameraUseCases(0));
// Listener for button video
btnVideo.setOnClickListener( v -> bindCameraUseCases(1));
示例 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);
}
}
示例 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);
}
}