重新绑定 CameraX 用例

Rebinding CameraX UseCases

我正在尝试 stop/pause 相机 PreviewView 在图像 processing/detection 期间使用 Firebase MLKit。要暂停预览,我调用

cameraProvider.unbind(previewUseCase)

这会在最后一帧停止预览,但现在我不知道如何重新启动它。我试过像这样再次绑定预览

cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)

但这会导致 PreviewView 只显示白色,就像它消失了一样,并且在重新启动应用程序之前无法恢复。

当我调用 unbindAll()

时,同样的事情发生了

所以我的问题是如何暂停预览视图,然后在稍后重新启动它?

这是我的代码

fun setupCamera(windowManager: WindowManager, previewView: PreviewView){

    _cameraProvider = _cameraProviderFuture.get()

    _preview = Preview.Builder()
        .setTargetRotation(windowManager.defaultDisplay.rotation)
        .build()

    _preview.setSurfaceProvider(previewView.previewSurfaceProvider)

    _cameraSelector = CameraSelector.Builder()
        .requireLensFacing(_requiredCameraLens)
        .build()

    _imageAnalyzer = ImageAnalysis.Builder()
        .setTargetResolution(Size(_imageWidth, _imageHeight))
        .setBackpressureStrategy(_imageBackpressureStrategy)
        .build()

    _imageAnalyzer.setAnalyzer(_imageExecutor,_analyzer)

    startPreview()

    _cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _imageAnalyzer)
}

// Called after image processing has finished
fun startPreview(){
    _cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _preview)
}

// Called when object is detected in an image
fun stopPreview(){
    _cameraProvider.unbind(_preview)
}

我没有在 Kotlin 中测试我的解决方案,但它在 Java 中运行良好。实际上,如果您只是调用 cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview) 它不会真正重新绑定您的预览。事实上,您必须重新创建预览并重置表面提供者。例如在 Java 中,当我想重新绑定我的预览时,我使用:

public void rebindPreview(){
    Preview preview = new Preview.Builder()
            .setTargetName("Preview")
            .build();
    preview.setSurfaceProvider(previewView.getPreviewSurfaceProvider());
    Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture);
}

我假设对于 Kotlin,您可以这样做:

fun rebindPreview(){
    _preview = Preview.Builder()
            .setTargetRotation(windowManager.defaultDisplay.rotation)
            .setTargetName("Preview")
            .build()
    _preview.setSurfaceProvider(previewView.previewSurfaceProvider)
    _cameraProvider.bindToLifecycle(_lifecycleOwner, _cameraSelector, _preview)
}