機(jī)票直達(dá)
Android CameraX 詳解一 (引言&基礎(chǔ))
Android CameraX 詳解二 (實(shí)時(shí)預(yù)覽)
Android CameraX 詳解三 (拍照)
Android CameraX 詳解四 (圖片分析)
Android CameraX 詳解五(視頻拍攝錄制)
概述
視頻拍攝通常會錄制視頻流和音頻流,對其進(jìn)行壓縮,對這兩個(gè)流進(jìn)行多路復(fù)用,然后將生成的流寫入磁盤,如圖1所示

圖1
在 CameraX 中,用于視頻捕獲的解決方案是
VideoCapture對象,如圖2所示視頻捕獲包括幾個(gè)高級架構(gòu)組件:
- SurfaceProvider,表示視頻來源。
- AudioSource,表示音頻來源。
- 用于對視頻/音頻進(jìn)行編碼和壓縮的兩個(gè)編碼器
- 用于對兩個(gè)流進(jìn)行多路復(fù)用的媒體復(fù)用器
-
用于保存結(jié)果的文件保存器
圖2
錄制視頻所用到的對象
-
VideoCapture是頂級用例類。VideoCapture通過CameraSelector和其他 CameraX 用例綁定到LifecycleOwner -
Recorder是與VideoCapture緊密耦合的 VideoOutput 實(shí)現(xiàn)。Recorder用于執(zhí)行視頻和音頻捕獲操作。應(yīng)用通過Recorder創(chuàng)建錄制對象。 -
PendingRecording會配置錄制對象,同時(shí)提供啟用音頻和設(shè)置事件監(jiān)聽器等選項(xiàng)。您必須使用Recorder來創(chuàng)建PendingRecording。PendingRecording不會錄制任何內(nèi)容。 -
Recording會執(zhí)行實(shí)際錄制操作。您必須使用PendingRecording來創(chuàng)建Recording。 -
圖3所示它們之間的關(guān)系
圖3
錄制步驟
- 申請
REORD_AUDIOCAMERA權(quán)限、添加PreviewView到布局(參考實(shí)時(shí)預(yù)覽章節(jié)中添加布局) - 創(chuàng)建
QualitySelector(分辨率選擇器)
Quality.UHD,適用于 4K 超高清視頻大小 (2160p)
Quality.FHD,適用于全高清視頻大小 (1080p)
Quality.HD,適用于高清視頻大小 (720p)
Quality.SD,適用于標(biāo)清視頻大小 (480p)
創(chuàng)建QualitySelector方法1:設(shè)置首選分辨率和備選分辨率,首選分辨率全部不支持時(shí)備選分辨率啟用
創(chuàng)建QualitySelector方法2:獲取設(shè)備支持的分辨率列表,然后選擇其一創(chuàng)建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為選擇項(xiàng)
- 創(chuàng)建
Recorder
val recorder = Recorder.Builder()
.setExecutor(cameraExecutor).setQualitySelector(qualitySelector)
.build()
- 創(chuàng)建
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)
}
- 設(shè)置保存參數(shù)
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()來控制錄制操作 - 在事件監(jiān)聽器內(nèi)響應(yīng)
VideoRecordEvents,即開始錄制示例代碼中的captureListener
存儲配置
Recorder 支持以下類型的 OutputOptions:
-
FileDescriptorOutputOptions,用于捕獲到FileDescriptor中 -
FileOutputOptions,用于捕獲到File中 -
MediaStoreOutputOptions,用于捕獲到MediaStore

