지난 포스팅에서 'MediaRecorder 를 이용한 오디오 레코딩 예제' 를 살펴보았습니다.

이번에는 지난번에 생성한 Project에 MediaRecorder API 를 이용한 캠코딩 예제를 추가해 보도록 하겠습니다.

즉 지난번에는 음성만 녹음하였다면, 이번에는 카메라로 들어오는 화면도 함께 캠코딩하는 것입니다.

 

1. Permission

우선 캠코딩을 하기 위해서 Camera 를 사용해야 하기 때문에, AndroidManifest.xml 에 Camera 관련 Permission 을 추가해 줍니다.

총 3개의 Permission 입니다. 음성을 녹음할 수 있는 권한과, 캠코딩된 파일을 저장해야 하기 때문에 External Storage 에 쓸수 있는 권한, 그리고 카메라로 들어오는 영상을 캠코딩해야 하므로 Camera 사용 권한도 함께 줄 수 있도록 합니다.

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>

 

2. Layout 구성하기

Layout은 지난번 구현하였던 오디오 레코딩 예제에 버튼을 하나 추가해서 캠코딩을 시작하고 정지할 수 있게 합니다.

카메라 프리뷰 화면과 녹화된 영상을 재생할 때 Video 를 뿌려줄 SurfaceView 를 하나 구성합니다.  

<Button
android:id="@+id/bt_camcording"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Camcording"/>



<SurfaceView
android:id="@+id/sv"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

캠코딩 시작 버튼이 눌렸을 때 캠코더를 시작하고, 다시 눌렸을 때 종료할 수 있도록 아래와 같이 OnClickListener 를 구현 해 줍니다.

mBtCamcording = (Button)findViewById(R.id.bt_camcording);
mBtCamcording.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
hasVideo = true;
initVideoRecorder();
startVideoRecorder();
}
});

 

3. Camera 와 Surface 연결 및 레코딩 시작 하기

위에서 버튼이 눌리면 가장 먼저 실행되는 initVideoRecorder() 함수에서는 Camera Device 를 open 하고, SurfaceHolder 를 초기화 하는 일을 수행 합니다.

Camera.open() 함수는 카메라 인스턴스를 리턴하고, 사용자는 이 객체를 통해 카메라 Device 에 접근할 수 있습니다.

Camera.open(int) 함수를 이용하면 Device 에 장착되어 있는 여러개의 카메라 중, 원하는 카메라에 접근하여 사용할 수 있습니다.

void initVideoRecorder() {
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
mSurfaceHolder = mSurface.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

mSurfaceHolder 에는 SurfaceView 의 getHolder 메소드를 통해 SurfaceHolder 의 인스턴스를 연결해 주고, Surface 의 변화가 있을 때 처리를 위해 Callback 을 등록해 줍니다.

두번째로 불리는 startVideoRecorder 함수에서는 MediaRecorder 를 초기화 하고, 실제 레코딩을 수행 합니다.

void startVideoRecorder() {
if(isRecording) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;

mCamera.lock();
isRecording = false;

mBtCamcording.setText("Start Camcording");
}
else {
runOnUiThread(new Runnable() {
@Override
public void run() {
mRecorder = new MediaRecorder();
mCamera.unlock();
mRecorder.setCamera(mCamera);
mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mRecorder.setOrientationHint(90);

mPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/record.mp4";
Log.d(TAG, "file path is " + mPath);
mRecorder.setOutputFile(mPath);

mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
try {
mRecorder.prepare();
}catch(Exception e){
e.printStackTrace();
}
mRecorder.start();
isRecording = true;

mBtCamcording.setText("Stop Camcording");
}
});
}
}

음성 녹음만 할 때는 Audio 에 관련된 설정들만 해주면 되었지만, 캠코딩인 경우에는 Video Source 에 대한 설정도 해주어야 합니다.

setCamera(..) :  비디오 레코딩 시 사용할 카메라를 설정해 줍니다.

setVideoSource(..) : 레코딩 시 비디오 소스를 설정합니다. DEFAULT, CAMERA, SURFACE 세개의 값 중 하나를 선택하면 됩니다.

setVideoEncoder(..) : 비디오 코덱을 설정합니다. Video Encoder 의 경우 DEFAULT, H263, H264, MPEG_4_SP, VP8, HEVC 등을 제공하고 있습니다.

Android 에서 제공하는 Video/Audio Encoder/Decoder 의 정보는 하기 사이트에서 더 자세하게 볼 수 있습니다.

https://developer.android.com/guide/topics/media/media-formats.html

 

각종 설정들을 마무리 하고 mRecorder.start() 를 호출하면 드디어 캠코딩이 시작됩니다.

캠코딩 시 Preview 화면은 MediaRecorder 의 setPreviewDisplay(..) 함수를 통해 설정해 준 SurfaceView 에 뿌려지게 됩니다.

 

4. 레코딩 한 파일 재생하기

재생의 경우에는 Audio 파일 재생과 완전히 동일하지만, Video 의 경우 화면을 뿌려주기 위한 Surface View 만 추가로 지정해 주면 됩니다.

기존에 만들어 두었던 Player Button 의 OnClickListener 에 아래와 같이 Video 를 가질 경우, 만들어 놓았던 SurfaceHolder 를 지정 해 주고,

if(hasVideo == true) {
mPlayer.setDisplay(mSurfaceHolder);
mPlayer.setOnCompletionListener(mListener);
}

Video 재생이 끝났을 경우 Button 의 Text 를 변경해 주기 위한 OnCompletionListener 를 등록해 줍니다.

MediaPlayer.OnCompletionListener mListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mBtPlay.setText("Start Playing");
}
};

등록된 Listener 에서는 간단하게 버튼의 Text 만 변경해 주었습니다.

 

여기까지 아직 많은 예외처리들이 필요하지만, 기본적인 오디오, 비디오 레코더를 완성 하였습니다.

MediaRecorder API와 Camera Class 에서 제공하는 API를 사용하면 이렇게 간단하게 레코딩 기능을 구현할 수 있습니다.

전체 소스는 https://github.com/bettercho/MyGithub/tree/master/MediaRecorder/app/src 를 참고해 주세요.

 

 

+ Recent posts