机票直达
Android CameraX 详解一 (引言&基础)
Android CameraX 详解二 (实时预览)
Android CameraX 详解三 (拍照)
Android CameraX 详解四 (图片分析)
Android CameraX 详解五(视频拍摄录制)
概述
视频拍摄通常会录制视频流和音频流,对其进行压缩,对这两个流进行多路复用,然后将生成的流写入磁盘,如图1所示

图1
在 CameraX 中,用于视频捕获的解决方案是
VideoCapture对象,如图2所示视频捕获包括几个高级架构组件:
- SurfaceProvider,表示视频来源。
- AudioSource,表示音频来源。
- 用于对视频/音频进行编码和压缩的两个编码器
- 用于对两个流进行多路复用的媒体复用器
-
用于保存结果的文件保存器
图2
录制视频所用到的对象
-
VideoCapture是顶级用例类。VideoCapture通过CameraSelector和其他 CameraX 用例绑定到LifecycleOwner -
Recorder是与VideoCapture紧密耦合的 VideoOutput 实现。Recorder用于执行视频和音频捕获操作。应用通过Recorder创建录制对象。 -
PendingRecording会配置录制对象,同时提供启用音频和设置事件监听器等选项。您必须使用Recorder来创建PendingRecording。PendingRecording不会录制任何内容。 -
Recording会执行实际录制操作。您必须使用PendingRecording来创建Recording。 -
图3所示它们之间的关系
图3
录制步骤
- 申请
REORD_AUDIOCAMERA权限、添加PreviewView到布局(参考实时预览章节中添加布局) - 创建
QualitySelector(分辨率选择器)
Quality.UHD,适用于 4K 超高清视频大小 (2160p)
Quality.FHD,适用于全高清视频大小 (1080p)
Quality.HD,适用于高清视频大小 (720p)
Quality.SD,适用于标清视频大小 (480p)
创建QualitySelector方法1:设置首选分辨率和备选分辨率,首选分辨率全部不支持时备选分辨率启用
创建QualitySelector方法2:获取设备支持的分辨率列表,然后选择其一创建QualitySelector
//方法1
val qualitySelector = QualitySelector.fromOrderedList(
listOf(Quality.UHD, Quality.FHD, Quality.HD, Quality.SD),
FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))
//方法2
val cameraInfo = cameraProvider.availableCameraInfos.filter {
Camera2CameraInfo
.from(it)
.getCameraCharacteristic(CameraCharacteristics.LENS\_FACING) == CameraMetadata.LENS_FACING_BACK
}
val supportedQualities = QualitySelector.getSupportedQualities(cameraInfo[0])
val filteredQualities = arrayListOf (Quality.UHD, Quality.FHD, Quality.HD, Quality.SD)
.filter { supportedQualities.contains(it) }
val qualitySelector = QualitySelector.from(filteredQualities[position]) //position为选择项
- 创建
Recorder
val recorder = Recorder.Builder()
.setExecutor(cameraExecutor).setQualitySelector(qualitySelector)
.build()
- 创建
VideoCapture并绑定
val videoCapture = VideoCapture.withOutput(recorder)
val preview = Preview.Builder().build()
val viewFinder: PreviewView = findViewById(R.id.previewView)
preview.setSurfaceProvider(viewFinder.getSurfaceProvider())
try {
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, CameraSelector.DEFAULT_BACK_CAMERA, preview, videoCapture)
} catch(exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
- 设置保存参数
val name = "CameraX-recording.mp4"
val contentValues = ContentValues().apply {
put(MediaStore.Video.Media.DISPLAY_NAME, name)
}
val mediaStoreOutput = MediaStoreOutputOptions.Builder(this.contentResolver,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
.setContentValues(contentValues)
.build()
- 开始录制
使用Recorder.prepareRecording方法为Recorder配置OutputOptions,该方法返回PendingRecording对象
使用PendingRecording.withAudioEnabled方法启用音频
使用PendingRecording.start方法开始录制并返回Recording对象
val recording = videoCapture.output
.prepareRecording(context, mediaStoreOutput)
.withAudioEnabled()
.start(ContextCompat.getMainExecutor(this), captureListener)
录制控制
- 如果需要,使用
withAudioEnabled()启用音频 - 针对
Recording使用pause()/resume()/stop()来控制录制操作 - 在事件监听器内响应
VideoRecordEvents,即开始录制示例代码中的captureListener
存储配置
Recorder 支持以下类型的 OutputOptions:
-
FileDescriptorOutputOptions,用于捕获到FileDescriptor中 -
FileOutputOptions,用于捕获到File中 -
MediaStoreOutputOptions,用于捕获到MediaStore

