Sistem perekaman umumnya merekam streaming video dan audio, mengompresinya, menggabungkan dua streaming secara multipleks, lalu menulis streaming yang dihasilkan ke disk.
Di CameraX, solusi untuk perekaman video adalah kasus penggunaan
VideoCapture
:
VideoCapture.Seperti yang ditunjukkan dalam gambar 2, perekaman video CameraX menyertakan beberapa komponen arsitektur tingkat tinggi:
SurfaceProvideruntuk sumber video.AudioSourceuntuk sumber audio.- Dua encoder untuk mengenkode dan mengompresi video/audio.
- Penggabung multipleks media untuk menggabungkan dua streaming secara multipleks.
- Penyimpan file untuk menuliskan hasilnya.
VideoCapture API meringkas mesin perekaman yang kompleks serta memberikan API yang jauh lebih sederhana dan mudah ke aplikasi.
Ringkasan VideoCapture API
VideoCapture adalah kasus penggunaan CameraX yang berfungsi dengan sendirinya atau saat
digabungkan dengan kasus penggunaan lainnya. Kombinasi tertentu yang didukung bergantung pada
kemampuan hardware kamera, tetapi Preview dan VideoCapture adalah
kombinasi kasus penggunaan yang valid di semua perangkat.
VideoCapture API terdiri dari objek berikut yang berkomunikasi dengan aplikasi:
VideoCaptureadalah class kasus penggunaan level teratas.VideoCaptureterikat padaLifecycleOwnerdenganCameraSelectordan UseCases CameraX lainnya. Untuk mengetahui informasi konsep dan penggunaan ini lebih lanjut, lihat Arsitektur CameraX.Recorderadalah implementasi VideoOutput yang dikaitkan erat denganVideoCapture.Recorderdigunakan untuk melakukan perekaman video dan audio. Aplikasi membuat rekaman dariRecorder.PendingRecordingmengonfigurasi perekaman, yang memberikan opsi seperti mengaktifkan audio dan menyetel pemroses peristiwa. Anda harus menggunakanRecorderuntuk membuatPendingRecording.PendingRecordingtidak merekam apa pun.Recordingakan melakukan perekaman yang sebenarnya. Anda harus menggunakanPendingRecordinguntuk membuatRecording.
Gambar 3 menunjukkan hubungan antara objek ini:
Keterangan:
- Membuat
RecorderdenganQualitySelector. - Mengonfigurasi
Recorderdengan salah satuOutputOptions. - Mengaktifkan audio dengan
withAudioEnabled()jika diperlukan. - Memanggil
start()dengan pemrosesVideoRecordEventuntuk mulai merekam. - Menggunakan
pause()/resume()/stop()padaRecordinguntuk mengontrol perekaman. - Merespons
VideoRecordEventsdalam pemroses peristiwa Anda.
Daftar API mendetail ada di current.txt dalam kode sumber.
Menggunakan VideoCapture API
Untuk mengintegrasikan kasus penggunaan VideoCapture CameraX ke dalam aplikasi Anda,
lakukan langkah-langkah berikut:
- Ikat
VideoCapture. - Siapkan dan konfigurasikan perekaman.
- Mulai dan kontrol perekaman runtime.
Bagian berikut menguraikan hal-hal yang dapat Anda lakukan di setiap langkah untuk mendapatkan sesi perekaman menyeluruh.
Mengikat VideoCapture
Untuk mengikat kasus penggunaan VideoCapure, lakukan langkah-langkah berikut:
- Buat objek
Recorder. - Buat objek
VideoCapture. - Ikatkan ke
Lifecycle.
VideoCapture API CameraX mengikuti pola desain builder. Aplikasi
menggunakan Recorder.Builder untuk membuat Recorder. Anda juga dapat mengonfigurasi
resolusi video untuk Recorder melalui objek QualitySelector.
Recorder CameraX mendukung Qualities berikut yang telah ditentukan sebelumnya
untuk resolusi video:
Quality.UHDuntuk ukuran video ultra HD 4K (2160p)Quality.FHDuntuk ukuran video full HD (1080p)Quality.HDuntuk ukuran video HD (720p)Quality.SDuntuk ukuran video SD (480p)
Perhatikan bahwa CameraX juga memilih resolusi lain saat diizinkan oleh aplikasi.
Ukuran video yang tepat dari setiap pilihan bergantung pada kemampuan kamera dan
encoder. Untuk mengetahui informasi selengkapnya, baca dokumentasi untuk
CamcorderProfile.
Aplikasi dapat mengonfigurasi resolusi dengan membuat
QualitySelector.
Anda dapat membuat QualitySelector menggunakan salah satu metode berikut:
Berikan beberapa resolusi pilihan menggunakan
fromOrderedList(), dan sertakan strategi penggantian untuk digunakan jika tidak ada resolusi pilihan yang didukung.CameraX dapat menentukan pencocokan penggantian terbaik berdasarkan kemampuan kamera yang dipilih, lihat
FallbackStrategy specificationQualitySelectoruntuk detail selengkapnya. Misalnya, kode berikut meminta resolusi tertinggi yang didukung untuk perekaman, dan jika tidak ada resolusi permintaan yang dapat didukung, izinkan CameraX untuk memilih resolusi yang paling mendekati resolusi Quality.SD:val qualitySelector = QualitySelector.fromOrderedList( listOf(Quality.UHD, Quality.FHD, Quality.HD, Quality.SD), FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))Buat kueri kapabilitas kamera terlebih dahulu, dan pilih dari resolusi yang didukung menggunakan
QualitySelector::from():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) } // Use a simple ListView with the id of simple_quality_list_view viewBinding.simpleQualityListView.apply { adapter = ArrayAdapter(context, android.R.layout.simple_list_item_1, filteredQualities.map { it.qualityToString() }) // Set up the user interaction to manually show or hide the system UI. setOnItemClickListener { _, _, position, _ -> // Inside View.OnClickListener, // convert Quality.* constant to QualitySelector val qualitySelector = QualitySelector.from(filteredQualities[position]) // Create a new Recorder/VideoCapture for the new quality // and bind to lifecycle val recorder = Recorder.Builder() .setQualitySelector(qualitySelector).build() // ... } } // A helper function to translate Quality to a string fun Quality.qualityToString() : String { return when (this) { Quality.UHD -> "UHD" Quality.FHD -> "FHD" Quality.HD -> "HD" Quality.SD -> "SD" else -> throw IllegalArgumentException() } }Perhatikan bahwa kemampuan yang ditampilkan dari
QualitySelector.getSupportedQualities()dijamin berfungsi untuk kasus penggunaanVideoCaptureataupun kombinasi kasus penggunaanVideoCapturedanPreview. Saat melakukan binding dengan kasus penggunaanImageCaptureatauImageAnalysis, CameraX mungkin masih menggagalkan binding jika kombinasi yang diperlukan tidak didukung pada kamera yang diminta.
Setelah Anda memiliki QualitySelector, aplikasi dapat membuat
objek VideoCapture dan melakukan binding. Perhatikan bahwa binding ini
sama dengan kasus penggunaan lainnya:
val recorder = Recorder.Builder()
.setExecutor(cameraExecutor).setQualitySelector(qualitySelector)
.build()
val videoCapture = VideoCapture.withOutput(recorder)
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)
}
Perhatikan bahwa bindToLifecycle() menampilkan objek Camera. Lihat panduan ini untuk informasi mengontrol output kamera selengkapnya, seperti zoom dan eksposur.
Recorder akan memilih format yang paling cocok untuk sistem. Codec video
yang paling umum adalah
H.264 AVC) dengan
format penampung
MPEG-4.
Mengonfigurasi dan membuat rekaman
Dari Recorder, aplikasi dapat membuat objek perekaman untuk
melakukan perekaman video dan audio. Aplikasi membuat rekaman dengan melakukan
hal-hal berikut:
- Mengonfigurasikan
OutputOptionsdenganprepareRecording(). - (Opsional) Mengaktifkan rekaman audio.
- Menggunakan
start()untuk mendaftarkan pemrosesVideoRecordEvent, dan memulai perekaman video.
Recorder menampilkan objek Recording saat Anda memanggil fungsi start().
Aplikasi Anda dapat menggunakan objek Recording ini untuk menyelesaikan
perekaman atau melakukan tindakan lainnya, seperti menjeda atau melanjutkan perekaman.
Recorder mendukung satu objek Recording dalam satu waktu. Anda dapat memulai
perekaman baru setelah memanggil Recording.stop() atau
Recording.close() pada objek Recording sebelumnya.
Mari kita lihat langkah-langkah ini secara lebih mendetail. Pertama, aplikasi akan mengonfigurasi
OutputOptions untuk Perekam dengan Recorder.prepareRecording().
Recorder mendukung jenis OutputOptions berikut:
FileDescriptorOutputOptionsuntuk merekam ke dalamFileDescriptor.FileOutputOptionsuntuk merekam ke dalamFile.MediaStoreOutputOptionsuntuk merekam ke dalamMediaStore.
Semua jenis OutputOptions memungkinkan Anda untuk menetapkan ukuran file maksimum dengan
setFileSizeLimit(). Opsi lainnya khusus untuk jenis output
individu, seperti ParcelFileDescriptor untuk FileDescriptorOutputOptions.
prepareRecording() menampilkan objek PendingRecording yang merupakan
objek perantara yang digunakan untuk membuat
objek Recording yang sesuai. PendingRecording adalah class sementara yang seharusnya
tidak terlihat dan jarang di-cache oleh aplikasi.
Aplikasi dapat mengonfigurasi perekaman lebih lanjut, seperti:
- Mengaktifkan audio dengan
withAudioEnabled(). - Mendaftarkan pemroses untuk menerima peristiwa perekaman video
dengan
start(Executor, Consumer<VideoRecordEvent>). - Izinkan rekaman untuk terus direkam saat VideoCapture terlampir
terhubung kembali ke kamera lain, dengan
PendingRecording.asPersistentRecording().
Untuk mulai merekam, panggil PendingRecording.start(). CameraX mengubah
PendingRecording menjadi Recording, mengantrekan permintaan perekaman,
dan menampilkan objek Recording yang baru dibuat ke aplikasi.
Setelah perekaman dimulai pada perangkat Kamera yang sesuai, CameraX akan mengirimkan
peristiwa VideoRecordEvent.EVENT_TYPE_START.
Contoh berikut menunjukkan cara merekam video dan audio ke
dalam file MediaStore:
// Create MediaStoreOutputOptions for our recorder
val name = "CameraX-recording-" +
SimpleDateFormat(FILENAME_FORMAT, Locale.US)
.format(System.currentTimeMillis()) + ".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()
// 2. Configure Recorder and Start recording to the mediaStoreOutput.
val recording = videoCapture.output
.prepareRecording(context, mediaStoreOutput)
.withAudioEnabled()
.start(ContextCompat.getMainExecutor(this), captureListener)
Saat pratinjau kamera dicerminkan di kamera depan secara default, video akan yang direkam oleh VideoCapture tidak dicerminkan secara default. Dengan CameraX 1.3, kini memungkinkan untuk mencerminkan rekaman video sehingga pratinjau kamera depan dan kecocokan video yang direkam.
Ada tiga opsi MirrorMode: MIRROR_MODE_OFF, MIRROR_MODE_ON, dan
MIRROR_MODE_ON_FRONT_ONLY. Untuk menyelaraskan dengan
pratinjau kamera, Google merekomendasikan penggunaan MIROR_MODE_ON_FRONT_ONLY, yang berarti
sehingga
pencerminan tidak diaktifkan untuk kamera belakang, tetapi diaktifkan untuk bagian depan
kamera. Untuk mengetahui informasi selengkapnya tentang MirrorMode, lihat
MirrorMode constants
Cuplikan kode ini menunjukkan cara memanggil
VideoCapture.Builder.setMirrorMode() menggunakan MIRROR_MODE_ON_FRONT_ONLY. Sebagai
informasi selengkapnya, lihat setMirrorMode().
Kotlin
val recorder = Recorder.Builder().build() val videoCapture = VideoCapture.Builder(recorder) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build() useCases.add(videoCapture);
Java
Recorder.Builder builder = new Recorder.Builder(); if (mVideoQuality != QUALITY_AUTO) { builder.setQualitySelector( QualitySelector.from(mVideoQuality)); } VideoCapture<Recorder> videoCapture = new VideoCapture.Builder<>(builder.build()) .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY) .build(); useCases.add(videoCapture);
Mengontrol perekaman aktif
Anda dapat menjeda, melanjutkan, dan menghentikan Recording yang sedang berjalan
dengan metode berikut:
pauseuntuk menjeda perekaman aktif saat ini.resume()untuk melanjutkan perekaman aktif yang dijeda.stop()untuk menyelesaikan perekaman dan menghapus semua objek perekaman terkait.mute()untuk membisukan atau membunyikan rekaman saat ini.
Perhatikan bahwa Anda dapat memanggil stop() untuk menghentikan Recording, terlepas
apakah perekaman dalam status dijeda atau aktif.
Jika Anda telah mendaftarkan EventListener dengan
PendingRecording.start(), Recording akan berkomunikasi
menggunakan
VideoRecordEvent.
VideoRecordEvent.EVENT_TYPE_STATUSdigunakan untuk merekam statistik seperti ukuran file saat ini dan rentang waktu yang direkam.VideoRecordEvent.EVENT_TYPE_FINALIZEdigunakan untuk hasil perekaman dan mencakup informasi seperti URI file akhir beserta error terkait apa pun.
Setelah aplikasi Anda menerima EVENT_TYPE_FINALIZE yang menunjukkan bahwa
sesi perekaman berhasil dilakukan, Anda dapat mengakses video yang direkam dari lokasi
yang ditentukan di OutputOptions.
Referensi lainnya
Untuk mempelajari CameraX lebih lanjut, baca referensi tambahan berikut ini:
- Memulai Codelab CameraX
- Aplikasi contoh CameraX resmi
- Daftar CameraX Video Capture API terbaru
- Catatan rilis CameraX
- Kode sumber CameraX