方法指南

使用 CameraX 1.5 进行高速拍摄和慢动作视频拍摄

阅读用时:6 分钟
Leo Huang
软件工程师

清晰地拍摄快速移动的动作是现代相机应用的一项关键功能。这是通过高速拍摄实现的,即以 120 或 240 fps 等速率获取帧的过程。这种高保真拍摄可用于两个不同的目的:创建高帧率视频以进行详细的逐帧分析,或生成慢动作视频,让动作在屏幕上以戏剧性的方式呈现。

以前,使用 Camera2 API 实现这些功能需要更多手动操作。现在,借助 CameraX 1.5 中的全新高速 API,整个流程得以简化,让您可以灵活地创建真正的高帧率视频或可直接播放的慢动作片段。本文将介绍如何熟练掌握这两种方法。如果您是 CameraX 新手,可以先阅读 CameraX 概览,快速了解相关知识。


慢动作背后的原理

慢动作的基本原理是以远高于播放帧速率的帧速率拍摄视频。例如,如果您以每秒 120 帧 (fps) 的速率录制一段时长为 1 秒的视频,然后以标准的 30 fps 速率播放该视频,则视频将需要 4 秒才能播放完毕。这种时间“拉伸”效果可营造出戏剧性的慢动作效果,让您看到肉眼无法捕捉的细节。

为确保最终输出的视频流畅顺畅,通常应以至少 30 fps 的帧速率进行渲染。这意味着,如需制作 4 倍慢动作视频,原始拍摄帧速率必须至少为 120 fps(120 拍摄 fps ÷ 4 = 30 播放 fps)。

拍摄高帧速率视频片段后,您可以通过以下两种主要方式实现所需效果:

  • 由播放器处理的慢动作(高帧速率视频):高速录制(例如 120 帧/秒)直接保存为高帧速率视频文件。然后,视频播放器会负责减慢播放速度。这样一来,用户就可以灵活地在正常播放和慢动作播放之间切换。
  • 可直接播放的慢动作视频(重新编码的视频):高速视频流经过处理并重新编码为具有标准帧速率(例如 30 帧/秒)的文件。通过调整帧时间戳,“烘焙”出慢动作效果。生成的视频将在任何标准视频播放器中以慢动作播放,无需特殊处理。虽然视频默认以慢动作播放,但视频播放器仍可提供播放速度控件,让用户能够提高播放速度并以原始速度观看视频。

CameraX API 提供了一种统一的方式来选择所需的方法,从而简化了此过程,如下所示。


新的高速视频 API

新的 CameraX 解决方案基于两个主要组件构建而成:

  • Recorder#getHighSpeedVideoCapabilities(CameraInfo):此方法可让您检查相机是否可以高速录制,如果可以,则检查支持哪些分辨率(Quality 对象)。
  • HighSpeedVideoSessionConfig:这是一个特殊的配置对象,用于将 VideoCapturePreview 使用情形分组,告知 CameraX 创建统一的高速相机会话。请注意,虽然 VideoCapture 流将以配置的高帧速率运行,但相机系统通常会将预览流限制为至少 30 FPS 的标准速率,以确保屏幕上的显示效果流畅。

使用入门

在开始之前,请确保您已将必要的 CameraX 依赖项添加到应用的 build.gradle.kts 文件中。您需要 camera-video 制品以及核心 CameraX 库。

  // build.gradle.kts (Module: app)

dependencies {

    val camerax_version = "1.5.1"


    implementation("androidx.camera:camera-core:$camerax_version")

    implementation("androidx.camera:camera-camera2:$camerax_version")

    implementation("androidx.camera:camera-lifecycle:$camerax_version")

    implementation("androidx.camera:camera-video:$camerax_version")

    implementation("androidx.camera:camera-view:$camerax_version")

}

关于实验性 API 的注意事项

请务必注意,高速录制 API 目前处于实验阶段。这意味着它们在未来版本中可能会发生变化。如需使用这些功能,您必须通过向代码添加以下注释来选择启用:

  @kotlin.OptIn(ExperimentalSessionConfig::class, ExperimentalHighSpeedVideo::class)

实现

这两种结果的实现都从相同的设置步骤开始。您只需进行一项设置,即可选择制作高帧速率视频还是慢动作视频。

1. 设置高速拍摄

首先,无论您的目标是什么,您都需要获取 ProcessCameraProvider、检查设备功能并创建用例。

以下代码块展示了挂起函数中的完整设置流程。您可以从协程作用域(例如 lifecycleScope.launch)调用此函数。

  // Add the OptIn annotation at the top of your function or class

@kotlin.OptIn(ExperimentalSessionConfig::class, ExperimentalHighSpeedVideo::class)

private suspend fun setupCamera() {

    // Asynchronously get the CameraProvider

    val cameraProvider = ProcessCameraProvider.awaitInstance(this)



    // -- CHECK CAPABILITIES --

    val cameraInfo = cameraProvider.getCameraInfo(CameraSelector.DEFAULT_BACK_CAMERA)

    val videoCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

    if (videoCapabilities == null) {

        // This camera device does not support high-speed video.

        return

    }




    // -- CREATE USE CASES --

    val preview = Preview.Builder().build()    


    // You can create a Recorder with default settings.

    // CameraX will automatically select a suitable quality.

    val recorder = Recorder.Builder().build()


    // Alternatively, to use a specific resolution, you can configure the
    // Recorder with a QualitySelector. This is useful if your app has
    // specific resolution requirements or you want to offer user
    // preferences. 

    // To use a specific quality, you can uncomment the following lines.

    // Get the list of qualities supported for high-speed video. 

    // val supportedQualities = videoCapabilities.getSupportedQualities(DynamicRange.SDR)

    // Build the Recorder using the quality from the supported list.

    // val recorderWithQuality = Recorder.Builder()

    //     .setQualitySelector(QualitySelector.from(supportedQualities.first()))

    //     .build()



    // Create the VideoCapture use case, using either recorder or recorderWithQuality

    val videoCapture = VideoCapture.withOutput(recorder)

    // Now you are ready to configure the session for your desired output...

}

2. 选择输出

现在,您可以决定要制作哪种类型的视频。此代码将在上述 setupCamera() suspend 函数内运行。

方法 A:制作高帧速率视频

如果您希望最终文件的帧速率较高(例如 120fps 的视频),请选择此选项。

  // Create a builder for the high-speed session

val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)

    .setPreview(preview)


// Query and apply a supported frame rate. Common supported frame rates include 120 and 240 fps.

val supportedFrameRateRanges =

    cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())


sessionConfigBuilder.setFrameRateRange(supportedFrameRateRanges.first())

方案 B:创建可直接播放的慢动作视频

如果您希望视频在任何标准视频播放器中自动以慢动作播放,请选择此选项。

  // Create a builder for the high-speed session

val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)

    .setPreview(preview)



// This is the key: enable automatic slow-motion!

sessionConfigBuilder.setSlowMotionEnabled(true)



// Query and apply a supported frame rate. Common supported frame rates include 120, 240, and 480 fps.

val supportedFrameRateRanges =

   cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())

sessionConfigBuilder.setFrameRateRange(supportedFrameRateRanges.first())

只需设置一个标志,即可创建可立即播放的慢动作视频。当 setSlowMotionEnabled 为 true 时,CameraX 会处理高速视频流并将其保存为标准的 30 fps 视频文件。慢动作速度取决于拍摄帧速率与此标准播放速度的比率。

例如:

  • 120 fps 的帧速率录制视频,则视频的播放速度为 1/4 倍速(120 ÷ 30 = 4)。
  • 240 fps 录制视频将生成以 1/8 倍速播放的视频(240 ÷ 30 = 8)。

综合应用:录制视频

配置 HighSpeedVideoSessionConfig 并将其绑定到生命周期后,最后一步是开始录制。准备输出选项、开始录制和处理视频事件的过程与标准视频拍摄相同。

本文重点介绍高速配置,因此不会详细介绍录制过程。如需获取有关所有方面的全面指南,包括准备 FileOutputOptionsMediaStoreOutputOptions 对象以及处理 VideoRecordEvent 回调,请参阅 VideoCapture 文档

  // Bind the session config to the lifecycle

cameraProvider.bindToLifecycle(

    this as LifecycleOwner,

    CameraSelector.DEFAULT_BACK_CAMERA,

    sessionConfigBuilder.build() // Bind the config object from Option A or B

)



// Start the recording using the VideoCapture use case

val recording = videoCapture.output

    .prepareRecording(context, outputOptions) // See docs for creating outputOptions

    .start(ContextCompat.getMainExecutor(context)) { recordEvent ->

        // Handle recording events (e.g., Start, Pause, Finalize)

    }

Google 相册对慢动作视频的支持

在 CameraX 中启用 setSlowMotionEnabled(true) 后,生成的视频文件可在标准视频播放器和图库应用中立即识别并以慢动作播放。特别是当拍摄帧速率为 120、240、360、480 或 960 fps 时,Google 相册可为这些慢动作视频提供增强功能:

  • 缩略图中的独特界面识别:在 Google 相册媒体库中,慢动作视频可通过特定界面元素进行识别,从而与普通视频区分开来。
normal.png
  • 播放期间可调整速度的片段:在播放慢动作视频时,Google 相册会提供控件来调整视频中哪些部分以慢速播放,哪些部分以正常速度播放,从而让用户能够发挥创意。然后,您可以使用分享按钮将编辑后的视频导出为新的视频文件,同时保留您定义的慢动作片段。
normal2.png

设备支持方面的注意事项

CameraX 的高速 API 依赖于底层的 Android CamcorderProfile 系统来确定设备支持哪些高速分辨率和帧速率。Android 兼容性测试套件 (CTS) 会验证 CamcorderProfiles,这意味着您可以放心地使用设备报告的视频录制功能。

这意味着,设备使用其内置相机应用录制慢动作视频的能力并不能保证 CameraX 高速 API 能够正常运行。出现这种差异是因为设备制造商负责在设备的固件中填充 CamcorderProfile 条目,但有时未包含必要的高速配置文件,例如 CamcorderProfile.QUALITY_HIGH_SPEED_1080PCamcorderProfile.QUALITY_HIGH_SPEED_720P。如果缺少这些配置文件,Recorder.getHighSpeedVideoCapabilities() 将返回 null

因此,务必始终使用 Recorder.getHighSpeedVideoCapabilities() 以编程方式检查受支持的功能,因为这是确保在不同设备上获得一致体验的最可靠方法。如果您尝试在 Recorder.getHighSpeedVideoCapabilities() 返回 null 的设备上绑定 HighSpeedVideoSessionConfig,该操作将失败并显示 IllegalArgumentException。您可以确认 Google Pixel 设备是否支持这些高速配置文件,因为这些设备始终包含这些配置文件。此外,其他制造商的各种设备(例如 Motorola Edge 30、OPPO Find N2 Flip 和 Sony Xperia 1 V)也支持高速视频功能。


总结

CameraX 高速视频 API 既强大又灵活。无论您是需要用于技术分析的真正的高帧率视频片段,还是想为应用添加电影般的慢动作效果,HighSpeedVideoSessionConfig 都能提供统一而简单的解决方案。了解 setSlowMotionEnabled 标志的作用后,您就可以轻松支持这两种使用情形,并让用户更灵活地控制创意。

继续阅读