使用相机启动和停止相机的正确方法是什么?



我已经开始探索camerax库以及示例应用程序,并且我注意到管理生命周期时有些不一致。

在此线程中,我将仅谈论预览用例,因为它主要与生命周期有关。

在示例应用程序中,在CameraFragment中,用例与onViewCreated中的CameraX绑定,并且在onDestroyView中取消绑定。第一个问题是,如果我们将LifecycleOwner传递给bind方法,我们是否必须使用unbind用例?我们可以将它们绑在onCreate中,然后将生命周期管理放到CameraX上吗?

我还尝试关注"入门"教程,其中TextureView的CC_11刚刚替换。在示例应用程序中,首先将TextureView从父中删除,然后添加,然后更换SurfaceTexture。我们必须这样做吗?原因是什么?

另一件事是,在示例应用程序中,用例是由view.post { }方法绑定的。我遇到了这种方法的许多问题,因为将片段放在背面上,替换为另一个片段,而不是重新创建的camerax记录了许多消息:

E/CamX: [ERROR][STATS_AEC] aec_led_calibration.cpp:560: aec_led_cal_apply_calibration Invalid pointer 0x7921174000 0x0
E/CamX: [ERROR][STATS_AEC] aec_set.cpp:1346: aec_set_fps_range Aec_Error invalid input 414  E/CamX: [ERROR][STATS_AEC] camxcaecstatsprocessor.cpp:1671 SetAlgoBayerHistValue() Unsupported bayer hist channel! 
E/CamX: [ERROR][STATS  ] camxcaecstatsprocessor.cpp:3194 ProcessRequestFastAE() [FastAE] Failed to apply gain to the stats! E/CamX: [ERROR][STATS_AEC] aec_process.cpp:1229: aec_process_stats_parsing aec is null or invalid 
E/CamX: [ERROR][STATS_AEC] aec_process.cpp:7983: aec_process_preview_and_video Error: invalid stats

只能设置OnPreviewOutputUpdateListener而不是绑定所有用例吗?

编辑

为了显示确切的问题,我创建了简单的项目相机游乐场。

这是CameraFragment,具有整个逻辑。

class CameraFragment : Fragment() {
    private val preview by lazy {
        val configuration = PreviewConfig.Builder().build()
        Preview(configuration)
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        CameraX.bindToLifecycle(this, preview)
    }
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_camera, container, false)
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        button_gallery.setOnClickListener {
            requireActivity().supportFragmentManager
                .beginTransaction()
                .replace(R.id.container, GalleryFragment())
                .addToBackStack("GalleryFragment")
                .commit()
        }
        preview.setOnPreviewOutputUpdateListener { texture_view.surfaceTexture = it.surfaceTexture }
    }
}

现在单击图库按钮后,CameraFragmentGalleryFragment替换。按下返回按钮并返回CameraFragment后,Camerax记录了此类消息:

2019-05-09 14:12:20.969 778-1363/? E/CamX: [ERROR][STATS  ] gcamfastaeutil.cpp:1170 SetTuningData() [FastAE] ERROR! Failed to get the tuning data
2019-05-09 14:12:20.969 778-1363/? E/CamX: [ERROR][HAL    ] camxmetadatapool.cpp:1447 GetMetadataByTag() Invalid Slot to get a metadata from
2019-05-09 14:12:20.969 778-1363/? E/CamX: [ERROR][HAL    ] camxmetadatapool.cpp:1447 GetMetadataByTag() Invalid Slot to get a metadata from
2019-05-09 14:12:20.969 778-1363/? E/CamX: [ERROR][STATS_AEC] aec_led_calibration.cpp:560: aec_led_cal_apply_calibration Invalid pointer 0x7920f1d000 0x0
2019-05-09 14:12:20.969 778-1363/? E/CamX: [ERROR][STATS_AEC] aec_set.cpp:1346: aec_set_fps_range Aec_Error invalid input 0 
2019-05-09 14:12:20.969 778-1363/? E/CamX: [ERROR][STATS  ] camxae.cpp:2203 AECSetSensorInfo() Wrong initial sequence from HAL!
2019-05-09 14:12:20.969 778-1363/? E/CamX: [ERROR][STATS_AEC] aec_get.cpp:777: aec_get_param GET_EXP_PARAMS ERROR, Uninitialized exposure settings requested
2019-05-09 14:12:20.969 778-1363/? E/CamX: [ERROR][HAL    ] camxmetadatapool.cpp:1447 GetMetadataByTag() Invalid Slot to get a metadata from

camerax库 camera start&停止使用Java

要打开相机,我们没有特定的代码。只有您可以使用 bindtolifecycle((。另外,do 不是忘记,实现 LifeCycleObServer 。这是在相机中启动相机的镜头代码示例。

private void mStartCamera(){
    Camera camera = mCameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis);
}

要关闭相机,您应该在 cameraprovider 上工作。您做不是需要使用相机对象。简短的代码示例。

private void mStopCamera(){
    mCameraProvider.unbindAll();
}
  • 奖金

如果您要问&quot&quot&quot cameraprovider?您需要在 cameraproviderfuture 上添加侦听器。shor代码示例。

private void mDefineCameraProvider() {
    final ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(this);
    cameraProviderFuture.addListener(() -> {
        try {
            ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
            mCameraProvider = cameraProvider;
        } 
        catch (ExecutionException | InterruptedException e) {
            // No errors need to be handled for this Future.
            // This should never be reached.
            Log.e("CANER", "Camera provider error: " +e);
        }
    }, ContextCompat.getMainExecutor(this));
}

第一个问题是,如果我们通过生命周围的clode虫来绑定方法,我们是否必须解开用例?我们可以将它们束缚在on greate中,然后将生命周期管理留在camerax上?

你是正确的。我认为示例应用程序可以安全删除CameraX.unbindAll()调用。

首先将纹理视图从父级删除,然后添加,然后更换surfaceTexture。我们必须这样做吗?原因是什么?

需要将纹理视图删除并从父视图中重新添加,以使其附加的surfaceTexture。这是因为一旦将其连接到视图层次结构,内部就可以在内部创建自己的surfaceTexture,并且一旦从视图层次结构中删除了父textureView,则内部surfaceTexture才能正确分离。入门Codelab已更新以包括重新连接。

另一件事是,在示例应用中,用例是从view.post {}方法绑定的。我遇到了这种方法的许多问题,因为将片段放在背面上,替换为另一个碎片,而不是重新创建的,camerax记录了许多消息

viewFinder.post { ... }内部的绑定用例,以确保在正确布置纹理浏览后用例绑定。您从E/CamX开始看到的错误实际上与Camerax库无关,并且似乎来自设备的本机相机堆栈(即相机驱动程序(。如果您在应用程序本身中没有看到任何问题,则可能会忽略错误消息。

可以仅设置OnPreviewOutputupDateListener而不是绑定所有用例吗?

我不确定我明白这一点。您必须绑定Camerax的所有用例,以实际启动它们作为相机会话的一部分。查看文档以获取更多详细信息。

相关内容

最新更新