Tin tức về sản phẩm

Giới thiệu CameraX 1.5: Quay video mạnh mẽ và chụp ảnh chuyên nghiệp

7 phút đọc
Xem hồ sơ của Scott Nien
Scott Nien Kỹ sư phần mềm

Nhóm CameraX rất vui mừng thông báo về việc phát hành phiên bản 1.5! Bản cập nhật mới nhất này tập trung vào việc cung cấp các tính năng chuyên nghiệp ngay trong tầm tay bạn, đồng thời giúp bạn dễ dàng định cấu hình phiên camera hơn bao giờ hết.

Đối với tính năng quay video, giờ đây, người dùng có thể dễ dàng quay video chuyển động chậm hoặc video có tốc độ khung hình cao tuyệt đẹp. Quan trọng hơn, Feature Group API mới cho phép bạn tự tin bật các tổ hợp phức tạp như HDR 10 bit và 60 khung hình/giây, đảm bảo kết quả nhất quán trên các thiết bị được hỗ trợ.

Về mặt chụp ảnh, bạn có thể linh hoạt tối đa nhờ tính năng hỗ trợ chụp tệp DNG (RAW) chưa xử lý, chưa nén. Ngoài ra, giờ đây bạn có thể tận dụng đầu ra Ultra HDR ngay cả khi sử dụng Tiện ích máy ảnh mạnh mẽ.

Nền tảng của các tính năng này là SessionConfig API mới, giúp đơn giản hoá việc thiết lập và định cấu hình lại camera. Bây giờ, hãy cùng tìm hiểu chi tiết về những tính năng mới thú vị này.

Quay video mạnh mẽ: Kết hợp tốc độ cao và nhiều tính năng

CameraX 1.5 mở rộng đáng kể các tính năng quay video, mang đến trải nghiệm quay video sáng tạo và mạnh mẽ hơn.

Video chuyển động chậm và có tốc độ khung hình cao

Một trong những tính năng được mong đợi nhất của chúng tôi, video chuyển động chậm, hiện đã ra mắt. Giờ đây, bạn có thể quay video tốc độ cao (ví dụ: 120 hoặc 240 khung hình/giây) và mã hoá trực tiếp thành video chuyển động chậm ấn tượng. Ngoài ra, bạn có thể quay video ở cùng tốc độ khung hình cao để tạo ra video mượt mà vượt trội.

Việc triển khai tính năng này rất đơn giản nếu bạn đã quen thuộc với API VideoCapture.

1. Kiểm tra khả năng hỗ trợ tốc độ cao: Sử dụng phương thức Recorder.getHighSpeedVideoCapabilities() mới để truy vấn xem thiết bị có hỗ trợ tính năng này hay không.

val cameraInfo = cameraProvider.getCameraInfo(cameraSelector)

val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

if (highSpeedCapabilities == null) {
    // This camera device does not support high-speed video.
    return
}

2. Định cấu hình và liên kết trường hợp sử dụng: Sử dụng videoCapabilities được trả về (chứa thông tin về chất lượng video được hỗ trợ) để tạo HighSpeedVideoSessionConfig. Sau đó, bạn phải truy vấn các dải tốc độ khung hình được hỗ trợ thông qua cameraInfo.getSupportedFrameRateRanges() và đặt dải mong muốn. Gọi setSlowMotionEnabled(true) để quay video chuyển động chậm, nếu không, video sẽ được quay ở tốc độ khung hình cao. Bước cuối cùng là sử dụng Recorder.prepareRecording().start() thông thường để bắt đầu quay video.

val preview = Preview.Builder().build()
val quality = highSpeedCapabilities
        .getSupportedQualities(DynamicRange.SDR).first()

val recorder = Recorder.Builder()
      .setQualitySelector(QualitySelector.from(quality)))
      .build()

val videoCapture = VideoCapture.withOutput(recorder)

val frameRateRange = cameraInfo.getSupportedFrameRateRanges(      
       HighSpeedVideoSessionConfig(videoCapture, preview)
).first()

val sessionConfig = HighSpeedVideoSessionConfig(
    videoCapture, 
    preview, 
    frameRateRange = frameRateRange, 
    // Set true for slow-motion playback, or false for high-frame-rate
    isSlowMotionEnabled = true
)

cameraProvider.bindToLifecycle(
     lifecycleOwner, cameraSelector, sessionConfig)

// Start recording slow motion videos. 
val recording = recorder.prepareRecording(context, outputOption)
      .start(executor, {})

Khả năng tương thích và các giới hạn

Tính năng quay tốc độ cao yêu cầu hỗ trợ CameraConstrainedHighSpeedCaptureSession và CamcorderProfile cụ thể. Luôn thực hiện quy trình kiểm tra khả năng và chỉ bật tính năng quay video tốc độ cao trên các thiết bị được hỗ trợ để tránh mang lại trải nghiệm không tốt cho người dùng. Hiện tại, tính năng này được hỗ trợ trên camera sau của hầu hết các thiết bị Pixel và một số mẫu thiết bị của các nhà sản xuất khác.

Hãy xem bài đăng trên blog để biết thêm thông tin.

Kết hợp các tính năng một cách tự tin: Feature Group API

CameraX 1.5 ra mắt Feature Group API (API Nhóm tính năng), giúp loại bỏ việc phỏng đoán khả năng tương thích của tính năng. Dựa trên API truy vấn kết hợp tính năng của Android 15, giờ đây, bạn có thể tự tin bật nhiều tính năng cùng lúc, đảm bảo phiên camera ổn định. Nhóm tính năng hiện hỗ trợ: HDR (HLG), 60 khung hình/giây, Ổn định bản xem trước và Ultra HDR. Ví dụ: bạn có thể bật đồng thời chế độ HDR, 60 khung hình/giây và tính năng Ổn định bản xem trước trên dòng thiết bị Pixel 10 và Galaxy S25. Chúng tôi dự định sẽ cải tiến thêm trong tương lai, bao gồm cả tính năng quay video 4K và thu phóng góc siêu rộng. 

API nhóm tính năng hỗ trợ hai trường hợp sử dụng thiết yếu:

Trường hợp sử dụng 1: Ưu tiên chất lượng tốt nhất

Nếu muốn chụp bằng cách kết hợp các tính năng tốt nhất có thể, bạn có thể cung cấp danh sách ưu tiên. CameraX sẽ cố gắng bật các chế độ này theo thứ tự, chọn tổ hợp đầu tiên mà thiết bị hỗ trợ đầy đủ.

val sessionConfig = SessionConfig(
    useCases = listOf(preview, videoCapture),
    preferredFeatureGroup = listOf(
        GroupableFeature.HDR_HLG10,
        GroupableFeature.FPS_60,
        GroupableFeature.PREVIEW_STABILIZATION
    )
).apply {
    // (Optional) Get a callback with the enabled features to update your UI.
    setFeatureSelectionListener { selectedFeatures ->
        updateUiIndicators(selectedFeatures)
    }
}
processCameraProvider.bindToLifecycle(activity, cameraSelector, sessionConfig)

Trong ví dụ này, CameraX cố gắng bật các tính năng theo thứ tự sau:

  1. HDR + 60 khung hình/giây + Chống rung khi xem trước
  2. HDR + 60 khung hình/giây
  3. HDR + Chống rung khi xem trước
  4. HDR
  5. 60 khung hình/giây + Chống rung khi xem trước
  6. 60 khung hình/giây
  7. Chống rung khi xem trước
  8. Không có

Trường hợp sử dụng 2: Xây dựng giao diện người dùng cho phần cài đặt dành cho người dùng

Giờ đây, bạn có thể phản ánh chính xác những tổ hợp tính năng được hỗ trợ trong giao diện người dùng cài đặt của ứng dụng, tắt nút bật/tắt cho các tuỳ chọn không được hỗ trợ như hình dưới đây. 

unsupported-features-disabled.gif

Để xác định xem có nên làm mờ nút bật/tắt hay không, hãy sử dụng các mã sau để kiểm tra khả năng hỗ trợ kết hợp tính năng. Ban đầu, hãy truy vấn trạng thái của từng tính năng riêng lẻ. Sau khi bật một tính năng, hãy truy vấn lại các tính năng còn lại bằng các tính năng đã bật để xem liệu các nút bật/tắt của các tính năng đó có phải chuyển sang màu xám do các quy tắc ràng buộc về khả năng tương thích hay không.

fun disableFeatureIfNotSuported(
   enabledFeatures: Set<GroupableFeature>,     
   featureToCheck:GroupableFeature
) {
 val sessionConfig = SessionConfig(
     useCases = useCases,
     requiredFeatureGroup = enabledFeatures + featureToCheck
 )
 val isSupported = cameraInfo.isFeatureGroupSupported(sessionConfig)

 if (!isSupported) {
     // disable the toggle for featureToCheck
 }
}

Vui lòng tham khảo bài đăng trên blog về Nhóm tính năng để biết thêm thông tin. 

Các tính năng nâng cao khác cho video

  • Cải tiến về camera đồng thời: Với CameraX 1.5.1, giờ đây bạn có thể liên kết đồng thời các trường hợp sử dụng Preview + ImageCapture + VideoCapture cho mỗi SingleCameraConfig ở chế độ không kết hợp. Ngoài ra, ở chế độ soạn (cùng trường hợp sử dụng với CompositionSettings), giờ đây, bạn có thể đặt CameraEffect được áp dụng cho kết quả kết hợp cuối cùng.
  • Tắt tiếng linh động: Giờ đây, bạn có thể bắt đầu ghi âm ở trạng thái tắt tiếng bằng PendingRecording.withAudioEnabled(boolean initialMuted) và cho phép người dùng bật tiếng sau bằng Recording.mute(boolean muted).
  • Cải thiện khả năng xử lý khi không đủ bộ nhớ: CameraX hiện gửi lỗi VideoRecordEvent.Finalize.ERROR_INSUFFICIENT_STORAGE một cách đáng tin cậy, cho phép ứng dụng của bạn xử lý linh hoạt các tình huống bộ nhớ thấp và thông báo cho người dùng.
  • Tăng cường ánh sáng yếu: Trên các thiết bị được hỗ trợ (như dòng Pixel 10), bạn có thể bật CameraControl.enableLowLightBoostAsync để tự động làm sáng bản xem trước và luồng video trong môi trường tối.

Chụp ảnh chuyên nghiệp

CameraX 1.5 mang đến những bản nâng cấp lớn cho ImageCapture dành cho những nhà phát triển yêu cầu chất lượng và tính linh hoạt tối đa.

Thoả sức sáng tạo với tính năng chụp ảnh DNG (RAW)

Để có toàn quyền kiểm soát quá trình xử lý hậu kỳ, CameraX hiện hỗ trợ chụp ảnh DNG (RAW). Điều này cho phép bạn truy cập vào dữ liệu hình ảnh chưa xử lý, chưa nén trực tiếp từ cảm biến máy ảnh, giúp bạn chỉnh sửa và phân loại màu ở cấp độ chuyên nghiệp. API hỗ trợ việc chỉ chụp tệp DNG hoặc chụp đồng thời cả tệp JPEG và DNG. Hãy xem mã mẫu bên dưới để biết cách chụp đồng thời tệp JPEG và DNG.

val capabilities = ImageCapture.getImageCaptureCapabilities(cameraInfo)
val imageCapture = ImageCapture.Builder().apply {
    if (capabilities.supportedOutputFormats
             .contains(OUTPUT_FORMAT_RAW_JPEG)) {
        // Capture both RAW and JPEG formats.
        setOutputFormat(OUTPUT_FORMAT_RAW_JPEG)
    }
}.build()
// ... bind imageCapture to lifecycle ...


// Provide separate output options for each format.
val outputOptionRaw = /* ... configure for image/x-adobe-dng ... */
val outputOptionJpeg = /* ... configure for image/jpeg ... */
imageCapture.takePicture(
    outputOptionRaw,
    outputOptionJpeg,
    executor,
    object : ImageCapture.OnImageSavedCallback {
        override fun onImageSaved(results: OutputFileResults) {
            // This callback is invoked twice: once for the RAW file
            // and once for the JPEG file.
        }

        override fun onError(exception: ImageCaptureException) {}
    }
)

Ultra HDR cho Tiện ích máy ảnh

Tận hưởng lợi ích của cả hai thế giới: nhiếp ảnh điện toán tuyệt đẹp của Tiện ích camera (như Chế độ ban đêm) kết hợp với màu sắc rực rỡ và dải động của Ultra HDR. Tính năng này hiện được hỗ trợ trên nhiều điện thoại Android cao cấp gần đây, chẳng hạn như dòng Pixel 9/10 và dòng Samsung S24/S25.

// Support UltraHDR when Extension is enabled. 

val extensionsEnabledCameraSelector = extensionsManager
     .getExtensionEnabledCameraSelector(
        CameraSelector.DEFAULT_BACK_CAMERA, ExtensionMode.NIGHT)

val imageCapabilities = ImageCapture.getImageCaptureCapabilities(
               cameraProvider.getCameraInfo(extensionsEnabledCameraSelector)

val imageCapture = ImageCapture.Builder()
     .apply {
       if (imageCapabilities.supportedOutputFormats
                .contains(OUTPUT_FORMAT_JPEG_ULTRA_HDR) {
           setOutputFormat(OUTPUT_FORMAT_JPEG_ULTRA_HDR)

       }

     }.build()

Cải tiến API cốt lõi và khả năng hữu dụng

Cách mới để định cấu hình: SessionConfig

Như trong các ví dụ trên, SessionConfig là một khái niệm mới trong CameraX 1.5. Thư viện này tập trung hoá cấu hình và đơn giản hoá API theo hai cách chính:

  1. Không còn phải gọi unbind() theo cách thủ công: API CameraX nhận biết được vòng đời. Nó sẽ ngầm "huỷ liên kết" các trường hợp sử dụng của bạn khi hoạt động hoặc LifecycleOwner khác bị huỷ. Tuy nhiên, khi cập nhật các trường hợp sử dụng hoặc chuyển đổi camera, bạn vẫn cần gọi unbind() hoặc unbindAll() trước khi liên kết lại. Giờ đây, với CameraX 1.5, khi bạn liên kết một SessionConfig mới, CameraX sẽ cập nhật phiên một cách liền mạch cho bạn, giúp bạn không cần phải gọi huỷ liên kết.
  2. Kiểm soát tốc độ khung hình tất định: API SessionConfig mới giới thiệu một cách tất định để quản lý tốc độ khung hình. Không giống như setTargetFrameRate trước đây (chỉ là một gợi ý), phương thức mới này đảm bảo phạm vi tốc độ khung hình được chỉ định sẽ được áp dụng khi định cấu hình thành công. Để đảm bảo độ chính xác, bạn phải truy vấn tốc độ khung hình được hỗ trợ bằng CameraInfo.getSupportedFrameRateRanges(SessionConfig). Bằng cách truyền toàn bộ SessionConfig, CameraX có thể xác định chính xác các dải được hỗ trợ dựa trên cấu hình luồng.

Camera-Compose hiện đã ổn định

Chúng tôi biết bạn rất thích Jetpack Compose và chúng tôi rất vui mừng được thông báo rằng thư viện camera-compose hiện đã ổn định ở phiên bản 1.5.1! Bản phát hành này bao gồm các bản sửa lỗi quan trọng liên quan đến việc sử dụng CameraXViewfinder với các tính năng của Compose như moveableContentOf và Pager, cũng như giải quyết vấn đề kéo giãn bản xem trước. Chúng tôi sẽ tiếp tục bổ sung nhiều tính năng hơn cho camera-compose trong các bản phát hành sau này.

Cải tiến ImageAnalysis và CameraControl

  • Điều chỉnh cường độ đèn pin: Kiểm soát chi tiết đèn pin của thiết bị bằng các API mới. Bạn có thể truy vấn cường độ tối đa được hỗ trợ bằng CameraInfo.getMaxTorchStrengthLevel(), sau đó đặt mức mong muốn bằng CameraControl.setTorchStrengthLevel().
  • Hỗ trợ NV21 trong ImageAnalysis: Giờ đây, bạn có thể yêu cầu định dạng hình ảnh NV21 ngay từ ImageAnalysis, giúp đơn giản hoá việc tích hợp với các thư viện và API khác. Bạn có thể bật tính năng này bằng cách gọi ImageAnalysis.Builder.setOutputImageFormat(OUTPUT_IMAGE_FORMAT_NV21).

Bắt đầu ngay hôm nay

Hãy cập nhật các phần phụ thuộc lên CameraX 1.5 ngay hôm nay để khám phá các tính năng mới thú vị. Chúng tôi rất mong chờ những sản phẩm sắp tới của bạn.

Để sử dụng CameraX 1.5, vui lòng thêm các phần phụ thuộc sau vào tệp libs.versions.toml. (Bạn nên sử dụng phiên bản 1.5.1 vì phiên bản này có nhiều bản sửa lỗi quan trọng và cải tiến về camera đồng thời.) 

[versions]

camerax = "1.5.1"


[libraries]

..

androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "camerax" }

androidx-camera-compose = { module = "androidx.camera:camera-compose", version.ref = "camerax" }

androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "camerax" }

androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camerax" }

androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "camerax" }

androidx-camera-extensions = { module = "androidx.camera:camera-extensions", version.ref = "camerax" }

Sau đó, hãy thêm các phần phụ thuộc này vào phần phụ thuộc build.gradle.kts của mô-đun:

dependencies {

  ..

  implementation(libs.androidx.camera.core)
  implementation(libs.androidx.camera.lifecycle)

  implementation(libs.androidx.camera.camera2)

  implementation(libs.androidx.camera.view) // for PreviewView 
  implementation(libs.androidx.camera.compose) // for compose UI

  implementation(libs.androidx.camera.extensions) // For Extensions 

}

Bạn có câu hỏi hoặc muốn kết nối với nhóm CameraX? Tham gia nhóm thảo luận dành cho nhà phát triển CameraX hoặc gửi báo cáo lỗi:

Tác giả:
Tiếp tục đọc