티스토리 뷰



이 자료들은 팁스소프트에서 제공하는 [ 알짜배기 ] 프로그램을 이용하면 더 편리하게 볼수 있습니다.
* 알짜배기 프로그램 받기 - http://www.tipssoft.com/bulletin/tb.php/QnA/8406
* 관리자의 Tipssoft 이야기를 들어보세요 ( 트위터 ID : tipssoft )
* 안드로이드 강좌 목록 - http://www.tipssoft.com/bulletin/tb.php/old_bbs/501
기본적으로 스마트폰은 마이크와 스피커를 내장하고 있습니다. 따라서 많은 어플리케이션에서 효과적인
사용자 인터페이스를 위해서 음성 데이터를 지원하는 경우가 늘어나고 있습니다. 예를 들어 카카오톡
같은 경우, 문자채팅뿐만 아니라 음성을 녹음하여 상대편에 전송할 수 있고, 전송받은 사용자는 해당
음성을 카카오톡 어플리케이션을 통해서 들을 수도 있습니다.
이렇게 자신이 만든 어플리케이션에서 음성을 녹음하고 재생하는 기능을 제공하는 방법에 대하여
소개하도록 하겠습니다. 이번 강좌에서는 녹음과 재생에 관련된 기초적인 원리와 구현 방법에 대해서
간단하게 설명할 것입니다.
1. 녹음하기
녹음은 어플리케이션 레벨에서 직접 제어하고, 수행할 수 없습니다. 그래서 어플리케이션에서는
Recorder 엔진에 여러가지 설정 작업이나 녹음 명령을 전달하여 녹음 작업을 수행하게 됩니다.
안드로이드 SDK 에서 이러한 역할을 해주는 클래스가 MediaRecorder 입니다.
아래의 그림은 MediaRecorder 객체의 상태를 다이어그램으로 표현한 것입니다. 각 상태에서 어떤
메소드를 호출하냐에 따라서 상태가 달라지게되며 각 상태에 맞지 않은 메소드를 호출하면
IllegalStateException 예외가 발생하므로 메소드를 순서에 맞게 호출해야 합니다
위의 각 상태를 코드와 함께 구성하여 보면 아래와 같습니다.
// 녹음 작업을 수행할 수 있는 MediaRecorder 객체를 할당한다.
MediaRecorder m_recorder = new MediaRecorder();
< Initial 상태 >
// 녹음을 할 때 사용할 오디오 장비를 설정합니다. 이 메소드는 setOutputFormat 메소드 호출전에
// 반드시 호출해야 합니다.
m_recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
< Initialized 상태 >
// 녹음된 데이터가 저장될 파일의 포맷을 설정합니다. 이 메소드는 prepare 메소드 호출전에 반드시
// 호출해야 합니다. 만약 H.263 비디오 인코더를 사용하거나 AMR 오디오 인코더를 사용하는 경우
// " 3GP " 포맷을 사용해야 합니다.
m_recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
< DataSourceConfigured 상태 >
// 녹음된 데이터가 저장될 파일 경로를 설정합니다.
m_recorder.setOutputFile("ExamRecordingActivity.3gp");
// 녹음에 사용할 오디오 인코더를 설정합니다. 이 메소드는 반드시 호출되어야 합니다.
m_recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
< DataSourceConfigured 상태 >
// 녹음을 할 준비를 합니다. 이 메소드는 인코더 설정, 경로설정, 볼륨 설정 등 모든 설정을 한 후에
// 호출해야 합니다.
m_recorder.prepare();
< Prepared 상태 >
// 녹음을 시작합니다. 녹음을 진행하는 동안 또 다른 어플리케이션에서 start 메소드를 호출해서는
// 안됩니다.
m_recorder.start();
< Recoding 상태 - 녹음중 >
// 녹음을 중지합니다. 녹음 상태(start 메소드 호출 후)에서 호출되어야 합니다.
m_recorder.stop();
// MediaRecorder 객체를 Initial 상태로 되돌립니다. 녹음을 수행하려면 또 다시 이전에 수행했던
// 설정 및 구성작업을 수행해야합니다.
m_recorder.reset();
< Initial 상태 >
// MediaRecorder 객체가 사용한 자원들을 되돌려줍니다. release 메소드를 호출한 후에
// 다시 녹음 작업을 수행하려면 객체 생성부터 다시 해주는 것이 좋습니다.
m_recorder.release();
< Released 상태 >
m_recorder = null;
위의 코드는 가장 간단하게 녹음하기 위한 최소한의 코드이며 채널, 샘플링비율, 최대 녹음시간,
최대 파일 크기 사이즈 등을 설정할 수도 있습니다. 또한 어플리케이션에서 직접적으로 알 수 없는
Recorder 엔진이 아는 정보나 에러 사항들은 리스너를 등록하여 통보받을 수도 있습니다.
이러한 자세한 사항은 추후에 다음 강좌에서 알아볼 것입니다.
2. 재생하기
위에서 다룬 녹음처럼 재생 또한 어플리케이션 레벨에서 직접 제어하고, 수행할 수 없습니다.
그래서 Player 엔진에 여러가지 설정 작업이나 재생 명령을 전달하여 재생 작업을 수행하게 됩니다.
안드로이드 SDK 에서 이러한 역할을 해주는 클래스가 MediaPlayer 입니다.
아래의 그림은 MediaPlayer 객체의 상태를 다이어그램으로 표현한 것입니다. 각 상태에서 어떤
메소드를 호출하냐에 따라서 상태가 달라지게되며 각 상태에 맞지 않은 메소드를 호출하면
IllegalStateException 예외가 발생하게 됩니다. 재생은 아래의 그림보다 녹음에 비해 많은 상태가
존재하고 여러가지 메소드를 호출하여 다양한 상태의 변화를 할 수 있지만 이번 강좌에서는 간단한
실행 방법만을 소개할 것입니다.
위의 각 상태를 코드와 함께 구성하여 보면 아래와 같습니다.
// 재생 작업을 수행할 수 있는 MediaPlayer 객체를 할당한다.
MediaPlayer m_player = new MediaPlayer();
// 재생의 경우 재생이 완료되어 더이상 재생할 데이터가 없어지면 재생을 중지해야하기 때문에
// 재생의 완료시점에 콜백해줄 리스너를 등록해주어야 합니다.
m_player.setOnCompletionListener(m_play_complete);
< Idle 상태 >
// 재생할 데이터의 파일 경로나 URL 경로를 설정합니다.
m_player.setDataSource("ExamRecordingActivity.3gp");
< Initialized 상태 >
// 재생을 준비합니다. 파일을 재생하는 경우 이 메소드가 정상적으로 호출되었다면 MediaPlayer
// 객체는 재생이 준비될 때까지 대기하게 됩니다.
m_player.prepare();
< Prepared 상태 >
// 재생을 시작합니다.
m_player.start();
< Started 상태 - 재생중 >
// OnCompletionListener 리스너를 등록했다면 재생이 완료될 시점이 리스너의 onCompletion
// 메소드가 호출됩니다. 이 메소드 안에서 stop 메소드나 reset 메소드들을 호출하여 정상적으로
// 재생을 중지시켜주는 것이 좋습니다.
CALLBACK : OnCompletionListener - onCompletion
< PlaybackCompleted 상태 >
// 재생을 중지시킵니다.
m_player.stop();
< Stopped 상태 >
// MediaPlayer 객체에 관련된 자원들을 모두 해제해줍니다. release 를 수행하여 End 상태에
// 돌입한 경우 MediaPlayer 객체를 재사용하지 않고 객체 생성을 새로하여 사용하길 권합니다.
m_player.release();
< End 상태 >
m_player = null;
MediaPlayer 객체를 사용하다가 release 메소드를 호출하면 자원이 해제되는 즉시 Player 엔진이
해당 자원을 사용할 수 있기때문에 다시 해당 객체를 사용하지 않는 것이 좋습니다.
위의 코드는 가장 간단하게 재생하기 위한 최소한의 코드이며 재생 지점 설정이나 중지(Pause),
재시작, 볼륨 설정 그리고 각종 리스너 사용법에 대한 부분은 포함되어 있지 않습니다. 이러한 자세한
사항은 추후에 다음 강좌에서 알아볼 것입니다.
3. 첨부된 예제
이 글에 첨부된 파일에는 녹음과 재생 기능을 구현한 프로젝트 폴더가 압축되어 있습니다.
해당 프로젝트에는 위의 코드보다 자세한 설명과 예외처리가 포함되어 있습니다.

 

댓글