【问题标题】:CameraX View in React Native - Unable to configure cameraReact Native 中的 CameraX 视图 - 无法配置相机
【发布时间】:2020-11-11 15:19:53
【问题描述】:

我正在创建 cameraX 视图,用于通过桥接进行本机反应。(正常视图在 RN 中呈现。桥接流程很好。)使用 PreviewView 显示 CameraX 预览的相机源。我已经成功实现了预览,但不确定为什么预览没有在 UI 上呈现。 它只是一个空白屏幕。

让我知道 UI 原生组件的正确实现方式。我在活动和工作中都很累。我是android平台的新手。提前致谢!

https://groups.google.com/a/android.com/g/camerax-developers/c/G9jKs1Bo_CE 检查了这个。但不确定问题是否与重新布局有关。

来自 NativeCameraView 类的日志:

23:21:45.415 8026-8026/com.app D/PreviewView: Surface requested by Preview.
11-11 23:21:45.415 8026-8784/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-ee9dbc80-160c-45e5-a38f-e68bc8f54373, androidx.camera.core.Preview-3e33af92-3cb6-4cb4-a0c3-dfb4e3c6cc8d] for camera: 0
11-11 23:21:45.415 8026-8784/com.app D/UseCaseAttachState: Active and attached use case: [androidx.camera.core.Preview-3e33af92-3cb6-4cb4-a0c3-dfb4e3c6cc8d] for camera: 0
11-11 23:21:45.416 8026-8784/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-ee9dbc80-160c-45e5-a38f-e68bc8f54373, androidx.camera.core.Preview-3e33af92-3cb6-4cb4-a0c3-dfb4e3c6cc8d] for camera: 0
11-11 23:21:45.416 8026-8784/com.app D/UseCaseAttachState: Active and attached use case: [androidx.camera.core.Preview-ee9dbc80-160c-45e5-a38f-e68bc8f54373, androidx.camera.core.Preview-3e33af92-3cb6-4cb4-a0c3-dfb4e3c6cc8d] for camera: 0
11-11 23:21:45.417 8026-8784/com.app D/UseCaseAttachState: Active and attached use case: [androidx.camera.core.Preview-ee9dbc80-160c-45e5-a38f-e68bc8f54373, androidx.camera.core.Preview-3e33af92-3cb6-4cb4-a0c3-dfb4e3c6cc8d] for camera: 0
11-11 23:21:50.459 8026-8785/com.app E/Camera2CameraImpl: Unable to configure camera 0, timeout!

相机活动记录:

11-12 22:55:40.545 6445-6445/com.app D/ReactVideoEvents: onHostPause
11-12 22:55:40.592 6445-7585/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-62b1221e-ac9f-4bc8-a145-f0dcb1f2e162] for camera: 0
11-12 22:55:40.593 6445-7585/com.app D/UseCaseAttachState: Active and attached use case: [] for camera: 0
11-12 22:55:40.593 6445-7585/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-62b1221e-ac9f-4bc8-a145-f0dcb1f2e162] for camera: 0
11-12 22:55:40.601 6445-7585/com.app I/CameraManager: Using legacy camera HAL.
11-12 22:55:40.604 6445-6445/com.app D/PreviewView: Surface requested by Preview.
11-12 22:55:40.611 6445-6445/com.app D/TextureViewImpl: SurfaceTexture available. Size: 1440x1080
11-12 22:55:40.612 6445-6445/com.app D/TextureViewImpl: Surface set on Preview.
11-12 22:55:40.791 6445-7585/com.app D/UseCaseAttachState: Active and attached use case: [androidx.camera.core.Preview-62b1221e-ac9f-4bc8-a145-f0dcb1f2e162] for camera: 0
11-12 22:55:40.793 6445-7585/com.app D/UseCaseAttachState: All use case: [androidx.camera.core.Preview-62b1221e-ac9f-4bc8-a145-f0dcb1f2e162] for camera: 0
11-12 22:55:40.793 6445-7585/com.app D/CaptureSession: Opening capture session.
11-12 22:55:40.795 6445-7585/com.app I/CameraDeviceState: Legacy camera service transitioning to state CONFIGURING
11-12 22:55:40.795 6445-8660/com.app I/RequestThread-0: Configure outputs: 1 surfaces configured.
11-12 22:55:40.795 6445-8660/com.app D/Camera: app passed NULL surface
11-12 22:55:40.819 6445-7585/com.app I/CameraDeviceState: Legacy camera service transitioning to state IDLE
11-12 22:55:40.820 6445-7578/com.app D/CaptureSession: Attempting to send capture request onConfigured
11-12 22:55:40.820 6445-7578/com.app D/CaptureSession: Issuing request for session.
11-12 22:55:40.822 6445-7578/com.app I/RequestQueue: Repeating capture request set.
11-12 22:55:40.822 6445-7578/com.app D/CaptureSession: CameraCaptureSession.onConfigured() mState=OPENED
11-12 22:55:40.823 6445-7585/com.app D/CaptureSession: CameraCaptureSession.onReady() OPENED

下面是sn-p:

public class myNativeCameraView extends FrameLayout {
...

public myNativeCameraView(ThemedReactContext context) {
    super(context);
    Log.d("ReactSpoCameraManager", "myNativeCameraView 1");
    mContext = context;

    FrameLayout layout = (FrameLayout) LayoutInflater.from(context).inflate(R.layout.camera_layout, null);
    mPreviewView = layout.findViewById(R.id.previewView);
    startCamera();
    setupLayoutHack();
}

private void startCamera() {
    final ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(mContext);
    cameraProviderFuture.addListener(new Runnable() {
        @Override
        public void run() {
            try {
                ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
                bindPreview(cameraProvider);
            } catch (ExecutionException | InterruptedException e) {}
        }
    }, ContextCompat.getMainExecutor(mContext));
}

void bindPreview(@NonNull ProcessCameraProvider cameraProvider) {
mPreviewView.setPreferredImplementationMode(PreviewView.ImplementationMode.SURFACE_VIEW);
    Preview preview = new Preview.Builder().build();
    CameraSelector cameraSelector = new CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build();
    ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
            .build();
    ImageCapture.Builder builder = new ImageCapture.Builder();

    preview.setSurfaceProvider(mPreviewView.createSurfaceProvider());
    Camera camera = cameraProvider.bindToLifecycle((AppCompatActivity) mContext.getCurrentActivity(), cameraSelector, preview, imageAnalysis);
}
}

我在构造函数中的startCamera 之后调用这个setupLayoutHack。确定问题是否与 React Native 中的重新布局有关。但仍然面临同样的错误。

void setupLayoutHack() {
        Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
            @Override
            public void doFrame(long frameTimeNanos) {
//                Log.d(TAG, "setupLayoutHack");
                manuallyLayoutChildren();
                getViewTreeObserver().dispatchOnGlobalLayout();
                Choreographer.getInstance().postFrameCallback(this);
            }
        });
    }

    void manuallyLayoutChildren() {
        for (int i = 0; i < getChildCount(); i++) {
            Log.d(TAG, "manuallyLayoutChildren");
            View child = getChildAt(i);
            child.measure(MeasureSpec.makeMeasureSpec(getMeasuredWidth(), MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY));
            child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
        }
    }

【问题讨论】:

  • 从错误信息看来mPreviewView为空,不应该在layout上调用findViewById()来获取PreviewView的实例吗?
  • 谢谢。现在它正在运行。但是预览仍然没有渲染。收到错误E/Camera2CameraImpl: Unable to configure camera 0, timeout!
  • 查看日志,我注意到两件事。 1) 有两个Preview 实例连接到相机,但从代码 sn-p 看来并非如此。 2) 相机向PreviewView 请求表面,但PreviewView 不提供表面。这可能是因为视图未在 UI 上呈现 (?)。
  • @HusaynHakeem 即使我已经设置了表面预览视图。但仍然 setPreferredImplementationMode(PreviewView.ImplementationMode.SURFACE_VIEW) 我错过了在 sn-p 中更新。知道缺少什么吗?
  • 相同的功能在活动中起作用。

标签: android react-native android-camera2 android-camerax


【解决方案1】:

我发现 PreviewView 没有添加到父级中,因为 getChildCount 返回 0。

使用 root 附加布局后它起作用了:

FrameLayout layout = (FrameLayout) LayoutInflater.from(context).inflate(R.layout.camera_layout, this, true);

而不是这个:

FrameLayout layout = (FrameLayout) LayoutInflater.from(context).inflate(R.layout.camera_layout, null);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    • 2022-11-10
    • 2020-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多