วิธีการ

การจับภาพความเร็วสูงและวิดีโอสโลว์โมชันด้วย CameraX 1.5

ใช้เวลาอ่าน 6 นาที
ดูโปรไฟล์ของ Charles Munger
Leo Huang วิศวกรซอฟต์แวร์

การจับภาพการเคลื่อนไหวที่รวดเร็วได้อย่างชัดเจนเป็นฟีเจอร์สำคัญของแอปกล้องถ่ายรูปสมัยใหม่ ซึ่งทำได้ผ่านการจับภาพความเร็วสูง ซึ่งเป็นกระบวนการรับเฟรมที่อัตรา เช่น 120 หรือ 240 เฟรมต่อวินาที การจับภาพที่มีความเที่ยงตรงสูงนี้ใช้ได้ 2 วัตถุประสงค์ที่แตกต่างกัน ได้แก่ การสร้างวิดีโออัตราเฟรมสูงสำหรับการวิเคราะห์แบบเฟรมต่อเฟรมอย่างละเอียด หรือการสร้างวิดีโอสโลว์โมชันที่การเคลื่อนไหวปรากฏบนหน้าจออย่างน่าทึ่ง

ก่อนหน้านี้ การใช้ฟีเจอร์เหล่านี้กับ Camera2 API เป็นกระบวนการที่ต้องลงมือทำมากขึ้น แต่ตอนนี้ด้วย High-Speed API ใหม่ใน CameraX 1.5 กระบวนการทั้งหมดจึงง่ายขึ้น ทำให้คุณมีความยืดหยุ่นในการสร้างวิดีโออัตราเฟรมสูงจริงหรือคลิปสโลว์โมชันที่พร้อมเล่น โพสต์นี้จะแสดงวิธีใช้ทั้ง 2 อย่างได้อย่างเชี่ยวชาญ สำหรับผู้ที่เพิ่งเริ่มใช้ CameraX โปรดดูข้อมูลเบื้องต้นได้ที่ภาพรวมของ CameraX


หลักการเบื้องหลังสโลว์โมชัน

หลักการพื้นฐานของสโลว์โมชันคือการจับภาพวิดีโอที่อัตราเฟรมสูงกว่าอัตราเฟรมที่เล่นมาก เช่น หากคุณบันทึกเหตุการณ์ 1 วินาทีที่120 เฟรมต่อวินาที (FPS) แล้วเล่นการบันทึกนั้นที่ 30 FPS มาตรฐาน วิดีโอจะใช้เวลาเล่น 4 วินาที การ "ยืด" เวลาเช่นนี้จะสร้างเอฟเฟกต์สโลว์โมชันที่น่าทึ่ง ซึ่งช่วยให้คุณเห็นรายละเอียดที่เร็วเกินกว่าที่ตาเปล่าจะมองเห็น

วิดีโอเอาต์พุตสุดท้ายควรแสดงผลที่ 30 FPS เป็นอย่างน้อยเพื่อให้วิดีโอราบรื่น ซึ่งหมายความว่าหากต้องการสร้างวิดีโอสโลว์โมชัน 4 เท่า อัตราเฟรมการจับภาพเดิมต้องเป็น 120 FPS เป็นอย่างน้อย (120 FPS การจับภาพ ÷ 4 = 30 FPS การเล่น)

เมื่อจับภาพฟุตเทจอัตราเฟรมสูงแล้ว คุณสามารถทำได้ 2 วิธีหลักๆ เพื่อให้ได้ผลลัพธ์ที่ต้องการ

  • สโลว์โมชันที่จัดการโดยเพลเยอร์ (วิดีโออัตราเฟรมสูง): การบันทึกความเร็วสูง (เช่น 120 FPS) จะบันทึกเป็นไฟล์วิดีโออัตราเฟรมสูงโดยตรง จากนั้นวิดีโอเพลเยอร์จะทำหน้าที่ลดความเร็วในการเล่น ซึ่งช่วยให้ผู้ใช้มีความยืดหยุ่นในการสลับระหว่างการเล่นปกติกับการเล่นสโลว์โมชัน
  • สโลว์โมชันที่พร้อมเล่น (วิดีโอที่เข้ารหัสใหม่): ระบบจะประมวลผลและเข้ารหัสสตรีมวิดีโอความเร็วสูงใหม่เป็นไฟล์ที่มีอัตราเฟรมมาตรฐาน (เช่น 30 FPS) เอฟเฟกต์สโลว์โมชันจะ "ฝัง" ไว้โดยการปรับการประทับเวลาของเฟรม วิดีโอที่ได้จะเล่นแบบสโลว์โมชันในวิดีโอเพลเยอร์มาตรฐานโดยไม่ต้องจัดการเป็นพิเศษ แม้ว่าวิดีโอจะเล่นแบบสโลว์โมชันโดยค่าเริ่มต้น แต่วิดีโอเพลเยอร์ก็ยังสามารถมีตัวควบคุมความเร็วในการเล่นที่ช่วยให้ผู้ใช้เพิ่มความเร็วและดูวิดีโอด้วยความเร็วเดิมได้

CameraX API ช่วยให้กระบวนการนี้ง่ายขึ้นด้วยการให้วิธีที่รวมเป็นหนึ่งเดียวในการเลือกแนวทางที่ต้องการ ดังที่คุณจะเห็นด้านล่าง


High-Speed Video API ใหม่

โซลูชัน CameraX ใหม่สร้างขึ้นจากคอมโพเนนต์หลัก 2 รายการ ได้แก่

  • Recorder#getHighSpeedVideoCapabilities(CameraInfo): เมธอดนี้ช่วยให้คุณตรวจสอบได้ว่ากล้องบันทึกแบบความเร็วสูงได้หรือไม่ และหากบันทึกได้ จะรองรับความละเอียดใดบ้าง (ออบเจ็กต์ Quality)
  • HighSpeedVideoSessionConfig: นี่คือออบเจ็กต์การกำหนดค่าพิเศษที่จัดกลุ่ม Use Case ของ VideoCapture และ Preview ไว้ด้วยกัน เพื่อบอกให้ CameraX สร้างเซสชันกล้องความเร็วสูงแบบรวมเป็นหนึ่งเดียว โปรดทราบว่าแม้ว่าสตรีม VideoCapture จะทำงานที่อัตราเฟรมสูงที่กำหนดค่าไว้ แต่ระบบกล้องมักจะจำกัดสตรีม Preview ไว้ที่อัตรามาตรฐานอย่างน้อย 30 FPS เพื่อให้แสดงผลบนหน้าจอได้อย่างราบรื่น

เริ่มต้นใช้งาน

ก่อนเริ่มต้นใช้งาน โปรดตรวจสอบว่าคุณได้เพิ่มทรัพยากร Dependency ของ CameraX ที่จำเป็นลงในไฟล์ build.gradle.kts ของแอปแล้ว คุณจะต้องมีอาร์ติแฟกต์ camera-video พร้อมกับไลบรารี CameraX หลัก

// 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")

}

หมายเหตุเกี่ยวกับ API การทดสอบ

โปรดทราบว่าปัจจุบัน API การบันทึกความเร็วสูงยังอยู่ในช่วงทดสอบ ซึ่งหมายความว่า API เหล่านี้อาจมีการเปลี่ยนแปลงในรุ่นที่จะเผยแพร่ในอนาคต หากต้องการใช้ API เหล่านี้ คุณต้องเลือกใช้โดยเพิ่มคำอธิบายประกอบต่อไปนี้ลงในโค้ด

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

การใช้งาน

การใช้งานสำหรับผลลัพธ์ทั้ง 2 อย่างเริ่มต้นด้วยขั้นตอนการตั้งค่าเดียวกัน การเลือกระหว่างการสร้างวิดีโออัตราเฟรมสูงหรือวิดีโอสโลว์โมชันขึ้นอยู่กับการตั้งค่าเพียงอย่างเดียว

1. ตั้งค่าการจับภาพความเร็วสูง

ก่อนอื่น ไม่ว่าเป้าหมายของคุณคืออะไร คุณต้องรับ ProcessCameraProvider ตรวจสอบความสามารถของอุปกรณ์ และสร้าง Use Case

โค้ดบล็อกต่อไปนี้แสดงขั้นตอนการตั้งค่าทั้งหมดภายในฟังก์ชันระงับ คุณสามารถเรียกฟังก์ชันนี้จากขอบเขตโครูทีน เช่น 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. เลือกเอาต์พุต

ตอนนี้คุณต้องตัดสินใจว่าต้องการสร้างวิดีโอประเภทใด โค้ดนี้จะทำงานภายในฟังก์ชัน setupCamera() suspend ที่แสดงด้านบน

ตัวเลือก ก: สร้างวิดีโออัตราเฟรมสูง

เลือกตัวเลือกนี้หากต้องการให้ไฟล์สุดท้ายมีอัตราเฟรมสูง (เช่น วิดีโอ 120 FPS)

// 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())

ตัวเลือก ข: สร้างวิดีโอสโลว์โมชันที่พร้อมเล่น

เลือกตัวเลือกนี้หากต้องการวิดีโอที่เล่นแบบสโลว์โมชันโดยอัตโนมัติในวิดีโอเพลเยอร์มาตรฐาน

// 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())

แฟล็กเดียวนี้เป็นกุญแจสำคัญในการสร้างวิดีโอสโลว์โมชันที่พร้อมเล่น เมื่อ setSlowMotionEnabled เป็นจริง CameraX จะประมวลผลสตรีมความเร็วสูงและบันทึกเป็นไฟล์วิดีโอ 30 FPS มาตรฐาน ความเร็วสโลว์โมชันจะกำหนดโดยอัตราส่วนของอัตราเฟรมการจับภาพต่ออัตราการเล่นมาตรฐานนี้

ตัวอย่างเช่น

  • การบันทึกที่120 FPS จะสร้างวิดีโอที่เล่นที่ความเร็ว 1/4 เท่า (120 ÷ 30 = 4)
  • การบันทึกที่240 FPS จะสร้างวิดีโอที่เล่นที่ความเร็ว 1/8 เท่า (240 ÷ 30 = 8)

รวมทุกอย่างเข้าด้วยกัน: การบันทึกวิดีโอ

เมื่อกำหนดค่า HighSpeedVideoSessionConfig และผูกไว้กับวงจรแล้ว ขั้นตอนสุดท้ายคือการเริ่มการบันทึก กระบวนการเตรียมตัวเลือกเอาต์พุต การเริ่มการบันทึก และการจัดการเหตุการณ์วิดีโอจะเหมือนกับการจับภาพวิดีโอมาตรฐาน

โพสต์นี้เน้นที่การกำหนดค่าความเร็วสูง ดังนั้นเราจะไม่พูดถึงกระบวนการบันทึกโดยละเอียด หากต้องการดูคำแนะนำที่ครอบคลุมทุกอย่างตั้งแต่การเตรียมออบเจ็กต์ FileOutputOptions หรือ MediaStoreOutputOptions ไปจนถึงการจัดการการเรียกกลับ VideoRecordEvent โปรดดูเอกสารประกอบ 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)

    }

การรองรับวิดีโอสโลว์โมชันของ Google Photos

เมื่อคุณเปิดใช้ setSlowMotionEnabled(true) ใน CameraX ระบบจะออกแบบไฟล์วิดีโอที่ได้เพื่อให้วิดีโอเพลเยอร์มาตรฐานและแอปแกลเลอรีจดจำและเล่นเป็นสโลว์โมชันได้ทันที โดยเฉพาะอย่างยิ่ง Google Photos มีฟังก์ชันการทำงานที่ได้รับการปรับปรุงสำหรับวิดีโอสโลว์โมชันเหล่านี้ เมื่ออัตราเฟรมการจับภาพอยู่ที่ 120, 240, 360, 480 หรือ 960 FPS

  • การจดจำ UI ที่แตกต่างในภาพขนาดย่อ: ในคลังภาพ Google Photos คุณสามารถระบุวิดีโอสโลว์โมชันได้จากองค์ประกอบ UI ที่เฉพาะเจาะจง ซึ่งจะแยกวิดีโอสโลว์โมชันออกจากวิดีโอปกติ
normal.png
slowmotion.png
ภาพปกวิดีโอปกติภาพปกวิดีโอสโลว์โมชัน
  • ส่วนความเร็วที่ปรับได้ระหว่างการเล่น: เมื่อเล่นวิดีโอสโลว์โมชัน Google Photos จะมีตัวควบคุมให้ปรับว่าส่วนใดของวิดีโอจะเล่นด้วยความเร็วต่ำและส่วนใดจะเล่นด้วยความเร็วปกติ ซึ่งช่วยให้ผู้ใช้ควบคุมความคิดสร้างสรรค์ได้ จากนั้นคุณสามารถส่งออกวิดีโอที่แก้ไขแล้วเป็นไฟล์วิดีโอใหม่โดยใช้ปุ่มแชร์ ซึ่งจะเก็บส่วนสโลว์โมชันที่คุณกำหนดไว้
normal2.png
slowmotion2.png
การเล่นวิดีโอปกติการเล่นวิดีโอสโลว์โมชัน 
พร้อมตัวควบคุมการแก้ไข 

หมายเหตุเกี่ยวกับการรองรับอุปกรณ์

High-Speed API ของ CameraX อาศัยระบบ CamcorderProfile ของ Android ที่อยู่เบื้องหลังเพื่อกำหนดความละเอียดและความเร็วสูงที่อุปกรณ์รองรับ ชุดเครื่องมือทดสอบความเข้ากันได้ (CTS) ของ Android จะตรวจสอบ CamcorderProfile ซึ่งหมายความว่าคุณมั่นใจได้ในความสามารถในการบันทึกวิดีโอที่อุปกรณ์รายงาน

ซึ่งหมายความว่าความสามารถของอุปกรณ์ในการบันทึกวิดีโอสโลว์โมชันด้วยแอปกล้องถ่ายรูปในตัวไม่ได้เป็นการรับประกันว่า High-Speed API ของ CameraX จะทำงาน ความคลาดเคลื่อนนี้เกิดขึ้นเนื่องจากผู้ผลิตอุปกรณ์มีหน้าที่รับผิดชอบในการป้อนข้อมูล CamcorderProfile ในเฟิร์มแวร์ของอุปกรณ์ และบางครั้งโปรไฟล์ความเร็วสูงที่จำเป็น เช่น CamcorderProfile.QUALITY_HIGH_SPEED_1080P และ CamcorderProfile.QUALITY_HIGH_SPEED_720P ก็ไม่ได้รวมอยู่ด้วย เมื่อไม่มีโปรไฟล์เหล่านี้ Recorder.getHighSpeedVideoCapabilities() จะแสดงผล null

ดังนั้น คุณจึงต้องใช้ Recorder.getHighSpeedVideoCapabilities() เสมอเพื่อตรวจสอบฟีเจอร์ที่รองรับแบบเป็นโปรแกรม เนื่องจากวิธีนี้เป็นวิธีที่เชื่อถือได้มากที่สุดในการรับประกันประสบการณ์การใช้งานที่สอดคล้องกันในอุปกรณ์ต่างๆ หากคุณพยายามผูก HighSpeedVideoSessionConfig ในอุปกรณ์ที่ Recorder.getHighSpeedVideoCapabilities() แสดงผลเป็น Null การดำเนินการจะล้มเหลวโดยมี IllegalArgumentException คุณสามารถยืนยันการรองรับในอุปกรณ์ Google Pixel เนื่องจากอุปกรณ์เหล่านี้มีโปรไฟล์ความเร็วสูงเหล่านี้อยู่เสมอ นอกจากนี้ อุปกรณ์ต่างๆ จากผู้ผลิตรายอื่นๆ เช่น Motorola Edge 30, OPPO Find N2 Flip และ Sony Xperia 1 V ก็รองรับความสามารถในการบันทึกวิดีโอความเร็วสูงด้วย


บทสรุป

High-Speed Video API ของ CameraX มีประสิทธิภาพและยืดหยุ่น HighSpeedVideoSessionConfig มีโซลูชันที่รวมเป็นหนึ่งเดียวและเรียบง่าย ไม่ว่าคุณจะต้องการฟุตเทจอัตราเฟรมสูงจริงสำหรับการวิเคราะห์ทางเทคนิคหรือต้องการเพิ่มเอฟเฟกต์สโลว์โมชันสไตล์ภาพยนตร์ลงในแอป การทำความเข้าใจบทบาทของแฟล็ก setSlowMotionEnabled จะช่วยให้คุณรองรับ Use Case ทั้ง 2 อย่างได้อย่างง่ายดายและให้ผู้ใช้ควบคุมความคิดสร้างสรรค์ได้มากขึ้น

เขียนโดย:
อ่านต่อ