清晰地拍摄快速移动的动作是现代相机应用的一项关键功能。这是通过高速拍摄实现的,即以 120 或 240 fps 等速率获取帧的过程。这种高保真拍摄可用于两个不同的目的:创建高帧速率视频 以进行详细的逐帧分析,或生成慢动作视频 ,让动作在屏幕上以戏剧性的方式展开。
以前,使用 Camera2 API 实现这些功能是一个更具实践性的过程。现在,借助 CameraX 1.5 中的新 高速 API ,整个过程得到了简化,让您可以灵活地创建真正的高帧速率视频或可直接播放的慢动作片段。本文将向您展示如何掌握这两种方法。如果您是 CameraX 的新手,可以阅读 CameraX 概览 快速入门。
慢动作背后的原理
慢动作的基本原理是以远高于回放速率的帧速率拍摄视频。例如,如果您以 120 帧/秒 (fps) 的速率录制一个持续一秒的事件,然后以标准的 30 fps 速率回放该录制内容,则视频将需要四秒才能播放完毕。这种时间的“拉伸”会产生戏剧性的慢动作效果,让您能够看到肉眼难以捕捉的细节。
为确保最终输出的视频流畅,通常应以至少 30 fps 的速率进行渲染。这意味着,要创建 4 倍慢动作视频,原始拍摄帧速率必须至少为 120 fps(120 拍摄 fps ÷ 4 = 30 回放 fps)。
拍摄高帧速率素材后,有两种主要方法可以实现所需的结果:
- 由播放器处理的慢动作(高帧速率视频): 高速录制(例如 120 fps)直接保存为高帧速率视频文件。然后,视频播放器负责减慢播放速度。这样,用户就可以灵活地在正常播放和慢动作播放之间切换。
- 可直接播放的慢动作(重新编码的视频): 高速视频流经过处理并重新编码为具有标准帧速率(例如 30 fps)的文件。通过调整帧时间戳,“内置”慢动作效果。生成的视频将在任何标准视频播放器中以慢动作播放,无需特殊处理。虽然视频默认以慢动作播放,但视频播放器仍然可以提供播放速度控件,让用户可以提高速度并以原始速度观看视频。
CameraX API 通过提供统一的方式来选择您想要使用的方法,从而简化了这一过程,如下所示。
新的高速视频 API
新的 CameraX 解决方案基于两个主要组件构建而成:
Recorder#getHighSpeedVideoCapabilities(CameraInfo):此方法可让您检查相机是否可以高速录制,如果可以,则检查支持哪些分辨率(Quality对象)。HighSpeedVideoSessionConfig:这是一个特殊的配置对象,用于将VideoCapture和Preview用例分组,告知 CameraX 创建统一的高速相机会话。请注意,虽然 VideoCapture 流将以配置的高帧速率运行,但 Preview 流通常会受到相机系统的限制,至少为 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 并将其绑定到生命周期后,最后一步是开始录制。准备输出选项、开始录制和处理视频事件的过程与标准视频拍摄的过程相同。
本文重点介绍高速配置,因此不会详细介绍录制过程。如需获取有关所有内容的全面指南,包括准备 FileOutputOptions 或 MediaStoreOutputOptions 对象,以及处理 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 或 960fps 时,Google 相册会为这些慢动作视频提供增强的功能:
- 缩略图中的独特界面识别: 在 Google 相册媒体库中,慢动作视频可以通过特定的界面元素来识别,从而与普通视频区分开来。
|
|
| 常规视频缩略图 | 慢动作视频缩略图 |
- 播放期间可调整速度的片段: 播放慢动作视频时,Google 相册会提供控件来调整视频的哪些部分以慢速播放,哪些部分以正常速度播放,从而让用户能够进行创意控制。然后,可以使用分享 按钮将编辑后的视频导出为新视频文件,保留您定义的慢动作片段。
|
|
| 常规视频播放 | 慢动作视频 播放,带有编辑 控件 |
关于设备支持的说明
CameraX 的高速 API 依赖于底层 Android CamcorderProfile 系统来确定设备支持哪些高速分辨率和帧速率。CamcorderProfile 由 Android 兼容性测试套件 (CTS) 验证,这意味着您可以确信设备报告的视频录制功能是准确的。
这意味着,设备使用其内置相机应用录制慢动作视频的能力并不能保证 CameraX 高速 API 能够正常运行。出现这种差异的原因是,设备制造商负责在其设备的固件中填充 CamcorderProfile 条目,有时必要的高速配置文件(例如 CamcorderProfile.QUALITY_HIGH_SPEED_1080P 和 CamcorderProfile.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 标志的作用,您可以轻松支持这两种用例,并让用户拥有更多创意控制权。
-
操作指南欢迎回到“构建智能 Android 应用”系列博文,我们将在此系列博文中介绍如何将基本的 Android 应用转变为个性化、智能化的智能体体验。在上一篇博文中,我们介绍了 Jetpacker,这是我们将在本系列博文中使用的演示版应用。
Caren Chang • 阅读用时:6 分钟 -
操作指南欢迎回到“构建智能 Android 应用”系列博文,我们将在此系列博文中介绍如何将基本的 Android 应用转变为个性化、智能化的智能体体验。
Thomas Ezan, Jolanda Verhoef, Caren Chang • 阅读用时:8 分钟 -
操作指南Jetpacker 是一款技术展示应用,我们的团队为今年的 Google I/O 大会从头开始构建了这款应用(使用 Antigravity 构建)。Jetpacker 的核心功能是帮助用户规划、探索和享受下一次重大冒险。
Jolanda Verhoef • 阅读用时:4 分钟
每周通过电子邮件接收最新的 Android 开发洞见 每周。