機(jī)票直達(dá)
Android CameraX 詳解一 (引言&基礎(chǔ))
Android CameraX 詳解二 (實(shí)時(shí)預(yù)覽)
Android CameraX 詳解三 (拍照)
Android CameraX 詳解四 (圖片分析)
Android CameraX 詳解五(視頻拍攝錄制)
概述
視頻拍攝通常會(huì)錄制視頻流和音頻流,對(duì)其進(jìn)行壓縮伶氢,對(duì)這兩個(gè)流進(jìn)行多路復(fù)用,然后將生成的流寫入磁盤佳吞,如圖1所示
圖1
在 CameraX 中,用于視頻捕獲的解決方案是
VideoCapture
對(duì)象盖淡,如圖2所示視頻捕獲包括幾個(gè)高級(jí)架構(gòu)組件:
- SurfaceProvider,表示視頻來(lái)源。
- AudioSource匾旭,表示音頻來(lái)源。
- 用于對(duì)視頻/音頻進(jìn)行編碼和壓縮的兩個(gè)編碼器
- 用于對(duì)兩個(gè)流進(jìn)行多路復(fù)用的媒體復(fù)用器
-
用于保存結(jié)果的文件保存器
圖2
錄制視頻所用到的對(duì)象
-
VideoCapture
是頂級(jí)用例類圃郊。VideoCapture
通過(guò)CameraSelector
和其他 CameraX 用例綁定到LifecycleOwner
-
Recorder
是與VideoCapture
緊密耦合的 VideoOutput 實(shí)現(xiàn)价涝。Recorder
用于執(zhí)行視頻和音頻捕獲操作。應(yīng)用通過(guò)Recorder
創(chuàng)建錄制對(duì)象持舆。 -
PendingRecording
會(huì)配置錄制對(duì)象色瘩,同時(shí)提供啟用音頻和設(shè)置事件監(jiān)聽器等選項(xiàng)。您必須使用Recorder
來(lái)創(chuàng)建PendingRecording
逸寓。PendingRecording
不會(huì)錄制任何內(nèi)容居兆。 -
Recording
會(huì)執(zhí)行實(shí)際錄制操作。您必須使用PendingRecording
來(lái)創(chuàng)建Recording
席覆。 -
圖3所示它們之間的關(guān)系
圖3
錄制步驟
- 申請(qǐng)
REORD_AUDIO
CAMERA
權(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
對(duì)象
使用PendingRecording.withAudioEnabled
方法啟用音頻
使用PendingRecording.start
方法開始錄制并返回Recording
對(duì)象
val recording = videoCapture.output
.prepareRecording(context, mediaStoreOutput)
.withAudioEnabled()
.start(ContextCompat.getMainExecutor(this), captureListener)
錄制控制
- 如果需要孤荣,使用
withAudioEnabled()
啟用音頻 - 針對(duì)
Recording
使用pause()
/resume()
/stop()
來(lái)控制錄制操作 - 在事件監(jiān)聽器內(nèi)響應(yīng)
VideoRecordEvents
甸陌,即開始錄制
示例代碼中的captureListener
存儲(chǔ)配置
Recorder
支持以下類型的 OutputOptions
:
-
FileDescriptorOutputOptions
,用于捕獲到FileDescriptor
中 -
FileOutputOptions
盐股,用于捕獲到File
中 -
MediaStoreOutputOptions
钱豁,用于捕獲到MediaStore