หน้านี้ครอบคลุมสถาปัตยกรรมของ CameraX ซึ่งรวมถึงโครงสร้าง วิธีการทำงานกับ API วิธีการทำงานกับวงจร และวิธีรวม Use Case
โครงสร้าง CameraX
คุณใช้ CameraX เพื่อเชื่อมต่อกับกล้องของอุปกรณ์ผ่าน การแยกส่วนที่เรียกว่า Use Case ได้ กรณีการใช้งานที่พร้อมใช้งานมีดังนี้
- แสดงตัวอย่าง: รับพื้นผิวเพื่อแสดงตัวอย่าง เช่น
PreviewView - การวิเคราะห์รูปภาพ: จัดเตรียมบัฟเฟอร์ที่ CPU เข้าถึงได้สำหรับการวิเคราะห์ เช่น สำหรับ แมชชีนเลิร์นนิง
- การจับภาพ: จับภาพและบันทึกรูปภาพ
- การจับภาพวิดีโอ: จับภาพวิดีโอและเสียงด้วย
VideoCapture
คุณสามารถรวม Use Case และเปิดใช้งานพร้อมกันได้ เช่น แอปอาจอนุญาตให้ ผู้ใช้ดูรูปภาพที่กล้องเห็นโดยใช้กรณีการใช้งานตัวอย่าง มีกรณีการใช้งานการวิเคราะห์รูปภาพที่ระบุว่าผู้คนในรูปภาพกำลังยิ้มหรือไม่ และมีกรณีการใช้งานการจับภาพเพื่อถ่ายรูปเมื่อผู้คนยิ้ม
โมเดล API
หากต้องการใช้ไลบรารี คุณต้องระบุสิ่งต่อไปนี้
- กรณีการใช้งานที่ต้องการพร้อมตัวเลือกการกำหนดค่า
- สิ่งที่ต้องทำกับข้อมูลเอาต์พุตโดยการแนบ Listener
- โฟลว์ที่ต้องการ เช่น เมื่อใดควรเปิดใช้กล้องและเมื่อใดควรสร้างข้อมูล โดยการเชื่อมโยง Use Case กับวงจรของสถาปัตยกรรม Android
การเขียนแอป CameraX ทำได้ 2 วิธี ได้แก่
CameraController (เหมาะหากต้องการวิธีที่ง่ายที่สุดในการใช้ CameraX) หรือ
CameraProvider (เหมาะหากต้องการความยืดหยุ่นมากขึ้น)
CameraController
CameraController มีฟังก์ชันหลักส่วนใหญ่ของ CameraX ในคลาสเดียว โดยไม่ต้องใช้โค้ดการตั้งค่ามากนัก และจะจัดการการเริ่มต้นกล้อง การจัดการ Use Case การหมุนเป้าหมาย การแตะเพื่อโฟกัส การบีบนิ้วเพื่อซูม และอื่นๆ โดยอัตโนมัติ
คลาสที่เป็นรูปธรรมซึ่งขยาย CameraController คือ
LifecycleCameraController
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);
UseCase เริ่มต้นสำหรับ CameraController คือ Preview, ImageCapture และ ImageAnalysis หากต้องการปิด ImageCapture หรือ ImageAnalysis หรือเปิด
VideoCapture ให้ใช้เมธอด
setEnabledUseCases()
ดูการใช้งาน CameraController เพิ่มเติมได้ที่
ตัวอย่างตัวสแกนคิวอาร์โค้ด
หรือ
วิดีโอพื้นฐานเกี่ยวกับ CameraController
CameraProvider
CameraProvider ยังคงใช้งานง่าย แต่เนื่องจากนักพัฒนาแอปจัดการการตั้งค่าเพิ่มเติม จึงมีโอกาสมากขึ้นในการปรับแต่งการกำหนดค่า เช่น การเปิดใช้การหมุนรูปภาพเอาต์พุตหรือการตั้งค่ารูปแบบรูปภาพเอาต์พุตใน ImageAnalysis นอกจากนี้ คุณยังใช้ Surface ที่กำหนดเองสำหรับตัวอย่างกล้องได้ด้วย ซึ่งจะช่วยให้มีความยืดหยุ่นมากขึ้น ในขณะที่ CameraController กำหนดให้คุณต้องใช้ PreviewView การใช้โค้ด Surface ที่มีอยู่จะเป็นประโยชน์หากโค้ดนั้น
เป็นอินพุตไปยังส่วนอื่นๆ ของแอปอยู่แล้ว
คุณกำหนดค่า Use Case โดยใช้set()เมธอด และทำให้เสร็จสมบูรณ์ด้วยเมธอด build()
ออบเจ็กต์กรณีการใช้งานแต่ละรายการจะมีชุด API เฉพาะกรณีการใช้งาน ตัวอย่างเช่น กรณีการใช้งานการจับภาพจะมีการเรียกใช้เมธอด takePicture()
แทนที่จะให้แอปพลิเคชันวางการเรียกเมธอดเริ่มต้นและหยุดที่เฉพาะเจาะจงใน
onResume() และ onPause() แอปพลิเคชันจะระบุวงจรเพื่อเชื่อมโยง
กล้องด้วยการใช้
cameraProvider.bindToLifecycle()
จากนั้นวงจรนั้นจะแจ้งให้ CameraX ทราบเมื่อใดควรตั้งค่าเซสชันการจับภาพของกล้อง
และตรวจสอบว่าการเปลี่ยนแปลงสถานะของกล้องเป็นไปอย่างเหมาะสมเพื่อให้ตรงกับการเปลี่ยนวงจร
ดูขั้นตอนการติดตั้งใช้งานสำหรับกรณีการใช้งานแต่ละกรณีได้ที่ติดตั้งใช้งาน การแสดงตัวอย่าง วิเคราะห์ รูปภาพ การ จับภาพ และการจับภาพวิดีโอ
กรณีการใช้งานการแสดงตัวอย่างจะโต้ตอบกับ
Surfaceเพื่อแสดง แอปพลิเคชัน
สร้างกรณีการใช้งานด้วยตัวเลือกการกำหนดค่าโดยใช้โค้ดต่อไปนี้
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();
ดูโค้ดตัวอย่างเพิ่มเติมได้ที่แอปตัวอย่าง CameraX อย่างเป็นทางการ
วงจรของ CameraX
CameraX จะสังเกตวงจรของออบเจ็กต์เพื่อพิจารณาว่าจะเปิดกล้องเมื่อใด จะสร้างเซสชันการจับภาพเมื่อใด และจะหยุดและปิดเมื่อใด API กรณีการใช้งานมี การเรียกเมธอดและ Callback เพื่อตรวจสอบความคืบหน้า
ดังที่อธิบายไว้ในรวม Use Case คุณสามารถเชื่อมโยง Use Case บางอย่างเข้ากับวงจรเดียวได้ เมื่อแอปต้องรองรับกรณีการใช้งานที่ ใช้ร่วมกันไม่ได้ คุณจะทำอย่างใดอย่างหนึ่งต่อไปนี้ได้
- จัดกลุ่มกรณีการใช้งานที่เข้ากันได้ไว้ด้วยกันเป็นFragment มากกว่า 1 รายการ แล้วสลับไปมาระหว่าง Fragment
- สร้างคอมโพเนนต์วงจรที่กำหนดเองและใช้เพื่อควบคุมวงจรของกล้องด้วยตนเอง
หากแยกเจ้าของวงจรของ Use Case ของการดูและกล้อง (เช่น
หากคุณใช้วงจรที่กำหนดเองหรือretain
fragment) คุณจะต้องตรวจสอบว่าได้ยกเลิกการเชื่อมโยง Use Case ทั้งหมดจาก CameraX โดยใช้
ProcessCameraProvider.unbindAll()
หรือโดยการยกเลิกการเชื่อมโยง Use Case แต่ละรายการแยกกัน หรือเมื่อเชื่อมโยงกรณีการใช้งานกับวงจรของแอป คุณจะให้ CameraX
จัดการการเปิดและปิดเซสชันการจับภาพ รวมถึงยกเลิกการเชื่อมโยงกรณีการใช้งานได้
หากฟังก์ชันการทำงานทั้งหมดของกล้องสอดคล้องกับวงจรของคอมโพเนนต์เดียวที่รับรู้ถึงวงจร เช่น AppCompatActivity หรือ Fragment AppCompat การใช้วงจรของคอมโพเนนต์นั้นเมื่อเชื่อมโยง Use Case ที่ต้องการทั้งหมดจะช่วยให้มั่นใจได้ว่าฟังก์ชันการทำงานของกล้องพร้อมใช้งานเมื่อคอมโพเนนต์ที่รับรู้ถึงวงจรทำงานอยู่ และจะมีการทิ้งอย่างปลอดภัยโดยไม่ใช้ทรัพยากรใดๆ
LifecycleOwner ที่กำหนดเอง
สำหรับกรณีขั้นสูง คุณสามารถสร้าง
LifecycleOwnerที่กำหนดเองเพื่อเปิดใช้แอป
ให้ควบคุมวงจรเซสชัน CameraX อย่างชัดเจนแทนที่จะเชื่อมโยงกับ
LifecycleOwnerมาตรฐานของ Android
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีสร้าง LifecycleOwner ที่กำหนดเองแบบง่าย
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; } }
การใช้ LifecycleOwner นี้จะช่วยให้แอปของคุณวางการเปลี่ยนสถานะในจุดที่ต้องการในโค้ดได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ฟังก์ชันนี้ในแอปได้ที่การใช้
LifecycleOwner ที่กำหนดเอง
กรณีการใช้งานพร้อมกัน
กรณีการใช้งานสามารถทำงานพร้อมกันได้ แม้ว่ากรณีการใช้งานจะเชื่อมโยงกับวงจร
ได้ตามลำดับ แต่การเชื่อมโยงกรณีการใช้งานทั้งหมดด้วยการเรียกใช้
CameraProcessProvider.bindToLifecycle() ครั้งเดียวจะดีกว่า ดูข้อมูลเพิ่มเติมเกี่ยวกับแนวทางปฏิบัติแนะนำสำหรับการเปลี่ยนแปลงการกำหนดค่าได้ที่จัดการการเปลี่ยนแปลงการกำหนดค่า
ในตัวอย่างโค้ดต่อไปนี้ แอปจะระบุ Use Case 2 รายการที่จะสร้าง และเรียกใช้พร้อมกัน นอกจากนี้ยังระบุวงจรที่จะใช้สำหรับทั้ง 2 กรณีการใช้งาน เพื่อให้ทั้ง 2 กรณีเริ่มต้นและหยุดตามวงจร
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)); }
CameraX อนุญาตให้ใช้ Preview,
VideoCapture, ImageAnalysis และ ImageCapture พร้อมกันได้ครั้งละ 1 อินสแตนซ์ นอกจากนี้
- กรณีการใช้งานแต่ละรายการสามารถทำงานได้ด้วยตัวเอง เช่น แอปสามารถบันทึกวิดีโอ โดยไม่ต้องใช้ตัวอย่าง
- เมื่อเปิดใช้ส่วนขยาย จะรับประกันว่าเฉพาะการผสมผสานระหว่าง
ImageCaptureและPreviewเท่านั้นที่จะใช้งานได้ ทั้งนี้ขึ้นอยู่กับการติดตั้งใช้งานของ OEM คุณอาจเพิ่มImageAnalysisไม่ได้ และเปิดใช้ส่วนขยายสำหรับ Use Case ของVideoCaptureไม่ได้ ดูรายละเอียดได้ที่เอกสารอ้างอิงส่วนขยาย - กล้องบางรุ่นอาจรองรับการผสมผสานใน โหมดความละเอียดต่ำกว่า แต่ไม่รองรับการผสมผสานเดียวกันใน ความละเอียดที่สูงกว่า ทั้งนี้ขึ้นอยู่กับความสามารถของกล้อง
- ในอุปกรณ์ที่มีฮาร์ดแวร์กล้องระดับ
FULLหรือต่ำกว่า การรวมPreview,VideoCaptureและImageCaptureหรือImageAnalysisอาจทำให้ CameraX ต้องทำซ้ำสตรีมPRIVของกล้องสำหรับPreviewและVideoCaptureการทำซ้ำนี้เรียกว่าการแชร์สตรีม ซึ่งช่วยให้ใช้ฟีเจอร์เหล่านี้ได้พร้อมกัน แต่ต้องแลกมาด้วยความต้องการในการประมวลผลที่เพิ่มขึ้น คุณอาจ พบว่าเวลาในการตอบสนองนานขึ้นเล็กน้อยและอายุการใช้งานแบตเตอรี่ลดลง
ระดับฮาร์ดแวร์ที่รองรับ
สามารถดึงข้อมูลได้จาก Camera2CameraInfo เช่น โค้ดต่อไปนี้
จะตรวจสอบว่ากล้องด้านหลังเริ่มต้นเป็นอุปกรณ์ LEVEL_3 หรือไม่
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\<CameraInfo\> 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; }
สิทธิ์
แอปของคุณจะต้องมีสิทธิ์
CAMERA หากต้องการ
บันทึกรูปภาพลงในไฟล์ แอปจะต้องมีสิทธิ์
WRITE_EXTERNAL_STORAGE
ด้วย ยกเว้นในอุปกรณ์ที่ใช้ Android 10 ขึ้นไป
ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่าสิทธิ์สำหรับแอปได้ที่ขอสิทธิ์ของแอป
ข้อกำหนด
CameraX มีข้อกำหนดขั้นต่ำของเวอร์ชันดังนี้
- ระดับ API 21 ของ Android
- คอมโพเนนต์สถาปัตยกรรมของ Android 1.1.1
สำหรับกิจกรรมที่รับรู้ถึงวงจร ให้ใช้
FragmentActivity หรือ
AppCompatActivity
ประกาศทรัพยากร Dependency
หากต้องการเพิ่มทรัพยากร Dependency ใน CameraX คุณต้องเพิ่มที่เก็บ Google Maven ลงในโปรเจ็กต์
เปิดไฟล์ settings.gradle สำหรับโปรเจ็กต์ แล้วเพิ่มที่เก็บ google()
ตามที่แสดงด้านล่าง
ดึงดูด
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
เพิ่มข้อมูลต่อไปนี้ที่ส่วนท้ายของบล็อก Android
ดึงดูด
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" } }
เพิ่มโค้ดต่อไปนี้ลงในไฟล์ build.gradle ของแต่ละโมดูลสำหรับแอป
Groovy
dependencies { // CameraX core library using the camera2 implementation def camerax_version = "1.7.0-alpha02" // 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.7.0-alpha02" // 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}") }
ดูข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่าแอปให้เป็นไปตามข้อกำหนดเหล่านี้ได้ที่การประกาศ การอ้างอิง
ความสามารถในการทำงานร่วมกันของ CameraX กับ Camera2
CameraX สร้างขึ้นบน Camera2 และแสดงวิธีอ่านและแม้กระทั่งเขียนพร็อพเพอร์ตี้ใน Camera2 โปรดดูรายละเอียดทั้งหมดในแพ็กเกจ Interop
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ CameraX กำหนดค่าพร็อพเพอร์ตี้ Camera2 ได้โดยใช้
Camera2CameraInfo
เพื่ออ่านCameraCharacteristics ที่เกี่ยวข้อง นอกจากนี้ คุณยังเลือกเขียนพร็อพเพอร์ตี้ Camera2
ที่เกี่ยวข้องในเส้นทางใดเส้นทางหนึ่งต่อไปนี้ได้ด้วย
ใช้
Camera2CameraControlซึ่งช่วยให้คุณตั้งค่าพร็อพเพอร์ตี้ในCaptureRequestพื้นฐาน เช่น โหมดโฟกัสอัตโนมัติขยาย
UseCaseของ CameraX ด้วยCamera2Interop.Extenderซึ่งช่วยให้คุณตั้งค่าพร็อพเพอร์ตี้ใน CaptureRequest ได้เช่นเดียวกับCamera2CameraControlนอกจากนี้ ยังช่วยให้คุณควบคุมเพิ่มเติมได้ เช่น การตั้งค่ากรณีการใช้งานสตรีมเพื่อ เพิ่มประสิทธิภาพกล้องสำหรับสถานการณ์การใช้งานของคุณ ดูข้อมูลได้ที่ใช้ Use Case ของสตรีมเพื่อประสิทธิภาพที่ดีขึ้น
ตัวอย่างโค้ดต่อไปนี้ใช้ Use Case ของสตรีมเพื่อเพิ่มประสิทธิภาพสำหรับการวิดีโอคอล
ใช้ Camera2CameraInfo
เพื่อดึงข้อมูลว่ากรณีการใช้งานสตรีมวิดีโอคอลพร้อมใช้งานหรือไม่ จากนั้นใช้
Camera2Interop.Extender
เพื่อตั้งค่ากรณีการใช้งานสตรีมพื้นฐาน
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)
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับ CameraX ได้จากแหล่งข้อมูลเพิ่มเติมต่อไปนี้
Codelab
ตัวอย่างโค้ด