You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于CameraX的Kotlin版Android视频拍摄APP参数调节开发咨询

基于CameraX的视频拍摄APP参数调节开发建议

结合你现有CameraXVideo项目基础,以及Kotlin经验不足的情况,以下是针对性的开发实现建议:

一、Kotlin快速适配小技巧

  • 用lateinit声明相机核心变量(如cameraControl、cameraProvider),避开空安全语法的繁琐,注意在初始化后再调用
  • 用Lambda简化UI组件监听(如按钮点击、滑块变化),替代Java风格的匿名内部类
  • 用runCatching包裹相机参数设置代码,捕获设备兼容性异常,避免崩溃
  • 优先使用Jetpack组件的Kotlin扩展语法,比如by viewModels()管理相机逻辑

二、帧率(30/60fps)切换实现

1. UI布局

添加一个切换按钮(如ToggleButton),显示当前帧率状态,示例布局代码:

<ToggleButton
    android:id="@+id/fps_toggle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textOff="30FPS"
    android:textOn="60FPS"/>

2. 逻辑实现

先获取设备支持的帧率范围,再通过按钮点击更新VideoCapture配置:

import androidx.camera.core.CameraSelector
import androidx.camera.core.VideoCapture
import androidx.camera.lifecycle.ProcessCameraProvider
import android.util.Range

private val FPS_30 = Range(30, 30)
private val FPS_60 = Range(60, 60)
private var currentFpsRange = FPS_30
private lateinit var cameraProvider: ProcessCameraProvider
private lateinit var cameraSelector: CameraSelector
// 保留原有项目中的preview、videoCapture等变量

// 初始化时先检查设备是否支持60fps
private fun checkFpsSupport() {
    val characteristics = cameraProvider.getCameraCharacteristics(cameraSelector)
    val supportedFpsRanges = characteristics.get(
        androidx.camera.core.CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES
    ) ?: emptyArray()
    // 若不支持60fps,禁用按钮或隐藏
    fps_toggle.isEnabled = supportedFpsRanges.any { it.contains(60) }
}

// 按钮点击事件
fps_toggle.setOnCheckedChangeListener { _, isChecked ->
    currentFpsRange = if (isChecked) FPS_60 else FPS_30
    updateVideoCaptureConfig()
}

private fun updateVideoCaptureConfig() {
    val newVideoCapture = VideoCapture.Builder()
        .setTargetFpsRange(currentFpsRange)
        .setTargetResolution(currentResolution) // 复用原有项目的分辨率变量
        .setAudioEnabled(isAudioEnabled) // 复用原有项目的音频开关状态
        .build()
    // 重新绑定CameraX用例
    cameraProvider.unbindAll()
    cameraProvider.bindToLifecycle(
        this, cameraSelector, preview, newVideoCapture
    )
}

三、曝光参数调节(滑块实现)

1. UI布局

添加SeekBar用于调节曝光补偿(单位为EV):

<SeekBar
    android:id="@+id/exposure_seekbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

2. 逻辑实现

通过CameraControl设置曝光补偿,先获取设备支持的补偿范围:

import androidx.camera.core.CameraControl
import android.hardware.camera2.CaptureRequest

private lateinit var cameraControl: CameraControl

// 初始化时获取曝光范围
private fun initExposureSeekBar() {
    val characteristics = cameraProvider.getCameraCharacteristics(cameraSelector)
    val exposureRange = characteristics.get(
        androidx.camera.core.CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE
    ) ?: Range(0, 0)
    val minExposure = exposureRange.lower
    val maxExposure = exposureRange.upper

    exposure_seekbar.apply {
        min = minExposure
        max = maxExposure
        progress = 0 // 默认0EV
    }

    // 获取CameraControl实例
    cameraControl = cameraProvider.getCamera(cameraSelector).cameraControl
}

// 滑块监听事件
exposure_seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        if (fromUser) {
            // 确保自动曝光模式开启,曝光补偿才生效
            runCatching {
                cameraControl.setCaptureRequestOption(
                    CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON
                )
                cameraControl.setExposureCompensation(progress)
            }
        }
    }

    override fun onStartTrackingTouch(seekBar: SeekBar?) {}
    override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})

四、白平衡参数调节(滑块实现)

1. UI布局

添加SeekBar用于调节色温(单位为K):

<SeekBar
    android:id="@+id/wb_seekbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

2. 逻辑实现

通过CameraControl手动设置色温,先获取设备支持的色温范围:

private fun initWbSeekBar() {
    val characteristics = cameraProvider.getCameraCharacteristics(cameraSelector)
    val tempRange = characteristics.get(
        androidx.camera.core.CameraCharacteristics.CONTROL_AWB_AVAILABLE_COLOR_TEMPERATURES
    ) ?: intArrayOf(4000, 4000)
    val minTemp = tempRange[0]
    val maxTemp = tempRange[1]

    wb_seekbar.apply {
        min = minTemp
        max = maxTemp
        progress = (minTemp + maxTemp) / 2 // 默认中间值
    }
}

wb_seekbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        if (fromUser) {
            runCatching {
                // 关闭自动白平衡,切换为手动色温模式
                cameraControl.setCaptureRequestOption(
                    CaptureRequest.CONTROL_AWB_MODE,
                    CaptureRequest.CONTROL_AWB_MODE_OFF
                )
                cameraControl.setCaptureRequestOption(
                    CaptureRequest.CONTROL_AWB_LOCK,
                    true
                )
                cameraControl.setCaptureRequestOption(
                    CaptureRequest.CONTROL_AWB_TEMPERATURE,
                    progress
                )
            }
        }
    }

    override fun onStartTrackingTouch(seekBar: SeekBar?) {}
    override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})

// 可额外添加自动白平衡按钮
auto_wb_btn.setOnClickListener {
    runCatching {
        cameraControl.setCaptureRequestOption(
            CaptureRequest.CONTROL_AWB_MODE,
            CaptureRequest.CONTROL_AWB_MODE_AUTO
        )
        cameraControl.setCaptureRequestOption(
            CaptureRequest.CONTROL_AWB_LOCK,
            false
        )
        // 重置滑块到自动色温对应值(可选)
        wb_seekbar.progress = 4000
    }
}

五、通用注意事项

  • 权限处理:确保已动态申请CAMERA权限,Android 13+还需READ_MEDIA_VIDEO权限用于视频存储
  • 生命周期:所有相机参数调节逻辑需在onResume之后执行,避免相机未初始化完成
  • 兼容性:所有参数范围(帧率、曝光、色温)必须从设备CameraCharacteristics获取,禁止硬编码数值
  • 异常捕获:用runCatching包裹相机参数设置代码,避免因设备不支持某参数导致崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 07:36:01