You need to enable JavaScript to run this app. Camera2 API启动视频录制时闪光灯自动关闭,如何保持闪光灯常亮?
优惠活动
大模型
产品
解决方案
定价
更多

Camera2 API启动视频录制时闪光灯自动关闭,如何保持闪光灯常亮?

问题原因

你启动录制时会创建全新的CaptureRequest.Builder,使用的CameraDevice.TEMPLATE_RECORD模板默认闪光灯模式为关闭,且你没有将当前的闪光灯状态同步到新的请求构造器中,所以新会话启动重复请求后闪光灯就会自动熄灭。

解决方案

每次创建新的CaptureRequest.Builder(包括预览会话和录制会话)时,都主动根据全局的isFlashOn状态配置闪光灯模式,保证状态继承即可。
具体修改如下:

  1. 修改previewSession()方法,创建请求构造器后新增闪光灯状态同步逻辑:
private fun previewSession() {
    val surfaceTexture = textureView.surfaceTexture
    MAX_PREVIEW_HEIGHT = textureView.height
    MAX_PREVIEW_WIDTH = textureView.width

    surfaceTexture?.setDefaultBufferSize(MAX_PREVIEW_HEIGHT, MAX_PREVIEW_WIDTH)
    val surface = Surface(surfaceTexture)
    captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
    // 新增:同步当前闪光灯状态
    if (isFlashOn) {
        captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH)
    } else {
        captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF)
    }
    captureRequestBuilder.addTarget(surface)

    // 后续原有逻辑不变
    mCameraDevice.createCaptureSession(
        listOf(surface),
        object : CameraCaptureSession.StateCallback() {
            override fun onConfigured(session: CameraCaptureSession) {
                if (session != null) {
                    captureSession = session
                    captureSession.setRepeatingRequest(
                        captureRequestBuilder.build(),
                        null,
                        null
                    )

                }
            }

            override fun onConfigureFailed(session: CameraCaptureSession) {
                showLog(TAG, "Failed to create CameraCaptureSession")
            }
        },
        mBackgroundHandler
    )
}
  1. 修改recordSession()方法,同样新增闪光灯状态同步逻辑:
private fun recordSession() {
    setUpMediaRecorder()
    val surfaceTexture = textureView.surfaceTexture
    MAX_PREVIEW_HEIGHT = textureView.height
    MAX_PREVIEW_WIDTH = textureView.width

    surfaceTexture?.setDefaultBufferSize(MAX_PREVIEW_HEIGHT, MAX_PREVIEW_WIDTH)
    val textureSurface = Surface(surfaceTexture)
    val recordSurface = mediaRecorder.surface
    captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD)
    // 新增:同步当前闪光灯状态
    if (isFlashOn) {
        captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH)
    } else {
        captureRequestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF)
    }
    captureRequestBuilder.addTarget(textureSurface)
    captureRequestBuilder.addTarget(recordSurface)

    // 后续原有逻辑不变
    val surfaces = ArrayList<Surface>().apply {
        add(textureSurface)
        add(recordSurface)
    }

    mCameraDevice.createCaptureSession(
        surfaces,
        object : CameraCaptureSession.StateCallback() {

            override fun onConfigured(session: CameraCaptureSession) {
                captureSession = session
                captureSession.setRepeatingRequest(
                    captureRequestBuilder.build(),
                    null,
                    null
                )
                isRecording = true
                mediaRecorder.start()
            }

            override fun onConfigureFailed(session: CameraCaptureSession) {
                showLog(TAG, "Failed to create CameraRecordSession!")
            }

        },
        mBackgroundHandler
    )
}
可选兼容配置

如果修改后偶现闪光灯自动关闭,可以在同步闪光灯状态的代码后新增自动曝光模式配置,避免系统自动曝光逻辑覆盖自定义的闪光灯设置:

captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON)

内容的提问来源于stack exchange,提问作者mendax01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 05:06:02