안드로이드에서 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
이 글보고 해결했어요. 너무 기쁘네요.
감사합니다. 복많이 받으세요. ^^