본문 바로가기
안드로이드 자바

[Android][Java] 카메라로 동영상 촬영하기

by teamnova 2023. 9. 4.
728x90

오늘은 안드로이드 앱에서 카메라로 동영상을 촬영한 뒤

촬영된 동영상의 Uri를 사용해 동영상의 썸네일을 이미지 뷰에 띄우는 예제를 해보겠습니다.

 

 

먼저 새로운 프로젝트를 생성하고 Manifest.xml 파일에 권한 관련 태그를 작성해줍니다.

<uses-permission android:name="android.permission.CAMERA" /> // 카메라 사용 권한
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> // 외부 저장소 읽기 권한
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> // 내부 저장소 읽기 권한

 

 

그리고 카메라를 실행하기 위한 트리거로 Button과 동영상의 썸네일을 띄워줄 ImageView를 레이아웃에 만들어 줍니다.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/img_thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/ic_launcher_background" />

    <Button
        android:id="@+id/btn_record"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="record"
        app:layout_constraintEnd_toEndOf="@+id/img_thumbnail"
        app:layout_constraintStart_toStartOf="@+id/img_thumbnail"
        app:layout_constraintTop_toBottomOf="@+id/img_thumbnail" />
</androidx.constraintlayout.widget.ConstraintLayout>

 

 

이제 java 파일에 사용할 코드를 작성해보겠습니다.

public class MainActivity extends AppCompatActivity {

    private static int CAMERA_PERMISSION_CODE = 100; // 카메라 권한 코드

    ImageView thumbnail; // 동영상의 썸네일을 띄워줄 ImageView

    ActivityResultLauncher<Intent> launcher_record = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @RequiresApi(api = Build.VERSION_CODES.P)
                @Override
                public void onActivityResult(ActivityResult result) {
                    if (result.getResultCode() == Activity.RESULT_OK) { // 동영상 촬영 및 가져오기에 성공했을 경우
                        Log.d("launcher_record Callback", "video recording is succeed");

                        // 촬영된 동영상의 경로 Uri를 가져와 Uri 객체 변수에 참조
                        Uri videoPath = result.getData().getData();

                        // 미디어 파일에서 특정 프레임을 추출하기 위해 사용하는 클래스 객체 생성
                        MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
                        // 해당 객체에 동영상 경로 설정
                        mediaMetadataRetriever.setDataSource(MainActivity.this, videoPath);
                        // 영상의 0.1초 프레임을 가져와 Bitmap 변수에 저장
                        Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(100000);//0.1초 영상 추출

                        // 썸네일 비트맵 ImageView에 띄우기
                        thumbnail.setImageBitmap(bitmap);
                    }else if(result.getResultCode() == Activity.RESULT_CANCELED){ // 동영상 촬영이 취소되었을 경우
                        Log.d("launcher_record Callback", "video recording is canceled");
                    }else{ // 그 외 문제가 생겼을 경우
                        Log.e("launcher_record Callback", "video recording has failed");
                    }
                }
            });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 레이아웃 뷰 객체 각 변수에 참조
        thumbnail = (ImageView) findViewById(R.id.img_thumbnail);
        Button record = (Button) findViewById(R.id.btn_record);

        // 버튼 클릭시 실행할 이벤트 설정
        record.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // 해당 어플의 카메라 권한 확인 후 권한이 없다면 권한 요청, 권한이 있다면 카메라 어플 실행
                if(ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED){
                    // 토스트 메시지 띄우기
                    Toast.makeText(MainActivity.this, "카메라 권한 설정을 해주세요.", Toast.LENGTH_SHORT).show();

                    // 권한이 없을 경우 요청
                    ActivityCompat.requestPermissions(MainActivity.this, new String[] {android.Manifest.permission.CAMERA}, CAMERA_PERMISSION_CODE);
                }else{
                    // 토스트 메시지 띄우기
                    Toast.makeText(MainActivity.this, "동영상 촬영을 시작합니다.", Toast.LENGTH_SHORT).show();

                    // 카메라 어플에게 동영상을 촬영하고 그것을 반환하라는 표준 액션을 가진 인텐트 생성
                    Intent intent_record = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
                    // 해당 인텐트를 ActivityResultLauncher 사용해 실행 (결과 값을 받기 위함)
                    launcher_record.launch(intent_record);
                }
            }
        });
    }
}

 

이렇게 코드 작성을 완료하고 어플을 실행하면 아래 동영상처럼 촬영한 뒤 해당 영상 썸네일을 표시하는 것을 확인할 수 있습니다.