机票直达
Android CameraX 详解一 (引言&基础)
Android CameraX 详解二 (实时预览)
Android CameraX 详解三 (拍照)
Android CameraX 详解四 (图片分析)
Android CameraX 详解五(视频拍摄录制)
概述
视频拍摄通常会录制视频流和音频流,对其进行压缩,对这两个流进行多路复用,然后将生成的流写入磁盘,如图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_AUDIO
CAMERA
权限、添加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
网友评论