ฮาวทู

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

ใช้เวลาอ่าน 6 นาที
Leo Huang
วิศวกรซอฟต์แวร์

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

ก่อนหน้านี้ การใช้ฟีเจอร์เหล่านี้กับ Camera2 API เป็นกระบวนการที่ต้องลงมือปฏิบัติมากกว่า ตอนนี้ 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 ช่วยลดความซับซ้อนด้วยการให้วิธีแบบรวมในการเลือกแนวทางที่ต้องการ ดังที่คุณจะเห็นด้านล่าง


API วิดีโอความเร็วสูงใหม่

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

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

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

การใช้งาน

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

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

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

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

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

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

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

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

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

// 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
  • ปรับความเร็วของบางช่วงขณะเล่น: เมื่อเล่นวิดีโอสโลว์โมชัน Google Photos จะมีตัวควบคุมให้ปรับว่าส่วนใดของวิดีโอจะเล่นด้วยความเร็วต่ำและส่วนใดจะเล่นด้วยความเร็วปกติ เพื่อให้ผู้ใช้ควบคุมได้อย่างสร้างสรรค์ จากนั้นคุณจะส่งออกวิดีโอที่ตัดต่อแล้วเป็นไฟล์วิดีโอใหม่ได้โดยใช้ปุ่มแชร์ ซึ่งจะเก็บส่วนสโลว์โมชันที่คุณกำหนดไว้
normal2.png

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

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

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


บทสรุป

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

เขียนโดย

อ่านต่อ