Android Camera2会话创建逻辑

问题描述 投票:0回答:1

我是Camera2框架的新手,我想了解创建捕捉会话的逻辑。

我需要一个简单的东西--预览和录制视频。我还想设置正确的方向提示。在我开始录制视频的时候. 但我遇到了一个鸡肋问题。

这是我的逻辑。

为了开始录音,我这样做。

    val recordRequest = session.device.createCaptureRequest(CameraDevice.TEMPLATE_RECORD).apply {
        // Add the preview and recording surface targets
        addTarget(viewFinder.holder.surface)
        addTarget(recorder.surface)
    }.build()

    session.setRepeatingRequest(recordRequest, null, cameraHandler)

    recorder.setOrientationHint(it) // NOT allowed after getSurface()!
    recorder.prepare()              // NOT allowed after getSurface()!
    recorder.start()

但是,我已经调用了 recorder.surface (或 getSurface())时,我在上面添加目标。可以认为我可以先准备好,然后再添加目标,然而。文件 对于 addTarget() 说,表面 添加的曲面必须是最近一次调用的曲面之一。CameraDevice#createCaptureSession


这就导致了一个有趣的问题。每当我打开应用程序时,我需要创建捕捉会话来开始预览相机图像。然而,在创建的时候 createCaptureSession() 需要包括 遍地 后会有期 捕捉请求. 这意味着,我也需要包括记录面,即使我只是打开相机,还没有记录。我如何得到这个 Surface 录音用的?嗯,这个 文件 说我可以从 MediaRecorder 或者我可以从 MediaCodec. 我想从 MediaRecorder 因为我想用 CamcorderProfiles. 然而,正如我在上面的代码中所显示的那样,一旦我从记录器中得到了曲面 在创建会话时 - 我不能在那里做任何改变 在开始录制时,比如设置方向提示。

官方 Camera2Video 样板应用做了一个技巧--它使用 创建持久性输入表面 然而在他们的例子中,摄像头是固定的,这使得他们可以为其分配足够的内存,并在整个应用生命周期中使用该表面。

如何解决这个问题?我是否误解了这里的概念?我如何能在稍后的时间点,当我开始录制时,创建记录器,但当我打开相机进行预览时,仍然有早期创建的表面?

android android-camera2
1个回答
2
投票

使用一个持久化的输入面是正确的方法。一旦你知道了录制的方向,就创建一个新的MediaRecorder,并使用持久性输入表面设置它的Surface。

这正是Camera2Video示例所做的。:

        // React to user touching the capture button
        capture_button.setOnTouchListener { view, event ->
            when (event.action) {

                MotionEvent.ACTION_DOWN -> lifecycleScope.launch(Dispatchers.IO) {

                    // Prevents screen rotation during the video recording
                    requireActivity().requestedOrientation =
                            ActivityInfo.SCREEN_ORIENTATION_LOCKED

                    // Start recording repeating requests, which will stop the ongoing preview
                    //  repeating requests without having to explicitly call `session.stopRepeating`
                    session.setRepeatingRequest(recordRequest, null, cameraHandler)

                    // Finalizes recorder setup and starts recording
                    recorder.apply {
                        // Sets output orientation based on current sensor value at start time
                        relativeOrientation.value?.let { setOrientationHint(it) }
                        prepare()
                        start()
                    }

recorder 是用早期创建的持久化曲面创建的。

    /** Saves the video recording */
    private val recorder: MediaRecorder by lazy { createRecorder(recorderSurface) 
    }

当你说相机是固定的,你是指应用程序的方向是固定的,还是说样本不支持切换前后摄像头? 对于持久化曲面来说,这些应该都不是特别重要,如果需要的话,你可以在切换摄像头或改变方向时创建一个新的曲面。

© www.soinside.com 2019 - 2024. All rights reserved.