Hướng dẫn

Quay video tốc độ cao và video chuyển động chậm bằng CameraX 1.5

6 phút đọc
Leo Huang
Kỹ sư phần mềm

Ghi lại các cảnh hành động chuyển động nhanh một cách rõ ràng là một tính năng quan trọng đối với các ứng dụng máy ảnh hiện đại. Tính năng này được thực hiện thông qua tính năng quay video tốc độ cao – quá trình thu thập khung hình ở các tốc độ như 120 hoặc 240 khung hình/giây. Tính năng quay video có độ trung thực cao này có thể được dùng cho 2 mục đích riêng biệt: tạo video có tốc độ khung hình cao để phân tích chi tiết từng khung hình hoặc tạo video chuyển động chậm trong đó cảnh hành động diễn ra một cách ấn tượng trên màn hình.

Trước đây, việc triển khai các tính năng này bằng Camera2 API là một quá trình thực hành nhiều hơn. Giờ đây, với API tốc độ cao mới trong CameraX 1.5, toàn bộ quá trình được đơn giản hoá, giúp bạn linh hoạt tạo video có tốc độ khung hình cao thực sự hoặc các đoạn video chuyển động chậm sẵn sàng phát. Bài đăng này sẽ hướng dẫn bạn cách sử dụng cả hai tính năng này. Đối với những người mới sử dụng CameraX, bạn có thể tìm hiểu nhanh thông qua Tổng quan về CameraX.


Nguyên tắc đằng sau tính năng chuyển động chậm

Nguyên tắc cơ bản của tính năng chuyển động chậm là quay video ở tốc độ khung hình cao hơn nhiều so với tốc độ phát lại. Ví dụ: nếu bạn quay một sự kiện kéo dài 1 giây ở tốc độ 120 khung hình/giây rồi phát lại bản ghi đó ở tốc độ 30 khung hình/giây tiêu chuẩn, thì video sẽ mất 4 giây để phát. Việc "kéo dài" thời gian này sẽ tạo ra hiệu ứng chuyển động chậm ấn tượng, cho phép bạn nhìn thấy những chi tiết quá nhanh đối với mắt thường.

Để đảm bảo video đầu ra cuối cùng mượt mà và trôi chảy, bạn thường phải kết xuất video ở tốc độ tối thiểu là 30 khung hình/giây. Điều này có nghĩa là để tạo video chuyển động chậm gấp 4 lần, tốc độ khung hình quay video ban đầu phải ít nhất là 120 khung hình/giây (120 khung hình/giây khi quay ÷ 4 = 30 khung hình/giây khi phát).

Sau khi quay được cảnh quay có tốc độ khung hình cao, có 2 cách chính để đạt được kết quả mong muốn:

  • Chuyển động chậm do trình phát xử lý (Video có tốc độ khung hình cao): Bản ghi tốc độ cao (ví dụ: 120 khung hình/giây) được lưu trực tiếp dưới dạng tệp video có tốc độ khung hình cao. Sau đó, trình phát video sẽ có trách nhiệm làm chậm tốc độ phát lại. Điều này giúp người dùng linh hoạt chuyển đổi giữa chế độ phát bình thường và chế độ phát chuyển động chậm.
  • Chuyển động chậm sẵn sàng phát (Video được mã hoá lại): Luồng video tốc độ cao được xử lý và mã hoá lại thành một tệp có tốc độ khung hình tiêu chuẩn (ví dụ: 30 khung hình/giây). Hiệu ứng chuyển động chậm được "tích hợp" bằng cách điều chỉnh dấu thời gian của khung hình. Video kết quả sẽ phát ở chế độ chuyển động chậm trong bất kỳ trình phát video tiêu chuẩn nào mà không cần xử lý đặc biệt. Mặc dù video phát ở chế độ chuyển động chậm theo mặc định, nhưng trình phát video vẫn có thể cung cấp các lựa chọn điều khiển tốc độ phát cho phép người dùng tăng tốc độ và xem video ở tốc độ ban đầu.

CameraX API đơn giản hoá quá trình này bằng cách cung cấp cho bạn một cách thống nhất để chọn phương pháp bạn muốn, như bạn sẽ thấy bên dưới.


API video tốc độ cao mới

Giải pháp CameraX mới được xây dựng dựa trên 2 thành phần chính:

  • Recorder#getHighSpeedVideoCapabilities(CameraInfo): Phương thức này cho phép bạn kiểm tra xem máy ảnh có thể quay video tốc độ cao hay không và nếu có thì những độ phân giải (Quality đối tượng) nào được hỗ trợ.
  • HighSpeedVideoSessionConfig: Đây là một đối tượng cấu hình đặc biệt nhóm các trường hợp sử dụng VideoCapturePreview, cho CameraX biết để tạo một phiên máy ảnh tốc độ cao thống nhất. Xin lưu ý rằng mặc dù luồng VideoCapture sẽ hoạt động ở tốc độ khung hình cao đã định cấu hình, nhưng luồng Xem trước thường sẽ bị giới hạn ở tốc độ tiêu chuẩn ít nhất là 30 FPS bởi hệ thống máy ảnh để đảm bảo hiển thị mượt mà trên màn hình.

Bắt đầu

Trước khi bắt đầu, hãy đảm bảo bạn đã thêm các phần phụ thuộc CameraX cần thiết vào tệp build.gradle.kts của ứng dụng. Bạn sẽ cần cấu phần phần mềm camera-video cùng với các thư viện CameraX cốt lõi.

  // build.gradle.kts (Module: app)

dependencies {

    val camerax_version = "1.5.1"


    implementation("androidx.camera:camera-core:$camerax_version")

    implementation("androidx.camera:camera-camera2:$camerax_version")

    implementation("androidx.camera:camera-lifecycle:$camerax_version")

    implementation("androidx.camera:camera-video:$camerax_version")

    implementation("androidx.camera:camera-view:$camerax_version")

}

Lưu ý về API thử nghiệm

Điều quan trọng cần lưu ý là các API quay video tốc độ cao hiện đang ở giai đoạn thử nghiệm. Điều này có nghĩa là các API này có thể thay đổi trong các bản phát hành trong tương lai. Để sử dụng các API này, bạn phải chọn tham gia bằng cách thêm chú thích sau vào mã của mình:

  @kotlin.OptIn(ExperimentalSessionConfig::class, ExperimentalHighSpeedVideo::class)

Triển khai

Việc triển khai cho cả 2 kết quả đều bắt đầu bằng các bước thiết lập giống nhau. Việc lựa chọn giữa tạo video có tốc độ khung hình cao hoặc video chuyển động chậm phụ thuộc vào một chế độ cài đặt duy nhất.

1. Thiết lập tính năng chụp tốc độ cao

Trước tiên, bất kể mục tiêu của bạn là gì, bạn cần lấy ProcessCameraProvider, kiểm tra khả năng của thiết bị và tạo các trường hợp sử dụng.

Khối mã sau đây cho thấy quy trình thiết lập hoàn chỉnh trong một hàm tạm ngưng. Bạn có thể gọi hàm này từ một phạm vi coroutine, chẳng hạn như lifecycleScope.launch.

  // Add the OptIn annotation at the top of your function or class

@kotlin.OptIn(ExperimentalSessionConfig::class, ExperimentalHighSpeedVideo::class)

private suspend fun setupCamera() {

    // Asynchronously get the CameraProvider

    val cameraProvider = ProcessCameraProvider.awaitInstance(this)



    // -- CHECK CAPABILITIES --

    val cameraInfo = cameraProvider.getCameraInfo(CameraSelector.DEFAULT_BACK_CAMERA)

    val videoCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)

    if (videoCapabilities == null) {

        // This camera device does not support high-speed video.

        return

    }




    // -- CREATE USE CASES --

    val preview = Preview.Builder().build()    


    // You can create a Recorder with default settings.

    // CameraX will automatically select a suitable quality.

    val recorder = Recorder.Builder().build()


    // Alternatively, to use a specific resolution, you can configure the
    // Recorder with a QualitySelector. This is useful if your app has
    // specific resolution requirements or you want to offer user
    // preferences. 

    // To use a specific quality, you can uncomment the following lines.

    // Get the list of qualities supported for high-speed video. 

    // val supportedQualities = videoCapabilities.getSupportedQualities(DynamicRange.SDR)

    // Build the Recorder using the quality from the supported list.

    // val recorderWithQuality = Recorder.Builder()

    //     .setQualitySelector(QualitySelector.from(supportedQualities.first()))

    //     .build()



    // Create the VideoCapture use case, using either recorder or recorderWithQuality

    val videoCapture = VideoCapture.withOutput(recorder)

    // Now you are ready to configure the session for your desired output...

}

2. Chọn đầu ra

Bây giờ, bạn quyết định loại video bạn muốn tạo. Mã này sẽ chạy bên trong hàm setupCamera() suspend được hiển thị ở trên.

Cách A: Tạo video có tốc độ khung hình cao

Chọn cách này nếu bạn muốn tệp cuối cùng có tốc độ khung hình cao (ví dụ: video 120 khung hình/giây).

  // Create a builder for the high-speed session

val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)

    .setPreview(preview)


// Query and apply a supported frame rate. Common supported frame rates include 120 and 240 fps.

val supportedFrameRateRanges =

    cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())


sessionConfigBuilder.setFrameRateRange(supportedFrameRateRanges.first())

Cách B: Tạo video chuyển động chậm sẵn sàng phát

Chọn cách này nếu bạn muốn video tự động phát ở chế độ chuyển động chậm trong bất kỳ trình phát video tiêu chuẩn nào.

  // Create a builder for the high-speed session

val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)

    .setPreview(preview)



// This is the key: enable automatic slow-motion!

sessionConfigBuilder.setSlowMotionEnabled(true)



// Query and apply a supported frame rate. Common supported frame rates include 120, 240, and 480 fps.

val supportedFrameRateRanges =

   cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())

sessionConfigBuilder.setFrameRateRange(supportedFrameRateRanges.first())

Cờ duy nhất này là chìa khoá để tạo video chuyển động chậm sẵn sàng phát. Khi setSlowMotionEnabled là true, CameraX sẽ xử lý luồng tốc độ cao và lưu dưới dạng tệp video 30 khung hình/giây tiêu chuẩn. Tốc độ chuyển động chậm được xác định bằng tỷ lệ giữa tốc độ khung hình quay video và tốc độ phát lại tiêu chuẩn này.

Ví dụ:

  • Quay video ở tốc độ 120 khung hình/giây sẽ tạo ra video phát lại ở tốc độ 1/4x (120 ÷ 30 = 4).
  • Quay video ở tốc độ 240 khung hình/giây sẽ tạo ra video phát lại ở tốc độ 1/8x (240 ÷ 30 = 8).

Kết hợp tất cả: Quay video

Sau khi bạn định cấu hình HighSpeedVideoSessionConfig và liên kết với vòng đời, bước cuối cùng là bắt đầu quay. Quy trình chuẩn bị các lựa chọn đầu ra, bắt đầu quay và xử lý các sự kiện video giống như quy trình quay video tiêu chuẩn.

Bài đăng này tập trung vào cấu hình tốc độ cao, vì vậy, chúng tôi sẽ không đề cập chi tiết đến quy trình quay video. Để có hướng dẫn toàn diện về mọi thứ, từ việc chuẩn bị đối tượng FileOutputOptions hoặc MediaStoreOutputOptions đến xử lý các lệnh gọi lại VideoRecordEvent, vui lòng tham khảo tài liệu VideoCapture.

  // Bind the session config to the lifecycle

cameraProvider.bindToLifecycle(

    this as LifecycleOwner,

    CameraSelector.DEFAULT_BACK_CAMERA,

    sessionConfigBuilder.build() // Bind the config object from Option A or B

)



// Start the recording using the VideoCapture use case

val recording = videoCapture.output

    .prepareRecording(context, outputOptions) // See docs for creating outputOptions

    .start(ContextCompat.getMainExecutor(context)) { recordEvent ->

        // Handle recording events (e.g., Start, Pause, Finalize)

    }

Hỗ trợ Google Photos cho video chuyển động chậm

Khi bạn bật setSlowMotionEnabled(true) trong CameraX, tệp video kết quả được thiết kế để có thể nhận dạng và phát ngay lập tức dưới dạng chuyển động chậm trong các trình phát video tiêu chuẩn và ứng dụng thư viện. Đặc biệt, Google Photos cung cấp chức năng nâng cao cho các video chuyển động chậm này khi tốc độ khung hình quay video là 120, 240, 360, 480 hoặc 960 khung hình/giây:

  • Nhận dạng giao diện người dùng riêng biệt trong hình thu nhỏ: Trong thư viện Google Photos, bạn có thể xác định video chuyển động chậm bằng các thành phần giao diện người dùng cụ thể, phân biệt chúng với video bình thường.
normal.png
  • Điều chỉnh các phân đoạn tốc độ trong khi phát: Khi phát video chuyển động chậm, Google Photos cung cấp các lựa chọn điều khiển để điều chỉnh những phần nào của video phát ở tốc độ chậm và những phần nào phát ở tốc độ bình thường, giúp người dùng kiểm soát sáng tạo. Sau đó, bạn có thể xuất video đã chỉnh sửa dưới dạng tệp video mới bằng nút Chia sẻ , giữ nguyên các phân đoạn chuyển động chậm mà bạn đã xác định.
normal2.png

Lưu ý về hỗ trợ thiết bị

API tốc độ cao của CameraX dựa vào hệ thống CamcorderProfile cơ bản của Android để xác định những độ phân giải và tốc độ khung hình tốc độ cao mà thiết bị hỗ trợ. CamcorderProfile được Bộ kiểm tra tính tương thích (CTS) với Android xác thực, nghĩa là bạn có thể tin tưởng vào các khả năng quay video được báo cáo của thiết bị.

Điều này có nghĩa là khả năng quay video chuyển động chậm của thiết bị bằng ứng dụng máy ảnh tích hợp không đảm bảo rằng API tốc độ cao của CameraX sẽ hoạt động. Sự khác biệt này xảy ra vì nhà sản xuất thiết bị chịu trách nhiệm điền các mục CamcorderProfile vào phần sụn của thiết bị và đôi khi các hồ sơ tốc độ cao cần thiết như CamcorderProfile.QUALITY_HIGH_SPEED_1080PCamcorderProfile.QUALITY_HIGH_SPEED_720P không được đưa vào. Khi các hồ sơ này bị thiếu, Recorder.getHighSpeedVideoCapabilities() sẽ trả về null.

Do đó, bạn cần phải luôn sử dụng Recorder.getHighSpeedVideoCapabilities() để kiểm tra các tính năng được hỗ trợ theo phương thức lập trình, vì đây là cách đáng tin cậy nhất để đảm bảo trải nghiệm nhất quán trên nhiều thiết bị. Nếu bạn cố gắng liên kết HighSpeedVideoSessionConfig trên một thiết bị mà Recorder.getHighSpeedVideoCapabilities() trả về giá trị rỗng, thì thao tác sẽ không thành công với IllegalArgumentException. Bạn có thể xác nhận hỗ trợ trên thiết bị Google Pixel vì các thiết bị này luôn bao gồm các hồ sơ tốc độ cao này. Ngoài ra, nhiều thiết bị của các nhà sản xuất khác, chẳng hạn như Motorola Edge 30, OPPO Find N2 Flip và Sony Xperia 1 V, cũng hỗ trợ các khả năng quay video tốc độ cao.


Kết luận

API video tốc độ cao của CameraX vừa mạnh mẽ vừa linh hoạt. Cho dù bạn cần cảnh quay có tốc độ khung hình cao thực sự để phân tích kỹ thuật hay muốn thêm hiệu ứng chuyển động chậm đậm chất điện ảnh vào ứng dụng, HighSpeedVideoSessionConfig đều cung cấp một giải pháp thống nhất và đơn giản. Bằng cách hiểu rõ vai trò của cờ setSlowMotionEnabled, bạn có thể dễ dàng hỗ trợ cả 2 trường hợp sử dụng và giúp người dùng kiểm soát sáng tạo nhiều hơn.

Tác giả:

Tiếp tục đọc