Bu sayfada, yapısı, API ile çalışma, yaşam döngüleriyle çalışma ve kullanım alanlarının nasıl birleştirileceği de dahil olmak üzere CameraX mimarisi ele alınmaktadır.
CameraX yapısı
Kullanım alanı adı verilen bir soyutlama ile cihazın kamerasıyla arayüz oluşturmak için CameraX'i kullanabilirsiniz. Aşağıdaki kullanım alanları mevcuttur:
- Önizleme: Önizleme 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 çekme: Fotoğraf çeker ve kaydeder.
- Video çekimi:
VideoCapture
ile video ve ses kaydedin
Kullanım alanları eşzamanlı olarak birleştirilebilir ve etkin olabilir. Örneğin, bir uygulama, önizleme kullanım alanı kullanarak kullanıcının kameranın gördüğü resmi görüntülemesine izin verebilir, fotoğraftaki kişilerin gülümsemelerini belirleyen bir görüntü analizi kullanım alanına sahip olabilir ve fotoğraf çekildikten sonra resim çekmek için bir kullanım alanı ekleyebilir.
API modeli
Kitaplıkta çalışmak için şunları belirtirsiniz:
- Yapılandırma seçenekleriyle istenen kullanım alanı.
- Dinleyici ekleyerek çıkış verileriyle ne yapmalı?
- Kullanım alanını Android Mimarisi Yaşam Döngüleri'ne bağlayarak kameraların ne zaman etkinleştirileceği ve ne zaman veri üretileceği gibi amaçlanan akış.
CameraX uygulaması yazmanın 2 yolu vardır: CameraController
(KameraX'ı kullanmanın en basit yolunu istiyorsanız idealdir) veya
CameraProvider
(daha fazla esnekliğe
ihtiyacınız varsa harikadır).
Kamera Kumandası
CameraController
, CameraX temel işlevlerinin çoğunu tek bir sınıfta sağlar. Az kurulum kodu gerektirir ve kamerayı başlatma, kullanım alanı yönetimi, hedef döndürme, dokunarak odaklamak için dokunma, yakınlaştırmak için sıkıştırma ve diğer işlemleri otomatik olarak yapar. CameraController
öğesini genişleten somut 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 etkinleştirmek için setEnabledUseCases()
yöntemini kullanın.
CameraController
ürününün diğer kullanım şekilleri için QR Kodu tarayıcı örneğine veya CameraController
ile ilgili temel bilgiler videosunu izleyin.
Kamera Sağlayıcısı
CameraProvider
kullanımı yine de kolaydır ancak kurulumun daha büyük bir kısmını uygulama geliştiricisi yaptığı için yapılandırmayı özelleştirmek için daha fazla fırsat sunulabilir. Örneğin, çıkış resmi rotasyonunu etkinleştirebilir veya ImageAnalysis
ürününde çıkış resmi biçimini ayarlayabilirsiniz. Ayrıca, kamera önizlemesi için özel bir Surface
kullanabilirsiniz. Böylece, daha fazla esneklik elde ederken CameraController'da PreviewView
kullanmanız gerekir. Uygulamanızın diğer bölümlerine giriş niteliğindeyse mevcut Surface
kodunuzu kullanmak yararlı olabilir.
Kullanım alanlarını set()
yöntemleriyle yapılandırır ve build()
yöntemiyle sonuçlandırırsı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öntem çağrısı sağlar.
Uygulama, onResume()
ve onPause()
içinde belirli bir başlatma ve durdurma yöntemi çağrıları yapmak yerine, cameraProvider.bindToLifecycle()
kullanarak kameranın ilişkilendirileceği bir yaşam döngüsü belirler.
Bu yaşam döngüsü daha sonra CameraX'e, kamera ç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 bir kullanım alanıyla ilgili uygulama adımları için Önizleme uygulama, Resimleri analiz etme, Görüntü yakalama ve Video yakalama konularına bakın.
Önizleme kullanım alanı, görüntülü reklam için Surface
ile etkileşimde bulunur. Uygulamalar, kullanım alanını aşağıdaki kodu kullanarak yapılandırma seçenekleriyle 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ı, çekim oturumunun ne zaman oluşturulacağını ve ne zaman durup 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ı karışımları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ça halinde gruplandırın ve ardından parçalar arasında geçiş yapın.
- Özel bir yaşam döngüsü bileşeni oluşturup bu bileşenle kamera yaşam döngüsünü manuel olarak kontrol etme
Görünüm 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 bir kullanım alanının bağlantısını ayrı ayrı kaldırarak tüm kullanım alanlarının CameraX'ten 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 KameraX'in yakalama oturumunun açılıp kapatılmasını ve kullanım alanlarının bağlantısını kesmesini sağlayabilirsiniz.
Kameranızın tüm işlevleri, yaşam döngüsüne duyarlı tek bir bileşenin (ör. AppCompatActivity
veya AppCompat
parçası) yaşam döngüsüne karşılık geliyorsa istenen tüm kullanım alanlarını bağlarken o bileşenin yaşam döngüsünü kullanmak, yaşam döngüsüne duyarlı bileşen etkin olduğunda kamera işlevselliğinin hazır olmasını ve herhangi bir kaynağı tüketmeden güvenli bir şekilde imha edilmesini sağlar.
Özel Yaşam Döngüsü Sahipleri
İleri düzey durumlarda, uygulamanızı standart bir Android LifecycleOwner
'a bağlamak yerine CameraX oturum yaşam döngüsünü açıkça kontrol etmesini sağlamak için özel bir LifecycleOwner
oluşturabilirsiniz.
Aşağıdaki kod örneğinde basit bir özel LifecycleOwner'ın 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. Bu işlevi uygulamanızda kullanma hakkında daha fazla bilgi için Özel Yaşam Döngüsü Sahiplerini Uygulama konusuna bakın.
Eş zamanlı kullanım alanları
Kullanım alanları eş zamanlı olarak çalışabilir. Kullanım alanları sıralı olarak bir yaşam döngüsüne bağlı olsa da 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. Ayrıca, her iki kullanım alanı için kullanılacak yaşam döngüsünü de belirtir. Böylece, kullanım ömrüne göre hem başlar hem de 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 destekleneceği garanti edilir (Önizleme veya Video Yakalama gerekli olduğunda ancak aynı anda ikisi birden gerekli değildir):
Önizleme veya Video Yakalama | Görüntü yakalama | Analiz | Açıklamalar |
---|---|---|---|
Kullanıcıya bir önizleme veya video kaydedin, fotoğraf çekin ve görüntü akışını analiz edin. | |||
Bir fotoğraf çekin ve görüntü akışını analiz edin. | |||
Kullanıcıya bir önizleme veya video kaydı sağlayın ve fotoğraf çekin. | |||
Kullanıcıya bir önizleme veya video kaydı sunun ve görüntü akışını analiz edin. |
Hem Önizleme hem de Video Yakalama gerekli olduğunda aşağıdaki kullanım alanı kombinasyonları koşullu olarak desteklenir:
Önizle | Video çekimi | Görüntü yakalama | Analiz | Özel koşul |
---|---|---|---|---|
Tüm kameralar için garantili | ||||
LIMITED (veya daha iyi) kameralı cihaz. | ||||
LEVEL_3 (veya daha iyi) kamera cihazı. |
Ayrıca,
- 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
vePreview
kombinasyonunun çalışacağı garanti edilir. OEM uygulamasına bağlı olarak,ImageAnalysis
eklemek de mümkün olmayabilir.VideoCapture
kullanım alanı için uzantılar etkinleştirilemez. Ayrıntılar için Uzantı referansı belgesi'ni inceleyin. - Kamera kapasitesine bağlı olarak, bazı kameralar düşük çözünürlük modlarında bu kombinasyonu destekleyebilir, ancak bazı yüksek çözünürlüklerde aynı kombinasyonu destekleyemez.
Desteklenen donanım düzeyi Camera2CameraInfo
adresinden alınabilir. Örneğin, aşağıdaki kod varsayılan arka kameranın 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ı olacak. Resimleri dosyalara kaydetmek için WRITE_EXTERNAL_STORAGE
izni de gereklidir (Android 10 veya sonraki sürümleri çalıştıran cihazlar hariç).
Uygulamanızın izinlerini yapılandırma hakkında daha fazla bilgi için Uygulama İzni İsteme bölümünü okuyun.
Gereksinimler
CameraX aşağıdaki minimum sürüm gereksinimlerine sahiptir:
- Android API düzeyi 21
- Android Mimari Bileşenleri 1.1.1
Yaşam döngüsüne duyarlı etkinlikler için FragmentActivity
veya AppCompatActivity
kullanın.
Bağımlılıkları belirtme
CameraX'e bağımlılık eklemek için projenize Google Maven deposunu eklemeniz gerekir.
Projeniz için settings.gradle
dosyasını açın ve google()
deposunu aşağıda gösterildiği gibi ekleyin:
Eski
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Aşağıdakini Android bloğunun sonuna ekleyin:
Eski
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" } }
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-rc01" // 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-rc01" // 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 şartlara uyacak şekilde yapılandırma hakkında daha fazla bilgi edinmek için Bağımlılıkları bildirme bölümüne bakın.
Camera2 ile CameraX birlikte çalışabilirliği
CameraX, Kamera2'de yerleşik olarak bulunur ve CameraX, Camera2 uygulamasında özellikleri okuma ve hatta yazma yöntemlerini gösterir. Tüm ayrıntılar için Interop paketine göz atın.
CameraX'ın Camera2 özelliklerini nasıl yapılandırdığı hakkında daha fazla bilgi edinmek için Camera2CameraInfo
kullanarak temel CameraCharacteristics
öğesini okuyun. Temel Camera2 özelliklerini aşağıdaki iki yoldan birinde yazmayı da seçebilirsiniz:
Temel
CaptureRequest
öğesinde otomatik odaklama modu gibi özellikleri ayarlamanıza olanak tanıyanCamera2CameraControl
özelliğini kullanın.CameraX'i
UseCase
birCamera2Interop.Extender
ile uzatın. Bu, CaptureRequest'teCamera2CameraControl
gibi özellikleri ayarlamanıza olanak tanır. Ayrıca yayın kullanım alanını, kamerayı kullanım senaryonuza göre optimize etmek gibi bazı ek kontroller de sunar. Daha fazla bilgi için Daha iyi performans için Akış Kullanım Alanlarını Kullanma bölümüne bakın.
Aşağıdaki kod örneğinde, görüntülü görüşme için optimizasyon yapmak amacıyla akış kullanım alanları kullanılmaktadır.
Görüntülü görüşme akışı kullanım alanının mevcut olup olmadığını öğrenmek için Camera2CameraInfo
simgesini kullanın. Ardından, temel akış kullanım alanını belirlemek 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ı
Kod örneği