Bir kayıt sistemi genellikle video ve ses akışlarını kaydeder, bunları sıkıştırır, iki akışı çoklar ve ardından ortaya çıkan akışı diske yazar.
CameraX'te video çekme çözümü VideoCapture kullanım alanıdır:
VideoCapture kullanım alanınıŞekil 2'de gösterildiği gibi, CameraX video yakalama özelliği birkaç üst düzey mimari bileşen içerir:
SurfaceProvidervideo kaynağı için.AudioSourceses kaynağı için.- Video/ses kodlamak ve sıkıştırmak için iki kodlayıcı.
- İki akışı çoklamak için bir medya çoklayıcı.
- Sonucu yazmak için bir dosya kaydedici.
VideoCapture API, karmaşık yakalama motorunu soyutlar ve uygulamalara çok daha basit ve anlaşılır bir API sağlar.
VideoCapture API'ye genel bakış
VideoCapture, tek başına veya diğer kullanım alanlarıyla birlikte iyi çalışan bir CameraX kullanım alanıdır. Desteklenen belirli kombinasyonlar kamera donanımının özelliklerine bağlıdır ancak Preview ve VideoCapture tüm cihazlarda geçerli bir kullanım alanı kombinasyonudur.
VideoCapture API, uygulamalarla iletişim kuran aşağıdaki nesnelerden oluşur:
VideoCapture, üst düzey kullanım alanı sınıfıdır.VideoCapture,CameraSelectorve diğer CameraX UseCases ileLifecycleOwner'ye bağlanır. Bu kavramlar ve kullanımlar hakkında daha fazla bilgi için CameraX Mimarisi başlıklı makaleye göz atın.Recorder,VideoCaptureile sıkı bir şekilde bağlı olan VideoOutput'un bir uygulamasıdır.Recorder, video ve ses yakalama işlemlerini gerçekleştirmek için kullanılır. Bir uygulama,Recorderkaynağından kayıt oluşturur.PendingRecordingkaydı yapılandırır, sesin etkinleştirilmesi ve etkinlik işleyicinin ayarlanması gibi seçenekler sunar.PendingRecordingoluşturmak içinRecorderkullanmanız gerekir.PendingRecordinghiçbir şey kaydetmez.Recording, gerçek kaydı yapar.Recordingoluşturmak içinPendingRecordingkullanmanız gerekir.
Şekil 3'te bu nesneler arasındaki ilişkiler gösterilmektedir:
Açıklama:
RecorderileQualitySelectoroluşturun.OutputOptionskullanarakRecorderyapılandırın.- Gerekirse
withAudioEnabled()ile sesi etkinleştirin. - Kaydı başlatmak için
start()numaralıVideoRecordEventdinleyiciyi arayın. - Kaydı kontrol etmek için
Recordingüzerindepause()/resume()/stop()simgelerini kullanın. - Etkinlik işleyicinizde
VideoRecordEventsyanıtı verin.
Ayrıntılı API listesi kaynak kodunun içindeki current.txt dosyasında yer alır.
VideoCapture API'yi kullanma
CameraX VideoCapture kullanım alanını uygulamanıza entegre etmek için aşağıdakileri yapın:
- Bind
VideoCapture. - Kaydı hazırlayın ve yapılandırın.
- Çalışma zamanı kaydını başlatma ve kontrol etme
Aşağıdaki bölümlerde, uçtan uca kayıt oturumu elde etmek için her adımda neler yapabileceğiniz özetlenmektedir.
Bind VideoCapture
VideoCapture kullanım alanını bağlamak için aşağıdakileri yapın:
Recordernesnesi oluşturun.VideoCapturenesnesi oluşturun.Lifecycle'e bağlayın.
CameraX VideoCapture API, builder tasarım kalıbını izler. Uygulamalar, Recorder.Builder kullanarak Recorder oluşturur. Ayrıca, Recorder için video çözünürlüğünü QualitySelector nesnesi üzerinden de yapılandırabilirsiniz.
CameraX Recorder, video çözünürlükleri için aşağıdaki önceden tanımlanmış Qualities'leri destekler:
Quality.UHD4K Ultra HD video boyutu (2160p) içinQuality.FHDiçin Full HD video boyutu (1080p)Quality.HDHD video boyutu (720p) içinQuality.SDSD video boyutu (480p) için
CameraX'in, uygulama tarafından yetkilendirildiğinde başka çözünürlükler de seçebileceğini unutmayın.
Her seçimin tam video boyutu, kameranın ve kodlayıcının özelliklerine bağlıdır. Daha fazla bilgi için CamcorderProfile dokümanlarına bakın.
Uygulamalar, QualitySelector oluşturarak çözünürlüğü yapılandırabilir.
Aşağıdaki yöntemlerden birini kullanarak QualitySelector oluşturabilirsiniz:
fromOrderedList()kullanarak birkaç tercih edilen çözünürlük sağlayın ve tercih edilen çözünürlüklerden hiçbiri desteklenmediğinde kullanılacak bir yedek strateji ekleyin.CameraX, seçilen kameranın özelliğine göre en iyi yedek eşleşmeye karar verebilir. Daha fazla bilgi için
QualitySelector'nınFallbackStrategy specificationbölümüne bakın. Örneğin, aşağıdaki kod, kayıt için desteklenen en yüksek çözünürlüğü ister. İstenen çözünürlüklerden hiçbiri desteklenemiyorsa CameraX'in Quality.SD çözünürlüğüne en yakın olanı seçmesine izin verir:val qualitySelector = QualitySelector.fromOrderedList( listOf(Quality.UHD, Quality.FHD, Quality.HD, Quality.SD), FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))Önce kamera özelliklerini sorgulayın ve
QualitySelector::from()kullanarak desteklenen çözünürlükler arasından seçim yapın: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() } }QualitySelector.getSupportedQualities()'dan döndürülen özelliğinVideoCapturekullanım alanı veyaVideoCapturevePreviewkullanım alanlarının kombinasyonu için çalışacağı garanti edilir.ImageCaptureveyaImageAnalysiskullanım alanıyla birlikte bağlandığında, istenen kamerada gerekli kombinasyon desteklenmiyorsa CameraX bağlamayı yine de gerçekleştiremeyebilir.
Bir QualitySelector oluşturduktan sonra uygulama, VideoCapture nesnesi oluşturup bağlama işlemini gerçekleştirebilir. Bu bağlamanın diğer kullanım alanlarıyla aynı olduğunu unutmayın:
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)
}
bindToLifecycle() işlevinin Camera nesnesi döndürdüğünü unutmayın. Yakınlaştırma ve pozlama gibi kamera çıkışını kontrol etme hakkında daha fazla bilgi için bu kılavuza bakın.
Recorder, sistem için en uygun biçimi seçer. En yaygın video codec'i, MPEG-4 kapsayıcı biçimindeki H.264 AVC'dir.
Kaydı yapılandırma ve oluşturma
Uygulama, Recorder aracılığıyla video ve ses yakalama işlemlerini gerçekleştirmek için kayıt nesneleri oluşturabilir. Uygulamalar, kayıt oluşturmak için aşağıdakileri yapar:
OutputOptions'ıprepareRecording()ile yapılandırın.- (İsteğe bağlı) Ses kaydını etkinleştirin.
start()simgesini kullanarakVideoRecordEventdinleyicisi kaydedin ve video yakalamaya başlayın.
Recorder, start() işlevini çağırdığınızda Recording nesnesini döndürür.
Uygulamanız, bu Recording nesnesini kullanarak yakalamayı tamamlayabilir veya duraklatma ya da devam ettirme gibi başka işlemler gerçekleştirebilir.
Recorder, tek seferde bir Recording nesnesini destekler. Önceki Recording nesnesinde Recording.stop() veya Recording.close() numaralarını aradıktan sonra yeni bir kayıt başlatabilirsiniz.
Bu adımları daha ayrıntılı olarak inceleyelim. İlk olarak uygulama, Recorder.prepareRecording() ile bir Kaydedici için OutputOptions yapılandırır.
Bir Recorder aşağıdaki OutputOptions türlerini destekler:
FileDescriptoriçine aktarmak içinFileDescriptorOutputOptions.Fileiçine aktarmak içinFileOutputOptions.MediaStoreiçine aktarmak içinMediaStoreOutputOptions.
Tüm OutputOptions türleri, setFileSizeLimit() ile maksimum dosya boyutu belirlemenize olanak tanır. Diğer seçenekler, çıkış türüne özeldir. Örneğin, FileDescriptorOutputOptions için ParcelFileDescriptor seçeneği.
prepareRecording(), ilgili Recording nesnesini oluşturmak için kullanılan bir ara nesne olan PendingRecording nesnesini döndürür. PendingRecording, çoğu durumda görünmez olması gereken ve uygulama tarafından nadiren önbelleğe alınan geçici bir sınıftır.
Uygulamalar, kaydı daha ayrıntılı şekilde yapılandırabilir. Örneğin:
withAudioEnabled()ile sesi etkinleştirin.start(Executor, Consumer<VideoRecordEvent>)ile video kaydı etkinliklerini almak için bir dinleyici kaydedin.- VideoCapture'ın başka bir kameraya yeniden bağlanması sırasında
PendingRecording.asPersistentRecording()ile kaydın sürekli olarak kaydedilmesine izin verin.
Kaydı başlatmak için PendingRecording.start() numarasını arayın. CameraX, PendingRecording öğesini Recording öğesine dönüştürür, kayıt isteğini sıraya alır ve yeni oluşturulan Recording nesnesini uygulamaya döndürür.
İlgili kamera cihazında kayıt başladığında CameraX, VideoRecordEvent.EVENT_TYPE_START etkinliğini gönderir.
Aşağıdaki örnekte, video ve sesin nasıl MediaStore dosyasına kaydedileceği gösterilmektedir:
// 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)
Kamera önizlemesi varsayılan olarak ön kamerada yansıtılırken VideoCapture ile kaydedilen videolar varsayılan olarak yansıtılmaz. CameraX 1.3 ile artık video kayıtlarını yansıtarak ön kamera önizlemesi ile kaydedilen videonun eşleşmesini sağlayabilirsiniz.
Üç MirrorMode seçeneği vardır: MIRROR_MODE_OFF, MIRROR_MODE_ON ve MIRROR_MODE_ON_FRONT_ONLY. Google, kamera önizlemesiyle hizalamak için MIROR_MODE_ON_FRONT_ONLY'nin kullanılmasını önerir. Bu, arka kamerada yansıtmanın etkinleştirilmediği ancak ön kamerada etkinleştirildiği anlamına gelir. MirrorMode hakkında daha fazla bilgi için MirrorMode constants sayfasına bakın.
Bu kod snippet'inde, MIRROR_MODE_ON_FRONT_ONLY kullanılarak VideoCapture.Builder.setMirrorMode() işlevinin nasıl çağrılacağı gösterilmektedir. Daha fazla bilgi için setMirrorMode() sayfasına bakın.
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);
Etkin bir kaydı kontrol etme
Devam eden bir Recording işlemini duraklatmak, devam ettirmek ve durdurmak için aşağıdaki yöntemleri kullanabilirsiniz:
pauseMevcut etkin kaydı duraklatmak için.resume()Duraklatılmış etkin bir kaydı devam ettirmek için.stop()kaydı bitirmek ve ilişkili kayıt nesnelerini temizlemek için.mute()Mevcut kaydın sesini kapatmak veya açmak için
Kaydın duraklatılmış veya etkin kayıt durumunda olup olmadığına bakılmaksızın stop() numaralı telefonu arayarak Recording sonlandırabileceğinizi unutmayın.
EventListener cihazını PendingRecording.start() ile kaydettiyseniz Recording, VideoRecordEvent kullanarak iletişim kurar.
VideoRecordEvent.EVENT_TYPE_STATUS, mevcut dosya boyutu ve kaydedilen süre gibi istatistikleri kaydetmek için kullanılır.VideoRecordEvent.EVENT_TYPE_FINALIZE, kayıt sonucu için kullanılır ve son dosyanın URI'si ile ilgili hatalar gibi bilgileri içerir.
Uygulamanız, başarılı bir kayıt oturumunu gösteren EVENT_TYPE_FINALIZE aldıktan sonra, OutputOptions içinde belirtilen konumdan kaydedilen videoya erişebilirsiniz.
Ek kaynaklar
CameraX hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara göz atın:
- CameraX Codelab'i Kullanmaya Başlama
- Resmi CameraX örnek uygulaması
- En Son CameraX Video Capture API Listesi
- CameraX sürüm notları
- CameraX kaynak kodu