CameraX mimarisi

Bu sayfada, yapısı, API ile nasıl çalışılacağı, yaşam döngüleriyle nasıl çalışılacağı ve kullanım alanlarının nasıl birleştirileceği de dahil olmak üzere CameraX mimarisi ele alınmaktadır.

CameraX yapısı

CameraX'i, kullanım alanı adı verilen bir soyutlama üzerinden cihazın kamerasıyla arayüz oluşturmak için kullanabilirsiniz. Aşağıdaki kullanım alanları mevcuttur:

  • Önizleme: Önizlemeyi görüntülemek için PreviewView gibi bir yüzeyi kabul eder.
  • Görüntü analizi: Makine öğrenimi gibi analizler için CPU tarafından erişilebilen arabellekler sağlar.
  • Resim yakalama: Bir fotoğraf çeker ve kaydeder.
  • Video yakalama: VideoCapture ile video ve ses yakalayın

Kullanım alanları birleştirilebilir ve eşzamanlı olarak etkin olabilir. Örneğin, bir uygulama kullanıcının, önizleme kullanım alanı kullanarak kameranın gördüğü resmi görüntülemesine izin verebilir, fotoğraftaki kişilerin gülümseyip gülümsemediğini belirleyen bir görüntü analizi kullanım alanı içerebilir ve kullanıcılar geldiklerinde bir resim çekmek için görüntü yakalama kullanım alanı içerebilir.

API modeli

Kitaplıkla çalışmak için aşağıdakileri belirtmeniz gerekir:

  • Yapılandırma seçenekleriyle istenen kullanım alanı.
  • İşleyiciler ekleyerek çıkış verileriyle ne yapılacağı.
  • Kullanım alanını Android Mimarisi Yaşam Döngüleri'ne bağlayarak, kameraların ne zaman etkinleştirileceği ve verilerin ne zaman üretileceği gibi amaçlanan akış.

CameraX uygulaması yazmanın 2 yolu vardır: CameraController (KameraX'i en kolay şekilde kullanmak istiyorsanız ideal) veya CameraProvider (daha fazla esnekliğe ihtiyacınız varsa idealdir).

Kamera Denetleyicisi

CameraController, CameraX temel işlevlerinin çoğunu tek bir sınıfta sunar. Çok az kurulum kodu gerektiren bu uygulama; kamera başlatma, kullanım alanı yönetimi, hedef döndürme, dokunarak odaklama, yakınlaştırmak için sıkıştırma ve daha pek çok işlemi otomatik olarak gerçekleştirir. CameraController boyunca uzanan beton sınıfı LifecycleCameraController şeklindedir.

Kotlin

val previewView: PreviewView = viewBinding.previewView
var cameraController = LifecycleCameraController(baseContext)
cameraController.bindToLifecycle(this)
cameraController.cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
previewView.controller = cameraController

Java

PreviewView previewView = viewBinding.previewView;
LifecycleCameraController cameraController = new LifecycleCameraController(baseContext);
cameraController.bindToLifecycle(this);
cameraController.setCameraSelector(CameraSelector.DEFAULT_BACK_CAMERA);
previewView.setController(cameraController);

CameraController için varsayılan UseCase değerleri Preview, ImageCapture ve ImageAnalysis şeklindedir. ImageCapture veya ImageAnalysis özelliğini devre dışı bırakmak ya da VideoCapture özelliğini açmak için setEnabledUseCases() yöntemini kullanın.

CameraController işlevinin diğer kullanımları için QR Kodu tarayıcı örneğine veya CameraController ile ilgili temel bilgiler videosuna bakın.

KameraSağlayıcı

CameraProvider'nin kullanımı yine de kolaydır ancak kurulumun büyük kısmını uygulama geliştirici halleder. Bu nedenle, ImageAnalysis ürününde çıkış resmi döndürmeyi etkinleştirme veya çıktı resmi biçimini ayarlama gibi, yapılandırmayı özelleştirmek için daha fazla fırsat vardır. Ayrıca, kamera önizlemesi için daha fazla esneklik sağlayan özel bir Surface kullanabilirsiniz. CameraController ile ise bir PreviewView kullanmanız gerekir. Mevcut Surface kodunuzu kullanmak, uygulamanızın diğer bölümleri için zaten girişse yararlı olabilir.

Kullanım alanlarını set() yöntemleri kullanarak yapılandırır ve build() yöntemiyle tamamlarsınız. Her kullanım alanı nesnesi, kullanım alanına özel bir dizi API sağlar. Örneğin, görüntü yakalama kullanım alanı bir takePicture() yöntemi çağrısı sağlar.

Uygulama, onResume() ve onPause() içine belirli başlatma ve durdurma yöntemi çağrıları yerleştirmek yerine, cameraProvider.bindToLifecycle() kullanarak kamerayı ilişkilendirecek bir yaşam döngüsü belirtir. Bu yaşam döngüsü daha sonra CameraX'e kamerayla çekim oturumunun ne zaman yapılandırılacağı konusunda bilgi verir ve kamera durumu değişikliklerinin yaşam döngüsü geçişlerine uygun şekilde yapılmasını sağlar.

Her kullanım alanına yönelik uygulama adımları için Önizleme uygulama, Görüntüleri analiz etme, Resim yakalama ve Video yakalama bölümlerine göz atın.

Önizleme kullanım alanı, görüntüleme için bir Surface ile etkileşime girer. Uygulamalar, aşağıdaki kodu kullanarak yapılandırma seçenekleriyle birlikte kullanım alanı oluşturur:

Kotlin

val preview = Preview.Builder().build()
val viewFinder: PreviewView = findViewById(R.id.previewView)

// The use case is bound to an Android Lifecycle with the following code
val camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview)

// PreviewView creates a surface provider and is the recommended provider
preview.setSurfaceProvider(viewFinder.getSurfaceProvider())

Java

Preview preview = new Preview.Builder().build();
PreviewView viewFinder = findViewById(R.id.view_finder);

// The use case is bound to an Android Lifecycle with the following code
Camera camera = cameraProvider.bindToLifecycle(lifecycleOwner, cameraSelector, preview);

// PreviewView creates a surface provider, using a Surface from a different
// kind of view will require you to implement your own surface provider.
preview.previewSurfaceProvider = viewFinder.getSurfaceProvider();

Daha fazla örnek kod için resmi CameraX örnek uygulamasına bakın.

CameraX Yaşam Döngüleri

CameraX; kameranın ne zaman açılacağını, ne zaman çekim oturumu oluşturulacağını ve ne zaman durdurulup kapatılacağını belirlemek için bir yaşam döngüsü gözlemler. Kullanım alanı API'leri, ilerlemeyi izlemek için yöntem çağrıları ve geri çağırmalar sağlar.

Kullanım alanlarını birleştirme bölümünde açıklandığı gibi, bazı kullanım alanı karmalarını tek bir yaşam döngüsüne bağlayabilirsiniz. Uygulamanızın birleştirilemeyen kullanım alanlarını desteklemesi gerektiğinde aşağıdakilerden birini yapabilirsiniz:

  • Uyumlu kullanım alanlarını birden fazla parçada gruplandırın ve ardından parçalar arasında geçiş yapın
  • Özel bir yaşam döngüsü bileşeni oluşturun ve bunu kullanarak kameranın yaşam döngüsünü manuel olarak kontrol edin

Görüntü ve kamera kullanım alanlarınızın Yaşam Döngüsü sahiplerini ayırırsanız (örneğin, özel bir yaşam döngüsü veya saklama parçası kullanıyorsanız) ProcessCameraProvider.unbindAll() kullanarak veya her kullanım alanının bağlantısını ayrı ayrı kaldırarak tüm kullanım alanlarının CameraX'le olan bağlantısının kaldırıldığından emin olmanız gerekir. Alternatif olarak, kullanım alanlarını bir Yaşam Döngüsü'ne bağladığınızda, CameraX'in yakalama oturumunun açılıp kapatılmasını ve kullanım alanlarının bağlantısını kaldırma işlemini yönetmesine izin verebilirsiniz.

Kameranızın tüm işlevleri, AppCompatActivity veya AppCompat parçası gibi yaşam döngüsünü takip eden tek bir bileşenin yaşam döngüsüne denk geliyorsa istenen tüm kullanım alanlarını bağlarken bu bileşenin yaşam döngüsünü kullanmak, yaşam döngüsüne duyarlı bileşen etkin olduğunda ve hiçbir kaynak kullanmadan güvenli bir şekilde imha edildiğinde kamera işlevinin hazır olmasını sağlar.

Özel Yaşam Döngüsü Sahipleri

İleri düzey durumlarda, uygulamanızın standart bir Android LifecycleOwner'a bağlamak yerine CameraX oturum yaşam döngüsünü açık bir şekilde kontrol etmesini sağlamak için özel bir LifecycleOwner oluşturabilirsiniz.

Aşağıdaki kod örneğinde, basit bir özel LifecycleOwner öğesinin nasıl oluşturulacağı gösterilmektedir:

Kotlin

class CustomLifecycle : LifecycleOwner {
    private val lifecycleRegistry: LifecycleRegistry

    init {
        lifecycleRegistry = LifecycleRegistry(this);
        lifecycleRegistry.markState(Lifecycle.State.CREATED)
    }
    ...
    fun doOnResume() {
        lifecycleRegistry.markState(State.RESUMED)
    }
    ...
    override fun getLifecycle(): Lifecycle {
        return lifecycleRegistry
    }
}

Java

public class CustomLifecycle implements LifecycleOwner {
    private LifecycleRegistry lifecycleRegistry;
    public CustomLifecycle() {
        lifecycleRegistry = new LifecycleRegistry(this);
        lifecycleRegistry.markState(Lifecycle.State.CREATED);
    }
   ...
   public void doOnResume() {
        lifecycleRegistry.markState(State.RESUMED);
    }
   ...
    public Lifecycle getLifecycle() {
        return lifecycleRegistry;
    }
}

Uygulamanız bu LifecycleOwner öğesini kullanarak kodunda istenen noktalara durum geçişleri yerleştirebilir. Uygulamanızda bu işlevin uygulanmasıyla ilgili daha fazla bilgi için Özel Yaşam Döngüsü Sahibi uygulama konusuna bakın.

Eşzamanlı kullanım alanları

Kullanım alanları eşzamanlı olarak çalıştırılabilir. Kullanım alanları sıralı bir şekilde bir yaşam döngüsüne bağlanabilir ancak tüm kullanım alanlarını tek bir CameraProcessProvider.bindToLifecycle() çağrısıyla bağlamak daha iyidir. Yapılandırma değişiklikleriyle ilgili en iyi uygulamalar hakkında daha fazla bilgi için Yapılandırma değişikliklerini işleme bölümüne bakın.

Aşağıdaki kod örneğinde uygulama, aynı anda oluşturulup çalıştırılacak iki kullanım alanını belirtir. Her iki kullanım alanı için de kullanılacak yaşam döngüsünü belirtir. Böylece her iki kullanım alanı da yaşam döngüsüne göre başlar ve durur.

Kotlin

private lateinit var imageCapture: ImageCapture

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val cameraProviderFuture = ProcessCameraProvider.getInstance(this)

    cameraProviderFuture.addListener(Runnable {
        // Camera provider is now guaranteed to be available
        val cameraProvider = cameraProviderFuture.get()

        // Set up the preview use case to display camera preview.
        val preview = Preview.Builder().build()

        // Set up the capture use case to allow users to take photos.
        imageCapture = ImageCapture.Builder()
                .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                .build()

        // Choose the camera by requiring a lens facing
        val cameraSelector = CameraSelector.Builder()
                .requireLensFacing(CameraSelector.LENS_FACING_FRONT)
                .build()

        // Attach use cases to the camera with the same lifecycle owner
        val camera = cameraProvider.bindToLifecycle(
                this as LifecycleOwner, cameraSelector, preview, imageCapture)

        // Connect the preview use case to the previewView
        preview.setSurfaceProvider(
                previewView.getSurfaceProvider())
    }, ContextCompat.getMainExecutor(this))
}

Java

private ImageCapture imageCapture;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    PreviewView previewView = findViewById(R.id.previewView);

    ListenableFuture<ProcessCameraProvider> cameraProviderFuture =
            ProcessCameraProvider.getInstance(this);

    cameraProviderFuture.addListener(() -> {
        try {
            // Camera provider is now guaranteed to be available
            ProcessCameraProvider cameraProvider = cameraProviderFuture.get();

            // Set up the view finder use case to display camera preview
            Preview preview = new Preview.Builder().build();

            // Set up the capture use case to allow users to take photos
            imageCapture = new ImageCapture.Builder()
                    .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
                    .build();

            // Choose the camera by requiring a lens facing
            CameraSelector cameraSelector = new CameraSelector.Builder()
                    .requireLensFacing(lensFacing)
                    .build();

            // Attach use cases to the camera with the same lifecycle owner
            Camera camera = cameraProvider.bindToLifecycle(
                    ((LifecycleOwner) this),
                    cameraSelector,
                    preview,
                    imageCapture);

            // Connect the preview use case to the previewView
            preview.setSurfaceProvider(
                    previewView.getSurfaceProvider());
        } catch (InterruptedException | ExecutionException e) {
            // Currently no exceptions thrown. cameraProviderFuture.get()
            // shouldn't block since the listener is being called, so no need to
            // handle InterruptedException.
        }
    }, ContextCompat.getMainExecutor(this));
}

Aşağıdaki yapılandırma kombinasyonlarının desteklendiği garanti edilir (Önizleme veya Video Yakalama gerekli ancak aynı anda ikisi birden desteklenmiyorsa):

Önizleme veya Video Yakalama Görüntü yakalama Analiz Açıklamalar
Kullanıcıya önizleme veya video kaydı sağlayın, fotoğraf çekin ve görüntü akışını analiz edin.
  Fotoğraf çekin ve görüntü akışını analiz edin.
  Kullanıcıya önizleme yapın veya video kaydedin ve fotoğraf çekin.
  Kullanıcıya önizleme veya video kaydı sağlayın ve resim akışını analiz edin.

Hem Önizleme hem de Video Yakalama gerekli olduğunda aşağıdaki kullanım alanı kombinasyonları koşullu olarak desteklenir:

Önizleme Video çekimi Görüntü yakalama Analiz Özel gereksinim
    Tüm kameralar için garantili
  LIMITED (veya daha iyi) kamera cihazı.
  LEVEL_3 (veya daha iyi) kamera cihazı.

Buna ek olarak,

  • Her kullanım alanı kendi başına işe yarayabilir. Örneğin, bir uygulama önizleme kullanmadan video kaydedebilir.
  • Uzantılar etkinleştirildiğinde yalnızca ImageCapture ve Preview kombinasyonunun çalışacağı garanti edilir. OEM uygulamasına bağlı olarak ImageAnalysis öğesi de eklenemeyebilir. Uzantılar, VideoCapture kullanım alanı için etkinleştirilemez. Ayrıntılar için Uzantı referansı belgesi'ni inceleyin.
  • Kamera özelliklerine bağlı olarak, bazı kameralar düşük çözünürlük modlarında kombinasyonu destekleyebilir, ancak bazı yüksek çözünürlüklerde aynı kombinasyonu destekleyemez.

Desteklenen donanım düzeyi Camera2CameraInfo konumundan alınabilir. Örneğin, aşağıdaki kod varsayılan arka kameranın bir LEVEL_3 cihaz olup olmadığını kontrol eder:

Kotlin

@androidx.annotation.OptIn(ExperimentalCamera2Interop::class)
fun isBackCameraLevel3Device(cameraProvider: ProcessCameraProvider) : Boolean {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return CameraSelector.DEFAULT_BACK_CAMERA
            .filter(cameraProvider.availableCameraInfos)
            .firstOrNull()
            ?.let { Camera2CameraInfo.from(it) }
            ?.getCameraCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ==
            CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3
    }
    return false
}

Java

@androidx.annotation.OptIn(markerClass = ExperimentalCamera2Interop.class)
Boolean isBackCameraLevel3Device(ProcessCameraProvider cameraProvider) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        List\ filteredCameraInfos = CameraSelector.DEFAULT_BACK_CAMERA
                .filter(cameraProvider.getAvailableCameraInfos());
        if (!filteredCameraInfos.isEmpty()) {
            return Objects.equals(
                Camera2CameraInfo.from(filteredCameraInfos.get(0)).getCameraCharacteristic(
                        CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL),
                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3);
        }
    }
    return false;
}

İzinler

Uygulamanızın CAMERA iznine ihtiyacı var. Resimleri dosyalara kaydetmek için WRITE_EXTERNAL_STORAGE izninin de olması gerekir (Android 10 veya sonraki sürümleri çalıştıran cihazlar hariç).

Uygulamanızın izinlerini yapılandırma hakkında daha fazla bilgi edinmek için Uygulama İzinleri İsteme bölümünü okuyun.

Şartlar

CameraX'in minimum sürüm gereksinimleri şu şekildedir:

  • Android API düzeyi 21
  • Android Mimarisi Bileşenleri 1.1.1

Yaşam döngüsüne duyarlı etkinlikler için FragmentActivity veya AppCompatActivity kullanın.

Bağımlılıkları bildirme

CameraX'e bağımlılık eklemek için projenize Google Maven deposunu eklemeniz gerekir.

Projenizin settings.gradle dosyasını açın ve google() deposunu aşağıda gösterildiği gibi ekleyin:

Modern

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

Kotlin

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

Android blokunun sonuna aşağıdakileri ekleyin:

Modern

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

Kotlin

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }
    // For Kotlin projects
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

Bir uygulama için her modülün build.gradle dosyasına aşağıdakileri ekleyin:

Modern

dependencies {
  // CameraX core library using the camera2 implementation
  def camerax_version = "1.4.0-alpha04"
  // The following line is optional, as the core library is included indirectly by camera-camera2
  implementation "androidx.camera:camera-core:${camerax_version}"
  implementation "androidx.camera:camera-camera2:${camerax_version}"
  // If you want to additionally use the CameraX Lifecycle library
  implementation "androidx.camera:camera-lifecycle:${camerax_version}"
  // If you want to additionally use the CameraX VideoCapture library
  implementation "androidx.camera:camera-video:${camerax_version}"
  // If you want to additionally use the CameraX View class
  implementation "androidx.camera:camera-view:${camerax_version}"
  // If you want to additionally add CameraX ML Kit Vision Integration
  implementation "androidx.camera:camera-mlkit-vision:${camerax_version}"
  // If you want to additionally use the CameraX Extensions library
  implementation "androidx.camera:camera-extensions:${camerax_version}"
}

Kotlin

dependencies {
    // CameraX core library using the camera2 implementation
    val camerax_version = "1.4.0-alpha04"
    // The following line is optional, as the core library is included indirectly by camera-camera2
    implementation("androidx.camera:camera-core:${camerax_version}")
    implementation("androidx.camera:camera-camera2:${camerax_version}")
    // If you want to additionally use the CameraX Lifecycle library
    implementation("androidx.camera:camera-lifecycle:${camerax_version}")
    // If you want to additionally use the CameraX VideoCapture library
    implementation("androidx.camera:camera-video:${camerax_version}")
    // If you want to additionally use the CameraX View class
    implementation("androidx.camera:camera-view:${camerax_version}")
    // If you want to additionally add CameraX ML Kit Vision Integration
    implementation("androidx.camera:camera-mlkit-vision:${camerax_version}")
    // If you want to additionally use the CameraX Extensions library
    implementation("androidx.camera:camera-extensions:${camerax_version}")
}

Uygulamanızı bu gereksinimleri karşılayacak şekilde yapılandırma hakkında daha fazla bilgi için Bağımlılık bildirme bölümüne bakın.

Camera2 ile CameraX birlikte çalışabilirliği

CameraX, Camera2'de yerleşiktir ve CameraX, Camera2 uygulamasındaki özellikleri okuma ve hatta yazma yolları sunar. Ayrıntılı bilgi için Birlikte çalışabilirlik paketi bölümünü inceleyin.

CameraX'in Camera2 özelliklerini nasıl yapılandırdığı hakkında daha fazla bilgi için alttaki CameraCharacteristics belgesini okumak için Camera2CameraInfo kullanın. Temel Camera2 özelliklerini aşağıdaki iki yoldan birine yazmayı da seçebilirsiniz:

Aşağıdaki kod örneğinde, görüntülü görüşme için optimizasyon yapmak üzere akış kullanım alanları kullanılmaktadır. Görüntülü görüşme akışı kullanım alanının mevcut olup olmadığını getirmek için Camera2CameraInfo ifadesini kullanın. Ardından temel akış kullanım alanını ayarlamak için bir Camera2Interop.Extender kullanın.

Kotlin

// Set underlying Camera2 stream use case to optimize for video calls.

val videoCallStreamId =
    CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL.toLong()

// Check available CameraInfos to find the first one that supports
// the video call stream use case.
val frontCameraInfo = cameraProvider.getAvailableCameraInfos()
    .first { cameraInfo ->
        val isVideoCallStreamingSupported = Camera2CameraInfo.from(cameraInfo)
            .getCameraCharacteristic(
                CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES
            )?.contains(videoCallStreamId)
        val isFrontFacing = (cameraInfo.getLensFacing() == 
                             CameraSelector.LENS_FACING_FRONT)
        (isVideoCallStreamingSupported == true) && isFrontFacing
    }

val cameraSelector = frontCameraInfo.cameraSelector

// Start with a Preview Builder.
val previewBuilder = Preview.Builder()
    .setTargetAspectRatio(screenAspectRatio)
    .setTargetRotation(rotation)

// Use Camera2Interop.Extender to set the video call stream use case.
Camera2Interop.Extender(previewBuilder).setStreamUseCase(videoCallStreamId)

// Bind the Preview UseCase and the corresponding CameraSelector.
val preview = previewBuilder.build()
camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview)

Java

// Set underlying Camera2 stream use case to optimize for video calls.

Long videoCallStreamId =
    CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_VIDEO_CALL.toLong();

// Check available CameraInfos to find the first one that supports
// the video call stream use case.
List<CameraInfo> cameraInfos = cameraProvider.getAvailableCameraInfos();
CameraInfo frontCameraInfo = null;
for (cameraInfo in cameraInfos) {
    Long[] availableStreamUseCases = Camera2CameraInfo.from(cameraInfo)
        .getCameraCharacteristic(
            CameraCharacteristics.SCALER_AVAILABLE_STREAM_USE_CASES
        );
    boolean isVideoCallStreamingSupported = Arrays.List(availableStreamUseCases)
                .contains(videoCallStreamId);
    boolean isFrontFacing = (cameraInfo.getLensFacing() ==
                             CameraSelector.LENS_FACING_FRONT);

    if (isVideoCallStreamingSupported && isFrontFacing) {
        frontCameraInfo = cameraInfo;
    }
}

if (frontCameraInfo == null) {
    // Handle case where video call streaming is not supported.
}

CameraSelector cameraSelector = frontCameraInfo.getCameraSelector();

// Start with a Preview Builder.
Preview.Builder previewBuilder = Preview.Builder()
    .setTargetAspectRatio(screenAspectRatio)
    .setTargetRotation(rotation);

// Use Camera2Interop.Extender to set the video call stream use case.
Camera2Interop.Extender(previewBuilder).setStreamUseCase(videoCallStreamId);

// Bind the Preview UseCase and the corresponding CameraSelector.
Preview preview = previewBuilder.build()
Camera camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview)

Ek kaynaklar

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

Kod laboratuvarı

  • CameraX'i Kullanmaya Başlama
  • Kod örneği

  • CameraX örnek uygulamaları