안드로이드에서 MediaRecorder를 이용해 녹음하는 것은 쉽지만, 조금 더 심도있는(?) 녹음을 위해서는 AudioRecorder 클래스를 이용해야한다.
AudioRecorder로 MP3를 녹음하는 방법은 WAV를 녹음하는 방법과 크게 다르지 않다. – 기회가 되면 WAV도 포스팅하기로 하고.
일단 MP3녹음을 위해 외부 library를 import한다.
일본인이 만든 듯한 SimpleLameLibForAndroid라는 라이브러리가 잘 쓰이는 듯 하며 구글에 많은 예제가 있으나 뭔가 복잡한 듯.
이를 간소화 시킨 버전이 있으며, 이를 이용한 프로젝트인 Mp3VoiceRecorderSample을 불러온다.
https://github.com/yhirano/Mp3VoiceRecorderSampleForAndroid
Import하는 방법은 Eclipse에서 좌측 Package Explore에서 마우스 우측 버튼 – Import -> Existing Android code… 를 이용해서 불러온다.
그 뒤 Mp3VoiceRecorderSampleForAndroid 프로젝트 위에서 마우스 우측버튼 – 맨아래 Properties – 메뉴의 Android 항목에서 Target Build 아래쪽에 Library -> Is Library 체크 박스를 선택해놓는다.
이제 이 라이브러리를 이용하려는 프로젝트 위에서 다시 마우스 우측버튼 – Properties – 메뉴의 Android 항목에서 Target Build 아래쪽에 Library 에서 Mp3Voice… 라이브러리를 추가한다.
이제 아래는 소스코드
import com.uraroji.garage.android.lame.SimpleLame;
public class RecordService extends Service implements Runnable {
static {
System.loadLibrary("mp3lame");
}
사용을 원하는 클래스에 패키지 및 Library를 로드한다.
파일 생성 -> 함수 내부는 적절히 변경할것
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
public static String getTempMP3Filename()
{
String filepath = Environment.getExternalStorageDirectory().getPath();
Date dt = new GregorianCalendar().getTime();
String AUDIO_RECORDER_MP3_FILE = "record_" + String.valueOf(dt.getTime()) + ".mp3";
Log.d(TAG,"Name : " + AUDIO_RECORDER_MP3_FILE);
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
File tempFile = new File(filepath,AUDIO_RECORDER_MP3_FILE);
if(tempFile.exists())
tempFile.delete();
return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_MP3_FILE);
}
적절한 위치에 변수 정의
FileOutputStream mp3file = null; String mp3name;
적절한 위치에서 파일 생성
mp3name = getTempMP3Filename();
try
{
mp3file = new FileOutputStream(mp3name);
{
e.printStackTrace();
}
적절한 위치에서 AudioRecorder 초기화 및 버퍼 생성
int frequency = 44100; //8000;
int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
audioRecord = new AudioRecord( MediaRecorder.AudioSource.MIC, frequency,
channelConfiguration, audioEncoding, bufferSize);
audioRecord.startRecording();
byte[] mp3buffer = new byte[(int) (7200 + bufferSize * 2 * 1.25)];
short[] buffer = new short[bufferSize];
SimpleLame.init(frequency, 1, frequency, 32);
여기서 주목할 것은 mp3의 버퍼 사이즈다.
Lame의 메뉴얼을 보면
@param mp3buf result encoded MP3 stream. You must specified
* “7200 + (1.25 * samples)” length array.
라고 되어있는데, MONO channel임에도 불구하고 Mp3Voice…예제에서는 x2를 한다.
그리고 프로그램 실행시 문제 없이 작동하는 것으로 보아 이렇게 둬도 되는 듯 하다.
init하는 함수의 parameter들은 SimpleLame.java파일에 설명이 나와있으니 적절히 수정할 것
이제 적절히 Thread함수에서 녹음을 시행한다.
while (threadState)
{
int bufferReadResult = audioRecord.read(buffer, 0,bufferSize);
byte[] byteBuffer = ShortToByte(buffer,bufferReadResult); //이건 WAV 만들 때 이용할 수 있다
int encResult = SimpleLame.encode(buffer,
buffer, bufferReadResult, mp3buffer);
if (encResult != 0) {
try {
mp3file.write(mp3buffer, 0, encResult);
} catch (IOException e) {
break;
}
}
}
//Thread가 끝나면 남아있는 버퍼를 정리한다.
flushResult = SimpleLame.flush(mp3buffer);
if (flushResult != 0) {
try {
mp3file.write(mp3buffer, 0, flushResult);
} catch (IOException e) {
Log.d(TAG,"MP3 flush error");
}
}
//close file
try {
mp3file.close();
} catch (IOException e) {
e.printStackTrace();
}
이것으로 끝

1 comment
이 글보고 해결했어요. 너무 기쁘네요.
감사합니다. 복많이 받으세요. ^^