Android Academy · 강의

동영상 녹화

CameraX로 동영상을 캡처합니다.

레슨 4/413개 단계

동영상 녹화은(는) CoddyKit의 무료 Android Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Android Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

CameraX로 동영상 녹화

CameRX는 Recorder를 기반으로 하는 VideoCapture 사용 사례를 통해 동영상을 녹화합니다. 이 과정에서는 동영상 촬영을 설정하고, 녹화를 시작하고 중지하며, 오디오를 포함해 갤러리에 저장하는 방법을 배웁니다.

전체 흐름은 사진과 비슷하지만, 시작한 뒤 나중에 중지하는 장시간 실행 Recording 세션이 추가됩니다.

Recorder 및 화질

먼저 인코딩과 화질을 정의하는 Recorder를 빌드합니다. QualitySelector를 사용하면 원하는 화질(예: HD, FHD)을 요청하고, 기기에서 해당 화질을 제공할 수 없을 때 사용할 대체 화질도 지정할 수 있습니다.

val recorder = Recorder.Builder()
    .setQualitySelector(
        QualitySelector.from(
            Quality.FHD,
            FallbackStrategy.lowerQualityOrHigherThan(Quality.SD)
        )
    )
    .build()

VideoCapture 생성

withOutput 팩토리를 사용해 Recorder를 VideoCapture 사용 사례로 감쌉니다. 이 객체를 카메라에 연결하며, ImageCapture와 같은 방식으로 사용합니다.

val videoCapture = VideoCapture.withOutput(recorder)

미리 보기 + VideoCapture 연결

미리 보기와 VideoCapture를 함께 연결합니다. 많은 기기에서는 ImageCapture와 VideoCapture를 동시에 연결할 수 없으므로 화면에 필요한 사용 사례를 선택해야 합니다.

cameraProvider.unbindAll()
cameraProvider.bindToLifecycle(
    lifecycleOwner,
    CameraSelector.DEFAULT_BACK_CAMERA,
    preview,
    videoCapture
)

오디오 권한

소리를 녹음하려면 CAMERA 외에도 런타임 RECORD_AUDIO 권한이 필요합니다. 녹화를 시작하기 전에 두 권한을 모두 요청하고, 사용자가 오디오 권한을 허용한 경우에만 오디오를 활성화하시기 바랍니다.

// Manifest declares both:
// <uses-permission android:name="android.permission.CAMERA" />
// <uses-permission android:name="android.permission.RECORD_AUDIO" />

val audioGranted = ContextCompat.checkSelfPermission(
    context, Manifest.permission.RECORD_AUDIO
) == PackageManager.PERMISSION_GRANTED

MediaStore를 통한 출력

사진과 마찬가지로 범위 지정 저장소를 사용해 동영상을 MediaStore에 저장합니다. mp4 MIME 유형으로 ContentValues를 만들고 MediaStoreOutputOptions를 생성합니다.

val values = ContentValues().apply {
    put(MediaStore.MediaColumns.DISPLAY_NAME, "VID_${System.currentTimeMillis()}")
    put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4")
    put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/MyApp")
}

val outputOptions = MediaStoreOutputOptions
    .Builder(context.contentResolver, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
    .setContentValues(values)
    .build()

녹화 시작

Recorder에서 녹화를 준비하고, 필요하면 withAudioEnabled()로 오디오를 활성화한 다음 start()를 호출합니다. start()는 나중에 녹화를 중지할 때 사용할 Recording 객체를 반환합니다.

또한 VideoRecordEvent 업데이트를 받는 리스너를 전달합니다.

val recording = videoCapture.output
    .prepareRecording(context, outputOptions)
    .apply { if (audioGranted) withAudioEnabled() }
    .start(ContextCompat.getMainExecutor(context)) { event ->
        when (event) {
            is VideoRecordEvent.Start -> { /* recording began */ }
            is VideoRecordEvent.Finalize -> {
                if (!event.hasError()) {
                    // event.outputResults.outputUri -> saved video
                }
            }
        }
    }

녹화 이벤트에 반응하기

리스너는 녹화의 수명 주기 정보를 스트리밍합니다.

  • VideoRecordEvent.Start — 녹화가 시작되었습니다(사용자 인터페이스를 중지 버튼으로 업데이트합니다).
  • VideoRecordEvent.Status — 녹화된 시간과 크기를 주기적으로 업데이트합니다.
  • VideoRecordEvent.Finalize — 녹화가 끝났습니다. hasError()를 확인합니다.
is VideoRecordEvent.Status -> {
    val seconds = event.recordingStats.recordedDurationNanos / 1_000_000_000
    // Update an on-screen timer.
}

녹화 중지

녹화를 완료하려면 앞에서 저장해 둔 Recording에 stop()을 호출합니다. 그러면 동영상 URI를 사용할 수 있게 되는 Finalize 이벤트가 발생합니다.

활성 녹화를 상태로 유지하면 하나의 버튼으로 시작과 중지를 전환할 수 있습니다.

var activeRecording: Recording? = null

// Toggle handler:
if (activeRecording == null) {
    activeRecording = startRecording()
} else {
    activeRecording?.stop()
    activeRecording = null
}

일시 중지 및 재개

Recording은 중지하지 않고도 일시 중지했다가 재개할 수 있습니다. 사용자가 여러 클립을 하나의 파일로 이어 붙일 수 있게 할 때 유용합니다.

activeRecording?.pause()
// ...later
activeRecording?.resume()
// Final stop writes the file:
activeRecording?.stop()

녹화를 위한 Compose UI

상태에 따라 UI를 동작하게 합니다. 녹화가 활성 상태인지 추적하고 그에 따라 버튼 아이콘과 동작을 바꿉니다. 리스너가 기본 실행기에서 실행되므로 리스너에서 직접 Compose 상태를 업데이트할 수 있습니다.

var isRecording by remember { mutableStateOf(false) }

IconButton(onClick = { toggleRecording() }) {
    Icon(
        imageVector = if (isRecording) Icons.Default.Stop else Icons.Default.Videocam,
        contentDescription = if (isRecording) "Stop" else "Record"
    )
}

빠른 확인

CameraX를 사용한 동영상 녹화를 제대로 이해했는지 확인해 보시기 바랍니다.

복습

이제 CameraX로 동영상을 녹화할 수 있습니다.

  • QualitySelector를 사용해 Recorder를 빌드하고 이를 VideoCapture.withOutput으로 감쌉니다.
  • 미리 보기와 연결하고 소리를 위해 RECORD_AUDIO를 요청합니다.
  • MediaStoreOutputOptions를 통해 저장한 다음 prepareRecording().start()를 호출해 Recording을 가져옵니다.
  • VideoRecordEvent에 반응하고, stop()을 호출해 녹화를 완료한 뒤 저장된 URI를 읽습니다.

CameraX 과정이 끝났습니다. 이제 미리 보기, 사진, 동영상을 모두 활용할 수 있습니다.

무료로 시작

AI 튜터와 함께 Kotlin을(를) 배우세요 — 무료

브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.

코스
36
레슨
152

자주 묻는 질문

“동영상 녹화” 강의는 무료인가요?

네 — “동영상 녹화” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Android Academy 강의 전체를 잠금 해제할 수 있습니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“동영상 녹화”에서 뭘 배우나요?

CameraX로 동영상을 캡처합니다. 브라우저에서 직접 실행하는 실습 코드로 Android Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Android Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Android Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“동영상 녹화” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Android Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Android Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. CameraX 개요
  2. 카메라 미리보기 표시
  3. 사진 촬영
  4. 동영상 녹화
← Android Academy(으)로 돌아가기