如何在场景黑暗时自动打开手电筒进行视频录制?

Posted

技术标签:

【中文标题】如何在场景黑暗时自动打开手电筒进行视频录制?【英文标题】:How to automatically turn on flashlight for video recording when the scene is dark? 【发布时间】:2021-09-18 16:00:47 【问题描述】:

我的应用显示预览,按下按钮即可开始录制视频。

我想要实现的是在视频录制开始时自动打开手电筒(手电筒模式)。

但是我找不到这样做的方法。在 Camera2 API 上,我们可以使用 FLASH_MODE_AUTO,它会在场景黑暗时使用手电筒拍摄照片,但这不适用于视频录制。 有这个 FLASH_MODE_TORCH,我可以用它来打开手电筒,就像我想要的那样,但没有 FLASH_MODE_TORCH_AUTO 可以在场景黑暗时自动这样做..

有一些答案使用设备的环境光传感器(Sensor.TYPE_LIGHT)来确定我们是否处于黑暗场景中,但是我认为使用前置环境光传感器而不是相机本身。这并不理想,因为环境光可能很低,但后置摄像头能够调整曝光水平以在不使用闪光灯的情况下获得足够好的图像质量。所以理想情况下,如果相机说“需要闪光灯”,那么只有应用程序会激活 FLASH_MODE_TORCH。

由于应用显示预览,设备在按下按钮之前就已经知道是否需要闪光灯,有没有办法在预览期间确定是否需要闪光灯?

【问题讨论】:

检查这个。希望它可能会有所帮助。 ***.com/a/47270509/8413748 谢谢,但似乎该解决方案需要触发预闪,更适合拍照而不是视频录制? 【参考方案1】:

请在需要的地方试试下面的方法就可以使用了

以下是相机 API

public void switchFlashOnMode() 
        Camera.Parameters p = getCamera().getParameters();
        try 
            //p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
            p.setFlashMode(Parameters.FLASH_MODE_AUTO);
            getCamera().setParameters(p);
            getCamera().startPreview();
            isFlashTorch = true;
        catch (Exception e)
            e.printStackTrace();
        
    

    public void switchFlashOffMode() 
        Camera.Parameters p = getCamera().getParameters();
        try 
            p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
            getCamera().setParameters(p);
            Thread.sleep(200);
            getCamera().stopPreview();
            isFlashTorch = false;
        catch (Exception e)
            e.printStackTrace();
        
    

下面是 Camera2 API

 void switchFlashMode() 
        if (!flashSupport) return;

        try 
            if (isFlashTorch) 
                isFlashTorch = false;
                requestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_OFF);
             else 
                isFlashTorch = true;
                  //requestBuilder.set(CaptureRequest.FLASH_MODE,CameraMetadata.FLASH_MODE_TORCH);
                  requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
                

            cameraCaptureSession.setRepeatingRequest(requestBuilder.build(), null, null);
         catch (Exception e) 
            e.printStackTrace();
        
    

希望对你有帮助

【讨论】:

您好,谢谢您的回答,我的理解是 CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH 只在拍照时触发一次手电筒,与 FLASH_MODE_TORCH 上的永久不一样?另外不要认为它适用于视频录制,除非我弄错了 刚试了一下,没用。 FLASH_MODE_TORCH 开启闪光灯进行视频录制,但无论场景亮度如何都会强制开启,而 CONTROL_AE_MODE_ON_AUTO_FLASH 为自动但不适用于视频录制:(【参考方案2】:

终于想通了,gpuser 的回答使用了正确的标志,但它不完整 - 仍然需要编写回调代码并在需要时打开手电筒。

我还发现,对于视频录制,我们仍然使用相同的 Camera2 API 初始化和配置步骤,只是有些回调会被触发多次,所以我添加了一个标志来只执行一次闪光检测。

1)相机开始拍摄后,运行这段代码

performAutoTorchDetectionOnce = true; // set this flag first, will be used later
captureRequestBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); // CONTROL_AE_MODE_ON_AUTO_FLASH is important here, to enable flash detection
captureSession.setRepeatingRequest(captureRequestBuilder.build(), captureCallback, null);

2)这是我的 captureCallback 实现,根据您的需要进行更改。它的要点是最终相机捕获将落入两种状态之一,CONTROL_AE_STATE_CONVERGED 或 CONTROL_AE_STATE_FLASH_REQUIRED。这两种状态意味着自动曝光算法已经运行完毕,如果它收敛意味着不需要闪光灯,而flash_required意味着我们必须打开闪光灯。在后者中,我们将需要在下一步中手动打开闪光灯。

private CameraCaptureSession.CaptureCallback captureCallback =
    new CameraCaptureSession.CaptureCallback() 
            @Override
            public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
                                         long timestamp, long frameNumber) 
                super.onCaptureStarted(session, request, timestamp, frameNumber);
            

            @Override
            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) 
                super.onCaptureCompleted(session, request, result);

                Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                if (aeState != null) 
                    if (performAutoTorchDetectionOnce) 
                        if (aeState == CameraMetadata.CONTROL_AE_STATE_CONVERGED            // CONTROL_AE_STATE_CONVERGED means Auto-exposure has finished
                            || aeState == CameraMetadata.CONTROL_AE_STATE_FLASH_REQUIRED)  // CONTROL_AE_STATE_FLASH_REQUIRED means Auto-exposure has finished, but flash is required
                            performAutoTorchDetectionOnce = false;
                            enableTorch(aeState == CameraMetadata.CONTROL_AE_STATE_FLASH_REQUIRED);
                        
                    
                
            
    ;

3) 这是 enableTorch 的实现。我尝试将 CONTROL_AE_MODE 保留为 CONTROL_AE_MODE_ON_AUTO_FLASH 但它不起作用,手电筒灯不亮,所以我必须将其更改为 CONTROL_AE_MODE_ON。

public synchronized void enableTorch(boolean enable) 
        Timber.d("enableTorch(" + enable + ") called");
        try 
            if (isCaptureStarted()) 
                if (enable) 
                    captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
                 else 
                    captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
                
                captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
                captureSession.setRepeatingRequest(captureRequestBuilder.build(), null, null);
            
         catch (CameraAccessException e) 
            Timber.e(e, "enableTorch(" + enable + ") failed: ");
        
    

【讨论】:

以上是关于如何在场景黑暗时自动打开手电筒进行视频录制?的主要内容,如果未能解决你的问题,请参考以下文章

为啥录制出来的视频没有声音?

打开打开录制声音后,为啥录屏还是没声音?

vivo手机在快手上怎么录制60秒

手机录屏录的视频为啥没有声音?

手机录制视频没有声音怎么办

如何为iOS设备制作录屏指导视频