0Pricing
Android Academy · 课时

录制视频

使用 CameraX 捕获视频

录制视频 是 CoddyKit 上的免费 Android Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Android Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Android Academy 课程共包含 4 节课。

使用 CameraX 录制视频

CameRX 通过由 Recorder 支持的 VideoCapture 用例录制视频。在本课中,您将设置视频捕获、开始和停止录制,并将视频保存到图库中——包括音频。

其流程与拍照类似,但增加了一个长时间运行的 Recording 会话,您可以启动它,之后再停止它。

Recorder 与质量

首先构建一个 Recorder,它负责定义编码方式和质量。QualitySelector 允许您请求目标质量(例如 HD、FHD);如果设备无法提供该质量,它还会使用备用方案。

val recorder = Recorder.Builder()
    .setQualitySelector(
        QualitySelector.from(
            Quality.FHD,
            FallbackStrategy.lowerQualityOrHigherThan(Quality.SD)
        )
    )
    .build()

创建 VideoCapture

使用 withOutput 工厂将 Recorder 封装到 VideoCapture 用例中。这就是要绑定到相机的对象,与 ImageCapture 类似。

val videoCapture = VideoCapture.withOutput(recorder)

绑定预览与 VideoCapture

将预览和 VideoCapture 绑定在一起。请注意,在许多设备上,您无法同时绑定 ImageCapture 和 VideoCapture,因此请根据屏幕需求选择用例。

cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
    lifecycleOwner,
    CameraSelector.DEFAULT_BACK_CAMERA,
    preview,
    videoCapture
)

音频权限

要录制声音,除了 CAMERA 外,您还需要 RECORD_AUDIO 运行时权限。请在开始录制前请求这两项权限,并且只有在用户授予音频权限后才启用音频。

// Manifest declares both:
// <uses-permission android:name="android.permission.CAMERA" />
// <uses-permission android:name="android.permission.RECORD_AUDIO" />

val audioGranted = ContextCompat.checkSelfPermission(
    context, Manifest.permission.RECORD_AUDIO
) == PackageManager.PERMISSION_GRANTED

通过 MediaStore 输出

与照片一样,请使用分区存储将视频保存到 MediaStore。使用 mp4 MIME 类型构建 ContentValues,然后创建 MediaStoreOutputOptions。

val values = ContentValues().apply {
    put(MediaStore.MediaColumns.DISPLAY_NAME, "VID_${System.currentTimeMillis()}")
    put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4")
    put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/MyApp")
}

val outputOptions = MediaStoreOutputOptions
    .Builder(context.contentResolver, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
    .setContentValues(values)
    .build()

开始录制

从录制器准备录制,可选择使用 withAudioEnabled() 启用音频,然后调用 start() 开始录制。start() 会返回一个 Recording 对象,请保存它,以便稍后停止录制。

您还需要传入一个监听器,用于接收 VideoRecordEvent 更新。

val recording = videoCapture.output
    .prepareRecording(context, outputOptions)
    .apply { if (audioGranted) withAudioEnabled() }
    .start(ContextCompat.getMainExecutor(context)) { event ->
        when (event) {
            is VideoRecordEvent.Start -> { /* recording began */ }
            is VideoRecordEvent.Finalize -> {
                if (!event.hasError()) {
                    // event.outputResults.outputUri -> saved video
                }
            }
        }
    }

响应录制事件

监听器会持续传递录制会话的生命周期事件:

  • VideoRecordEvent.Start — 录制已开始(将界面更新为停止按钮)。
  • VideoRecordEvent.Status — 定期更新已录制的时长和大小。
  • VideoRecordEvent.Finalize — 录制已结束;请检查 hasError()。
is VideoRecordEvent.Status -> {
    val seconds = event.recordingStats.recordedDurationNanos / 1_000_000_000
    // Update an on-screen timer.
}

停止录制

录制完成后,对之前保存的 Recording 调用 stop()。这会触发 Finalize 事件,此时可以获取视频 URI。

请将当前录制保存在状态中,这样一个按钮就能切换开始和停止操作。

var activeRecording: Recording? = null

// Toggle handler:
if (activeRecording == null) {
    activeRecording = startRecording()
} else {
    activeRecording?.stop()
    activeRecording = null
}

暂停与恢复

Recording 还可以暂停和恢复,而无需停止录制。这对于让用户将多个片段拼接到同一个文件中非常方便。

activeRecording?.pause()
// ...later
activeRecording?.resume()
// Final stop writes the file:
activeRecording?.stop()

用于录制的 Compose 界面

让界面由状态驱动。跟踪当前是否正在录制,并相应地切换按钮图标和操作。由于监听器在主执行器上运行,您可以直接在其中更新 Compose 状态。

var isRecording by remember { mutableStateOf(false) }

IconButton(onClick = { toggleRecording() }) {
    Icon(
        imageVector = if (isRecording) Icons.Default.Stop else Icons.Default.Videocam,
        contentDescription = if (isRecording) "Stop" else "Record"
    )
}

快速检查

请确认您已掌握使用 CameraX 录制视频的方法。

回顾

现在,您已经可以使用 CameraX 录制视频:

  • 使用 QualitySelector 构建 Recorder,并将其封装到 VideoCapture.withOutput 中。
  • 将其与预览绑定,并请求 RECORD_AUDIO 以录制声音。
  • 通过 MediaStoreOutputOptions 保存视频,然后调用 prepareRecording().start() 获取 Recording。
  • 响应 VideoRecordEvent 事件;调用 stop() 完成录制,并读取已保存的视频 URI。

您已经完成 CameraX 课程——预览、拍照和视频录制现在都已掌握。

常见问题解答

「录制视频」课时是免费的吗?

是的 — 「录制视频」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Android Academy 课程的其余内容,请升级到 CoddyKit PRO。 Android Academy 课程共包含 4 节课。

「录制视频」这节课中我会学到什么?

使用 CameraX 捕获视频 你通过在浏览器中直接运行的动手代码来练习 Android Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Android Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Android Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「录制视频」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Android Academy 课中编写并运行代码吗?

能。每节 Android Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. CameraX 概览
  2. 显示摄像头预览
  3. 拍照
  4. 录制视频
← 返回 Android Academy