방법

CameraX 1.5를 사용한 고속 캡처 및 슬로 모션 동영상

전문 길이: 6분
Leo Huang
소프트웨어 엔지니어

빠르게 움직이는 동작을 선명하게 포착하는 것은 최신 카메라 앱의 핵심 기능입니다. 이는 120fps 또는 240fps와 같은 속도로 프레임을 획득하는 프로세스인 고속 캡처를 통해 달성됩니다. 이 고화질 캡처는 두 가지 용도로 사용할 수 있습니다. 자세한 프레임별 분석을 위한 고프레임률 동영상을 만들거나 화면에서 동작이 극적으로 펼쳐지는 슬로우 모션 동영상을 생성할 수 있습니다.

이전에는 Camera2 API로 이러한 기능을 구현하는 것이 더 실무적인 프로세스였습니다. 이제 CameraX 1.5의 새로운 고속 API를 사용하면 전체 프로세스가 간소화되어 실제 고프레임 속도 동영상이나 바로 재생 가능한 슬로우 모션 클립을 유연하게 만들 수 있습니다. 이 게시물에서는 두 가지 모두 능숙하게 사용하는 방법을 보여줍니다. CameraX를 처음 사용하는 경우 CameraX 개요를 통해 빠르게 익힐 수 있습니다.


슬로 모션의 원리

슬로 모션의 기본 원리는 재생되는 것보다 훨씬 높은 프레임 속도로 동영상을 촬영하는 것입니다. 예를 들어 초당 120프레임 (fps)으로 1초짜리 이벤트를 녹화한 다음 표준 30fps로 녹화된 동영상을 재생하면 동영상이 재생되는 데 4초가 걸립니다. 이러한 시간의 '늘림'이 극적인 슬로우 모션 효과를 만들어 육안으로 너무 빠른 세부정보를 확인할 수 있습니다.

최종 출력 동영상이 매끄럽고 부드러우려면 일반적으로 최소 30fps로 렌더링해야 합니다. 즉, 4배 슬로 모션 동영상을 만들려면 원본 캡처 프레임 속도가 최소 120fps여야 합니다 (120 캡처 fps ÷ 4 = 30 재생 fps).

높은 프레임 속도 푸티지를 촬영한 후 원하는 결과를 얻는 방법에는 두 가지가 있습니다.

  • 플레이어에서 처리하는 슬로우 모션 (고프레임 속도 동영상): 고속 녹화 (예: 120fps)가 고프레임 속도 동영상 파일로 직접 저장됩니다. 그런 다음 동영상 플레이어가 재생 속도를 늦춰야 합니다. 이를 통해 사용자는 일반 재생과 슬로우 모션 재생 간에 유연하게 전환할 수 있습니다.
  • 재생 준비된 슬로 모션 (재인코딩된 동영상): 고속 동영상 스트림이 처리되고 표준 프레임 속도 (예: 30fps)의 파일로 재인코딩됩니다. 프레임 타임스탬프를 조정하여 슬로 모션 효과가 '내장'됩니다. 이렇게 만들어진 동영상은 특별한 처리 없이도 표준 동영상 플레이어에서 슬로 모션으로 재생됩니다. 동영상은 기본적으로 슬로 모션으로 재생되지만, 동영상 플레이어는 사용자가 속도를 높여 동영상을 원래 속도로 시청할 수 있는 재생 속도 컨트롤을 제공할 수 있습니다.

CameraX API는 아래에 표시된 것처럼 원하는 접근 방식을 선택하는 통합된 방법을 제공하여 이 과정을 간소화합니다.


새로운 고속 동영상 API

새 CameraX 솔루션은 다음 두 가지 주요 구성요소를 기반으로 빌드됩니다.

  • Recorder#getHighSpeedVideoCapabilities(CameraInfo): 이 메서드를 사용하면 카메라가 고속으로 녹화할 수 있는지, 녹화할 수 있다면 지원되는 해상도 (Quality 객체)를 확인할 수 있습니다.
  • HighSpeedVideoSessionConfig: VideoCapturePreview 사용 사례를 그룹화하여 CameraX에 통합된 고속 카메라 세션을 만들도록 지시하는 특수 구성 객체입니다. VideoCapture 스트림은 구성된 높은 프레임 속도로 작동하지만 미리보기 스트림은 일반적으로 화면에서 원활하게 표시되도록 카메라 시스템에 의해 최소 30FPS의 표준 속도로 제한됩니다.

시작하기

시작하기 전에 앱의 build.gradle.kts 파일에 필요한 CameraX 종속 항목을 추가했는지 확인하세요. 핵심 CameraX 라이브러리와 함께 camera-video 아티팩트가 필요합니다.

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

구현

두 결과의 구현은 동일한 설정 단계로 시작됩니다. 고프레임률 동영상과 슬로 모션 동영상 중 어떤 동영상을 만들지는 하나의 설정에 따라 결정됩니다.

1. 고속 캡처 설정

먼저 목표와 관계없이 ProcessCameraProvider를 가져오고, 기기 기능을 확인하고, 사용 사례를 만들어야 합니다.

다음 코드 블록은 suspend 함수 내의 전체 설정 흐름을 보여줍니다. 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 함수 내에서 실행됩니다.

옵션 A: 높은 프레임 속도의 동영상 만들기

최종 파일의 프레임 속도가 높아야 하는 경우 (예: 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가 true이면 CameraX는 고속 스트림을 처리하고 표준 30fps 동영상 파일로 저장합니다. 슬로우 모션 속도는 캡처 프레임 속도와 이 표준 재생 속도의 비율에 따라 결정됩니다.

예를 들면 다음과 같습니다.

  • 120fps로 녹화하면 1/4배속으로 재생되는 동영상이 생성됩니다 (120 ÷ 30 = 4).
  • 240fps로 녹화하면 1/8x 속도 (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 포토 지원

CameraX에서 setSlowMotionEnabled(true)를 사용 설정하면 결과 동영상 파일이 표준 동영상 플레이어 및 갤러리 앱에서 슬로우 모션으로 즉시 인식되고 재생되도록 설계됩니다. 특히 Google 포토는 캡처 프레임 속도가 120, 240, 360, 480 또는 960fps인 슬로 모션 동영상에 대해 다음과 같은 향상된 기능을 제공합니다.

  • 썸네일의 고유한 UI 인식: Google 포토 라이브러리에서 슬로우 모션 동영상은 특정 UI 요소로 식별되어 일반 동영상과 구분됩니다.
normal.png
  • 재생 중 속도 조절 세그먼트: 슬로 모션 동영상을 재생할 때 Google 포토는 동영상의 어떤 부분이 느린 속도로 재생되고 어떤 부분이 일반 속도로 재생되는지 조정하는 컨트롤을 제공하여 사용자에게 창의적인 제어 기능을 제공합니다. 그런 다음 편집된 동영상을 공유 버튼을 사용하여 새 동영상 파일로 내보내면 정의한 슬로우 모션 세그먼트가 유지됩니다.
normal2.png

기기 지원에 관한 참고사항

CameraX의 고속 API는 기본 Android CamcorderProfile 시스템을 사용하여 기기에서 지원하는 고속 해상도와 프레임 속도를 결정합니다. CamcorderProfiles는 Android 호환성 테스트 모음 (CTS)에 의해 검증되므로 기기에서 보고된 동영상 녹화 기능을 신뢰할 수 있습니다.

즉, 내장 카메라 앱으로 슬로 모션 동영상을 녹화하는 기기의 기능이 CameraX 고속 API의 작동을 보장하지는 않습니다. 이러한 불일치는 기기 제조업체가 기기 펌웨어에 CamcorderProfile 항목을 채워야 하는데, 필요한 고속 프로필(예: CamcorderProfile.QUALITY_HIGH_SPEED_1080P, CamcorderProfile.QUALITY_HIGH_SPEED_720P)이 포함되지 않는 경우가 있기 때문에 발생합니다. 이러한 프로필이 누락되면 Recorder.getHighSpeedVideoCapabilities()에서 null을 반환합니다.

따라서 다양한 기기에서 일관된 환경을 보장하는 가장 안정적인 방법인 Recorder.getHighSpeedVideoCapabilities()를 항상 사용하여 지원되는 기능을 프로그래매틱 방식으로 확인해야 합니다. Recorder.getHighSpeedVideoCapabilities()이 null을 반환하는 기기에서 HighSpeedVideoSessionConfig을 바인딩하려고 하면 작업이 IllegalArgumentException로 실패합니다. Google Pixel 기기는 이러한 고속 프로필을 일관되게 포함하므로 지원 여부를 확인할 수 있습니다. 또한 Motorola Edge 30, OPPO Find N2 Flip, Sony Xperia 1 V와 같은 다른 제조업체의 다양한 기기에서도 고속 동영상 기능을 지원합니다.


결론

CameraX 고속 동영상 API는 강력하면서도 유연합니다. 기술 분석을 위해 진정한 고프레임 속도 영상이 필요하거나 앱에 영화 같은 슬로우 모션 효과를 추가하려는 경우 HighSpeedVideoSessionConfig는 통합되고 간단한 솔루션을 제공합니다. setSlowMotionEnabled 플래그의 역할을 이해하면 두 사용 사례를 모두 쉽게 지원하고 사용자에게 더 많은 창의적인 제어 기능을 제공할 수 있습니다.

작성자:

계속 읽기