产品资讯

CameraX 1.5 隆重推出:强大的视频录制和专业级图片拍摄功能

阅读用时:7 分钟
查看 Scott Nien 的个人资料
Scott Nien 软件工程师

CameraX 团队很高兴地宣布,1.5 版现已发布!此次最新更新专注于为您提供专业级功能,同时让相机拍摄会话的配置比以往更加轻松。

在视频录制方面,用户现在可以轻松拍摄令人惊艳的慢动作或高帧率视频。更重要的是,借助全新的 Feature Group API,您可以放心地启用 10 位 HDR 和 60 FPS 等复杂组合,确保在受支持的设备上获得一致的效果。

在图片拍摄方面,您可获得最大的灵活性,因为系统支持拍摄未经处理、未经压缩的 DNG (RAW) 文件。此外,即使使用强大的 Camera Extensions,您现在也可以利用 Ultra HDR 输出。

这些功能以全新的 SessionConfig API 为基础,可简化相机设置和重新配置。现在,我们来详细了解一下这些令人兴奋的新功能。

强大的视频录制功能:高速和功能组合

CameraX 1.5 显著扩展了视频功能,可实现更具创意且更强大的录制体验。

慢动作和高帧速率视频

我们最受期待的功能之一“慢动作视频”现已推出。现在,您可以拍摄高速视频(例如 120 或 240 fps),并直接将其编码为极具张力的慢动作视频。或者,你也可以使用相同的高帧速率进行录制,从而制作出极其流畅的视频。

如果您熟悉 VideoCapture API,则可以轻松实现此功能。

1. 检查是否支持高速录制:使用新的 Recorder.getHighSpeedVideoCapabilities() 方法查询设备是否支持此功能。

val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)

val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

if (highSpeedCapabilities == null) {
    // This camera device does not support high-speed video.
    return
}

2. 配置并绑定用例:使用返回的 videoCapabilities(其中包含支持的视频画质信息)构建 HighSpeedVideoSessionConfig。然后,您必须通过 cameraInfo.getSupportedFrameRateRanges() 查询支持的帧速率范围,并设置所需的范围。调用 setSlowMotionEnabled(true) 可录制慢动作视频,否则会录制高帧率视频。最后一步是使用常规 Recorder.prepareRecording().start() 开始录制视频。

val preview = Preview.Builder().build()
val quality = highSpeedCapabilities
        .getSupportedQualities(DynamicRange.SDR).first()

val recorder = Recorder.Builder()
      .setQualitySelector(QualitySelector.from(quality)))
      .build()

val videoCapture = VideoCapture.withOutput(recorder)

val frameRateRange = cameraInfo.getSupportedFrameRateRanges(      
       HighSpeedVideoSessionConfig(videoCapture, preview)
).first()

val sessionConfig = HighSpeedVideoSessionConfig(
    videoCapture, 
    preview, 
    frameRateRange = frameRateRange, 
    // Set true for slow-motion playback, or false for high-frame-rate
    isSlowMotionEnabled = true
)

cameraProvider.bindToLifecycle(
     lifecycleOwner, cameraSelector, sessionConfig)

// Start recording slow motion videos. 
val recording = recorder.prepareRecording(context, outputOption)
      .start(executor, {})

兼容性和限制

高速录制需要特定的 CameraConstrainedHighSpeedCaptureSession 和 CamcorderProfile 支持。请务必执行功能检查,并仅在受支持的设备上启用高速录制,以防止出现糟糕的用户体验。目前,几乎所有 Pixel 设备以及其他制造商的部分型号设备的后置摄像头都支持此功能。

如需了解详情,请参阅这篇博文。

放心组合功能:Feature Group API

CameraX 1.5 引入了功能组 API,让您无需再猜测功能兼容性。借助 Android 15 的功能组合查询 API,您现在可以放心地同时启用多项功能,确保相机拍摄会话稳定运行。Feature Group 目前支持:HDR (HLG)、60 fps、预览防抖和 Ultra HDR。例如,您可以在 Pixel 10 和 Galaxy S25 系列上同时启用 HDR、60 fps 和预览防抖功能。未来计划推出 4K 录制和超广角变焦等增强功能。

特征组 API 支持两个基本应用场景:

应用场景 1:优先考虑最佳质量

如果您想使用尽可能最佳的功能组合进行捕获,可以提供一个优先级列表。CameraX 会尝试按顺序启用这些组合,并选择设备完全支持的第一个组合。

val sessionConfig = SessionConfig(
    useCases = listOf(preview, videoCapture),
    preferredFeatureGroup = listOf(
        GroupableFeature.HDR_HLG10,
        GroupableFeature.FPS_60,
        GroupableFeature.PREVIEW_STABILIZATION
    )
).apply {
    // (Optional) Get a callback with the enabled features to update your UI.
    setFeatureSelectionListener { selectedFeatures ->
        updateUiIndicators(selectedFeatures)
    }
}
processCameraProvider.bindToLifecycle(activity, cameraSelector, sessionConfig)

在此示例中,CameraX 会尝试按以下顺序启用功能:

  1. HDR + 60 FPS + 预览防抖
  2. HDR + 60 FPS
  3. HDR + 预览防抖
  4. HDR
  5. 60 FPS + 预览防抖
  6. 60 FPS
  7. 预览防抖
  8. 无

用例 2:构建面向用户的设置界面

现在,您可以在应用的设置界面中准确反映支持的功能组合,并停用不支持选项的切换开关,如下图所示。

unsupported-features-disabled.gif

如需确定是否要将切换开关灰显,请使用以下代码检查是否支持功能组合。首先,查询每个单独功能的状态。启用某项功能后,请重新查询剩余功能和已启用功能,看看由于兼容性限制,剩余功能的切换开关现在是否必须灰显。

fun disableFeatureIfNotSuported(
   enabledFeatures: Set<GroupableFeature>,     
   featureToCheck:GroupableFeature
) {
 val sessionConfig = SessionConfig(
     useCases = useCases,
     requiredFeatureGroup = enabledFeatures + featureToCheck
 )
 val isSupported = cameraInfo.isFeatureGroupSupported(sessionConfig)

 if (!isSupported) {
     // disable the toggle for featureToCheck
 }
}

如需了解详情,请参阅这篇关于特征组的博文 。

更多视频增强功能

  • 并发相机改进:借助 CameraX 1.5.1,您现在可以在非合成模式下为每个 SingleCameraConfig 并发绑定 Preview + ImageCapture + VideoCapture 用例。此外,在“撰写”模式 (与 CompositionSettings 相同的用例)下,您现在可以设置应用于最终合成结果的 CameraEffect。
  • 动态静音:您现在可以使用 PendingRecording.withAudioEnabled(boolean initialMuted) 在静音状态下开始录制,并允许用户稍后使用 Recording.mute(boolean muted) 取消静音。
  • 改进了存储空间不足的处理方式:CameraX 现在可以可靠地分派 VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGE 错误,让您的应用能够妥善处理存储空间不足的情况并通知用户。
  • 弱光增强:在受支持的设备(例如 Pixel 10 系列)上,您可以启用 CameraControl.enableLowLightBoostAsync,以便在黑暗环境中自动调亮预览和视频流。

专业级图片拍摄

CameraX 1.5 为追求极致画质和灵活性的开发者带来了 ImageCapture 的重大升级。

DNG (RAW) 拍摄功能,让您尽情发挥创意

为了让您能够完全控制后期处理,CameraX 现在支持 DNG (RAW) 拍摄。这样,您就可以直接从相机传感器获取未经处理、未经压缩的图片数据,从而进行专业级编辑和调色。该 API 支持单独拍摄 DNG 文件,或同时拍摄 JPEG 和 DNG 输出。请参阅以下示例代码,了解如何同时捕获 JPEG 和 DNG 文件。

val capabilities = ImageCapture.getImageCaptureCapabilities(cameraInfo)
val imageCapture = ImageCapture.Builder().apply {
    if (capabilities.supportedOutputFormats
             .contains(OUTPUT_FORMAT_RAW_JPEG)) {
        // Capture both RAW and JPEG formats.
        setOutputFormat(OUTPUT_FORMAT_RAW_JPEG)
    }
}.build()
// ... bind imageCapture to lifecycle ...


// Provide separate output options for each format.
val outputOptionRaw = /* ... configure for image/x-adobe-dng ... */
val outputOptionJpeg = /* ... configure for image/jpeg ... */
imageCapture.takePicture(
    outputOptionRaw,
    outputOptionJpeg,
    executor,
    object : ImageCapture.OnImageSavedCallback {
        override fun onImageSaved(results: OutputFileResults) {
            // This callback is invoked twice: once for the RAW file
            // and once for the JPEG file.
        }

        override fun onError(exception: ImageCaptureException) {}
    }
)

适用于 Camera Extensions 的 Ultra HDR

两全其美:Camera Extensions 的出色计算摄影功能(例如夜间模式)与 Ultra HDR 的绚丽色彩和动态范围完美结合。此功能现已在许多近期推出的高端 Android 手机上受支持,例如 Pixel 9/10 系列和 Samsung S24/S25 系列。

// Support UltraHDR when Extension is enabled. 

val extensionsEnabledCameraSelector = extensionsManager
     .getExtensionEnabledCameraSelector(
        CameraSelector.DEFAULT_BACK_CAMERA, ExtensionMode.NIGHT)

val imageCapabilities = ImageCapture.getImageCaptureCapabilities(
               cameraProvider.getCameraInfo(extensionsEnabledCameraSelector)

val imageCapture = ImageCapture.Builder()
     .apply {
       if (imageCapabilities.supportedOutputFormats
                .contains(OUTPUT_FORMAT_JPEG_ULTRA_HDR) {
           setOutputFormat(OUTPUT_FORMAT_JPEG_ULTRA_HDR)

       }

     }.build()

核心 API 和易用性增强功能

全新配置方式:SessionConfig

如上例所示,SessionConfig 是 CameraX 1.5 中的一个新概念。它通过以下两种主要方式集中配置并简化 API:

  1. 无需再手动调用 unbind():CameraX API 具有生命周期感知能力。当 activity 或其他 LifecycleOwner 被销毁时,它会隐式“解除绑定”您的用例。但更新用例或切换相机仍需要您在重新绑定之前调用 unbind() 或 unbindAll()。现在,借助 CameraX 1.5,当您绑定新的 SessionConfig 时,CameraX 会为您无缝更新会话,而无需调用解除绑定。
  2. 确定性帧速率控制:新的 SessionConfig API 引入了一种确定性帧速率管理方式。与之前的 setTargetFrameRate(仅作为提示)不同,这种新方法可保证在配置成功后应用指定的帧速率范围。为确保准确性,您必须使用 CameraInfo.getSupportedFrameRateRanges(SessionConfig) 查询支持的帧速率。通过传递完整的 SessionConfig,CameraX 可以根据数据流配置准确确定支持的范围。

Camera-Compose 现已稳定

我们知道您非常喜欢 Jetpack Compose,因此很高兴地宣布,camera-compose 库现已推出稳定版 1.5.1!此版本包含与 CameraXViewfinder 搭配使用 Compose 功能(例如 moveableContentOf 和 Pager)相关的关键 bug 修复,并解决了预览拉伸问题。我们将在未来版本中继续为 camera-compose 添加更多功能。

ImageAnalysis 和 CameraControl 改进

  • 手电筒强度调节:借助新 API,可以精细控制设备的手电筒。您可以使用 CameraInfo.getMaxTorchStrengthLevel() 查询支持的最大强度,然后使用 CameraControl.setTorchStrengthLevel() 设置所需的级别。
  • ImageAnalysis 中支持 NV21:您现在可以直接从 ImageAnalysis 请求 NV21 图片格式,从而简化与其他库和 API 的集成。此功能通过调用 ImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21) 启用。

立即开始使用

立即将依赖项更新为 CameraX 1.5,探索令人兴奋的新功能。我们迫不及待想看到您的杰作。

如需使用 CameraX 1.5,请将以下依赖项添加到 libs.versions.toml 中。(我们建议使用 1.5.1,其中包含许多关键问题修复和并发摄像头改进。)

[versions]

camerax = "1.5.1"


[libraries]

..

androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" }

androidx-camera-compose = { module = "androidx.camera:camera-compose", version.ref = "camerax" }

androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "camerax" }

androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" }

androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" }

androidx-camera-extensions = { module = "androidx.camera:camera-extensions", version.ref = "camerax" }

然后,将以下内容添加到模块 build.gradle.kts 依赖项中:

dependencies {

  ..

  implementation(libs.androidx.camera.core)
  implementation(libs.androidx.camera.lifecycle)

  implementation(libs.androidx.camera.camera2)

  implementation(libs.androidx.camera.view) // for PreviewView 
  implementation(libs.androidx.camera.compose) // for compose UI

  implementation(libs.androidx.camera.extensions) // For Extensions 

}

有疑问或想与 CameraX 团队联系?加入 CameraX 开发者论坛或提交 bug 报告:

继续阅读