CameraX video yakalama mimarisi

Yakalama sistemi genellikle video ve ses akışlarını kaydeder, iki akışı karıştırır ve sonuç olarak elde edilen akışı diske yazar.

bir video ve ses yakalama sisteminin kavramsal diyagramı
Şekil 1. Bir video ve ses için kavramsal diyagram yakalama sistemidir.

CameraX'te, video yakalama çözümü VideoCapture Kullanım alanı:

x kamerasının bu hareketi nasıl işlediğini gösteren kavramsal diyagram
         video çekimi kullanım alanı
Şekil 2. CameraX'in nasıl çalıştığını gösteren kavramsal diyagram VideoCapture kullanım alanını kapsıyor.

Şekil 2'de gösterildiği gibi CameraX video yakalama, birkaç üst düzey mimari bileşenler

  • Video kaynağı için SurfaceProvider.
  • Ses kaynağı için AudioSource.
  • Videoyu/sesi kodlamak ve sıkıştırmak için iki kodlayıcı.
  • İki akışı karıştırmak için bir medya muxer.
  • Sonucu yazmak için bir dosya koruyucu.

VideoCapture API, karmaşık yakalama motorunu soyutlar ve bir API ile kullanıma sunuyoruz.

VideoCapture API'ye genel bakış

VideoCapture, kendi başına veya fotoğraf makineleriyle iyi performans gösteren bir CameraX kullanım alanıdır. başka kullanım alanlarıyla birleştirilir. Desteklenen belirli kombinasyonlar donanım özelliklerini kullanıyor, ancak Preview ve VideoCapture bir kullanım alanı kombinasyonuna sahip olmalıdır.

VideoCapture API, aşağıdakileri yapan aşağıdaki nesnelerden oluşur: şu uygulamalarla:

  • VideoCapture kullanım alanı sınıfını kullanabilirsiniz. VideoCapture, şunlara bağlanır: CameraSelector ve başka bir CameraX ile LifecycleOwner Kullanım Durumları. Bu kavramlar ve kullanımlar hakkında daha fazla bilgi için KameraX Mimarisi.
  • Recorder, bir VideoCapture ile sıkı sıkıya bağlantılı VideoÇıktı uygulamasının uygulanması. Recorder, video ve ses yakalamayı gerçekleştirmek için kullanılır. uygulaması bir Recorder kaynağından kayıtlar oluşturur.
  • PendingRecording kaydı yapılandırarak sesi etkinleştirme ve ayar yapma gibi seçenekler sunar yardımcı olur. PendingRecording oluşturmak için Recorder kullanmalısınız. PendingRecording hiçbir şey kaydetmez.
  • Recording, şu işlemleri gerçekleştirir: gerçek kayıt. Recording oluşturmak için PendingRecording kullanmalısınız.

Şekil 3 bu nesneler arasındaki ilişkileri gösterir:

bir videoda gerçekleşen etkileşimleri gösteren diyagram
         kullanım alanını yakala
Şekil 3. Gerçekleşen etkileşimleri gösteren diyagram kullanım örneğinde olduğu gibi.

Gösterge:

  1. Şununla bir Recorder oluşturun: QualitySelector.
  2. Recorder öğesini OutputOptions
  3. Sesi şununla etkinleştir: withAudioEnabled() bakın.
  4. start() numaralı telefonu arayın VideoRecordEvent ile dinleyiciyi seçin.
  5. pause()/resume()/stop() adresini şurada kullanın: Recording kullanabilirsiniz.
  6. VideoRecordEvents adlı kullanıcıya yanıt verin kullanabilirsiniz.

Ayrıntılı API listesi, kaynak kodundaki current.txt dosyasında bulunur.

VideoCapture API'yi kullanma

CameraX VideoCapture kullanım alanını uygulamanıza entegre etmek için şunları yapın:

  1. VideoCapture bağla.
  2. Kaydı hazırlama ve yapılandırma.
  3. Çalışma zamanı kaydını başlatın ve kontrol edin.

Aşağıdaki bölümlerde, kalite puanı almak için her adımda baştan sona kayıt oturumundan bahsettik.

Video Yakalama'yı Bağla

VideoCapure kullanım alanını bağlamak için aşağıdakileri yapın:

  1. Bir Recorder nesnesi oluşturun.
  2. VideoCapture nesnesi oluşturun.
  3. Bir Lifecycle bağlayın.

CameraX VideoCapture API, oluşturucu tasarım kalıbına uyar. Uygulamalar Recorder oluşturmak için Recorder.Builder öğesini kullanın. Ayrıca, QualitySelector nesnesi aracılığıyla Recorder için video çözünürlüğü.

CameraX Recorder, aşağıdaki önceden tanımlanmış Qualities özelliklerini destekler video çözünürlükleri için:

  • 4K ultra HD video boyutu için Quality.UHD (2160p)
  • Tam HD video boyutu (1080p) için Quality.FHD
  • HD video boyutu (720p) için Quality.HD
  • SD video boyutu (480p) için Quality.SD

KameraX'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 özellikler. Daha fazla bilgi için CamcorderProfile.

Uygulamalar, bir QualitySelector. Aşağıdaki yöntemlerden birini kullanarak bir QualitySelector oluşturabilirsiniz:

  • fromOrderedList() kullanarak birkaç tercih edilen çözünürlük belirtin ve kullanılmaması durumunda kullanılacak bir yedek desteklenen çözünürlükler desteklenir.

    CameraX, seçilen kameranın özelliklerine dayalı olarak en iyi yedek eşleşmeye karar verebilir. özelliği, QualitySelector FallbackStrategy specification dokümanına bakın inceleyebilirsiniz. Örneğin, aşağıdaki kodda desteklenen en yüksek ve istek çözümlerinden hiçbiri desteklenmiyorsa KameraX'e, Quality.SD çözünürlüğüne en yakın olanı seçmesi için yetki verin:

    val qualitySelector = QualitySelector.fromOrderedList(
             listOf(Quality.UHD, Quality.FHD, Quality.HD, Quality.SD),
             FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))
    
  • Önce kamera özelliklerini sorgulayın ve desteklenen QualitySelector::from() kullanan çözünürlükler:

    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()
        }
    }
    
    

    Döndürülen özelliğin QualitySelector.getSupportedQualities() VideoCapture kullanım alanı veya VideoCapture ve Preview kullanım alanlarının bir arada kullanılması. Şununla birbirine bağlarken: ImageCapture veya ImageAnalysis kullanım alanı, CameraX gereken kombinasyon şurada desteklenmediğinde bile bağlama başarısız olabilir: kamera ekleyebilirsiniz.

QualitySelector edinildikten sonra uygulama bir VideoCapture nesnesini tanımlayın ve bağlamayı gerçekleştirin. Bu bağlamanın Aynı durum diğer kullanım alanlarıyla aynıdır:

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 etmeyle ilgili daha fazla bilgi için bu kılavuza bakın.

Recorder, sistem için en uygun biçimi seçer. En yaygın olarak kullanılan video codec'i H.264 AVC) kapsayıcı biçimi MPEG-4

Kaydı yapılandır ve oluştur

Uygulama, bir Recorder'den kayıt nesnelerini oluşturabilir: video ve ses yakalama işlemini gerçekleştirmeniz gerekir. Uygulamalar, kayıtları şu:

  1. OutputOptions öğesini prepareRecording() ile yapılandırın.
  2. (İsteğe bağlı) Ses kaydını etkinleştirin.
  3. start() kullanın VideoRecordEvent ve video kaydını başlatın.

start() işlevini çağırdığınızda Recorder, bir Recording nesnesi döndürür. Uygulamanız işlemi tamamlamak için bu Recording nesnesini kullanabilir veya duraklatma ya da devam ettirme gibi başka işlemler gerçekleştirmek için kullanılabilir.

Recorder, tek seferde bir Recording nesnesini destekler. Oturum boyunca Recording.stop() adlı kişiyi aradıktan sonra yeni kayıt veya Önceki Recording nesnede Recording.close().

Bu adımları daha ayrıntılı bir şekilde inceleyelim. İlk olarak, uygulama Recorder.prepareRecording() özellikli Kaydedici için OutputOptions. Recorder, aşağıdaki OutputOptions türlerini destekler:

  • içine çekmek için FileDescriptorOutputOptions FileDescriptor
  • File yakalamak için FileOutputOptions.
  • içine çekmek için MediaStoreOutputOptions MediaStore

Tüm OutputOptions türleri, setFileSizeLimit(). Diğer seçenekler bağımsız çıkışa özgüdür türü, örneğin FileDescriptorOutputOptions için ParcelFileDescriptor.

prepareRecording(), PendingRecording nesnesini döndürür. karşılık gelen öğeyi oluşturmak için kullanılan ara nesne Recording nesne. PendingRecording geçici bir sınıf, çoğu durumda görünmez ve uygulama tarafından nadiren önbelleğe alınır.

Uygulamalar kaydı daha fazla yapılandırabilir. Örneğin:

  • withAudioEnabled() ile sesi etkinleştirin.
  • Video kaydı etkinliklerini almak için bir dinleyici kaydedin start(Executor, Consumer<VideoRecordEvent>) ile birlikte.
  • Video Yakalama eklenmişken bir kaydın sürekli olarak kayıt yapmasına izin verme başka bir kameraya ribaundunu göndermek, PendingRecording.asPersistentRecording()

Kaydetmeye başlamak için PendingRecording.start() numaralı telefonu arayın. CameraX, videodaki PendingRecording öğesi Recording içine alını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ıktan sonra CameraX, VideoRecordEvent.EVENT_TYPE_START etkinliği.

Aşağıdaki örnekte bir MediaStore dosyası:

// 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 kameraya yansıtılırken videolar VideoCapture tarafından kaydedilen videolar varsayılan olarak yansıtılmaz. CameraX 1.3 ile, Artık video kayıtlarının ön kamera önizlemesi ve kaydedilmiş video eşleşmesi.

Üç MirrorMode seçeneği vardır: MIRROR_MODE_OFF, MIRROR_MODE_ON ve SADECE MIRROR_MODE_ON_FRONT_ONLY. kamera önizlemesinde, Google MIROR_MODE_ON_FRONT_ONLY kullanmanızı önerir. Bu, verileri yansıma arka kamerada etkin değil, ancak ön kamerada etkinleştirilmiş bulun. MirrorMode hakkında daha fazla bilgi için şuraya bakın: MirrorMode constants.

Bu kod snippet'i, VideoCapture.Builder.setMirrorMode(), MIRROR_MODE_ON_FRONT_ONLY kullanıyor. Örneğin, Daha fazla bilgi için bkz. 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);

Etkin bir kaydı kontrol etme

Devam eden bir Recording işlemini aşağıdaki işlemleri yaparak duraklatabilir, devam ettirebilir ve durdurabilirsiniz: kullanabilirsiniz:

  • pause geçerli etkin kaydı duraklatın.
  • resume() devam ettirebilirsiniz.
  • stop() kullanarak kaydı bitirin ve ilişkili kayıt nesnelerini temizleyin.
  • mute() tuşuna basarak geçerli kaydın sesini kapatabilir veya açabilirsiniz.

Bir Recording hesabını feshetmek için stop() numaralı telefonu çağırabileceğinizi unutmayın. kaydın duraklatılmış veya etkin kayıt durumunda olup olmadığını gösterir.

Mevcut bir EventListener PendingRecording.start(), Recording iletişim kurar üzerinde bir VideoRecordEvent.

  • VideoRecordEvent.EVENT_TYPE_STATUS, şu tür istatistikleri kaydetmek için kullanılır: geçerli dosya boyutu ve kaydedilen zaman aralığı olarak gösterir.
  • Kayıt sonucu için VideoRecordEvent.EVENT_TYPE_FINALIZE kullanılır ve son dosyanın URI'si gibi bilgileri içerir. kontrol edin.

Uygulamanız, başarılı olduğunu gösteren bir EVENT_TYPE_FINALIZE aldığında oluşturduktan sonra, kaydedilen videoya mobil cihazınızın OutputOptions içinde belirtilir.

Ek kaynaklar

CameraX hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara bakın: