Android Audio Recording Tutorial
03/11/2009
After many hours of trying to record audio on my Google Android device, I’ve finally arrived at a workable solution. There were a few bumps along the way besides the horribly out of date MediaRecorder documentation, which was sorely lacking details. For one, I could only get audio to record to the SD card. Additionally, the directory being recorded to must already exist before attempting to record to it. Without further ado, here is a complete example for recording audio on the Android via the MediaRecorder API:
package com.benmccann.android.hello;
import java.io.File;
import java.io.IOException;
import android.media.MediaRecorder;
import android.os.Environment;
/**
* @author <a href="http://www.benmccann.com">Ben McCann</a>
*/
public class AudioRecorder {
final MediaRecorder recorder = new MediaRecorder();
final String path;
/**
* Creates a new audio recording at the given path (relative to root of SD card).
*/
public AudioRecorder(String path) {
this.path = sanitizePath(path);
}
private String sanitizePath(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
if (!path.contains(".")) {
path += ".3gp";
}
return Environment.getExternalStorageDirectory().getAbsolutePath() + path;
}
/**
* Starts a new recording.
*/
public void start() throws IOException {
String state = android.os.Environment.getExternalStorageState();
if(!state.equals(android.os.Environment.MEDIA_MOUNTED)) {
throw new IOException("SD Card is not mounted. It is " + state + ".");
}
// make sure the directory we plan to store the recording in exists
File directory = new File(path).getParentFile();
if (!directory.exists() && !directory.mkdirs()) {
throw new IOException("Path to file could not be created.");
}
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path);
recorder.prepare();
recorder.start();
}
/**
* Stops a recording that has been previously started.
*/
public void stop() throws IOException {
recorder.stop();
recorder.release();
}
}
Hi Piyush, I’ve never recorded video on Android, so I’m afraid I can’t be of much help. Hopefully it’s not too different. Best of luck! -Ben
Hi is any idea how stream audio recording on server? You speak and behaind all what you say save to buffer and stream on server.
I dont know how save audio from mic to buffer..
THX
Hello Ben .
i am trying to record and save voice.My code is not working, i am definately making some mistake.can some please give me sample code to record i tried the above example.
Please help.
hi ben,
how can someone receive a buffer of audio data once its recorded and is ready to be written to file or stream or something else. is there any callback by the mediarecorder or a notification? so that the code can access that buffer and can go ahead and use it.
appreciate your response and time.
thanks
pk
Can anyone tell me what sensors can be used in the emulator with SDK 2.0 and can audio recording be done in the Android emulator?
Hi Deepa, you can record audio on the Android emulator.
The example does not work for me. This is the problem I’m experiencing:
http://code.google.com/p/android/issues/detail?id=5063
Has anyone also encountered this, and been able to find a workaround? SDK 2.1 and Nexus One.
Hello,
I’m a beginner in Android and request any help on the following.
I’m trying to use an SDCard loaded on to the Emulator and store files
programmatically.
The code snippet is as below
public class Downloader {
public Downloader(String path) {
this.path=sanitize(path);
Log.d(“DEBUG”,”The File Path is ” + path);
}
public String sanitize(String path) {
if (!path.startsWith(“/”)) {
path = “/” + path;
}
return Environment.getExternalStorageDirectory().getAbsolutePath()
+path;
}
public void start() throws IOException {
// Check if Media is mounted else throw IOException
String state = Environment.getExternalStorageState();
if(state != Environment.MEDIA_MOUNTED) {
Log.d(“DEBUG”, “The Card is Not Mounted ” + state +”–“);
throw new IOException (“SD Card is not Mounted. It is in ” + state);
}
}
With the above code I’m able to see the “The Card is Not Mounted –”
message in the logcat. I’m making use of the following permissions in
the manifest.xml
Questions
1. Are there additional permissions to be included?
2. The Downloader.java is a helper class whose object is being used in
a Receiver. Does giving the receiver the WRITE_EXTERNAL_STORAGE would
also enable Downloader.java to access the SDCard
3. Any other suggestions
Best Regards
Acer
I have recorded several files on my android using the voice recorder, but I can not figure out how to ge t them off my card or convert them to a .wav file. Could you provide some help? Thanks.
You can get the files off by using adb. Find out where the file is by executing “adb shell ls /sdcard” and then executing
“adb pull “.
Fellow developers, for those having trouble with this MediaRecorder example, or any MediaRecorder sample code in the web (a lot of developers are facing the same issue and nobody answers), I recommend trying adding WRITE_EXTERNAL_STORAGE permission to your Android Manifest file, in the case that you are trying to record media to your external SDCARD. Adding the following line should do the trick. Let me know if it worked.
Thank You Ben…
and very much thank you too Matias de la Vega …..
you solved a great problem
now my code is running very well and i m able to record and play the audio from emulator…
now wat about video?, i know dat emulator does not support video recording…but is there any trick?what is the way for a developer for checking out if his code fr recording a video is working properly ….I m not having real android device…only emulator….
Where does an Android emulator capture input audio from and output to when testing recording and playback? Also, for param4android, did you test with Linux or Windows Android emulator? Thanks.
Following Ben’s code and comments in this RSS feed, we were able to write an audio recorder and player for an Android emulator on Windows. However, on playback we found the recorded audio is at half speed of the input audio, with correct pitch but with noise. Since many in this feed reported successes using an emulator to record and play audio, may we ask how the emulators are configured, which version and on what platform? Thanks.
Hi Ben,
can you send me a code which can connect to remote server and read the response from the server.I have one project.it is able to write to socket but cant read from server socket.If u can send me your email id i will send it to you because there is no attachment option over here
Thanks much
Can anybody tell where exactly the file get stored. I cant see any file.
i am getting following n error when I try to set recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
ERROR/audio_input(52): unsupported parameter: x-pvmf/media-input-node/cap-config-interface;valtype=key_specific_value
ERROR/audio_input(52): VerifyAndSetParameter failed
ERROR/PVOMXEncNode(52): PVMFOMXEncNode-Audio_AMRNB::DoPrepare(): Got Component OMX.PV.amrencnb handle
Any one can tell me why its happening
but it shows audio source not found how to configure system MIC to the android application
Hi
Has anyone had any success with setting the AudioSource to VOICE_CALL? It seems to only record one side of the conversation.
Really really need help here.
Thanks
hi SISI how u doing? i have copied ur whole above code but btnlistener1 is working but the below code has lots of sysntax mistake. i want to integrate this whole class with main class how can i do dis please help me.
//folgendes passiert, wenn auf btn2 geklickt wird
private OnClickListener btnListener2 = new OnClickListener()
{
public void onClick(View v)
{
MediaPlayer mp = new MediaPlayer();
Toast.makeText(getBaseContext(),
“Hello, please stop!” + mp.isPlaying(),
Toast.LENGTH_LONG).show();
/*
try {
recorder.stop();
} catch (IOException e) {
}*/
}
};
//folgendes passiert, wenn auf btn3 geklickt wird
private OnClickListener btnListener3 = new OnClickListener()
{
public void onClick(View v)
{
MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(“C:/Bochum”);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.start();
Toast.makeText(getBaseContext(),
“Hello, please play!” +” is playing?: “+ mp.isPlaying(),
Toast.LENGTH_LONG).show();
}
};
}
SISI your code is error free but can u please tell me that u have created an object of AUDIORECORDER2 class which is described by the author. now can u please tell me that how did u run the programme. actually i am using 3 classes
1- iSnore.java: this file contains the UI like input name, time setting e.t.c. this class has a button. now i want to create an event like if i click the DONE button than recording starts.
2-AudioRecorder2.java: this class is same as the 1st code of this blog.
3-Record.java: this class contains your code.
now i want to call class number 3 on the button DONE of class 1. How can i do this.Please help me.
I tried your code, it kind of working for me. It can create a .3gp file, but I can’t open the file after download it to PC.
Seems it just create a file with name contains “.3gp”, but it’s not a legal 3gp file.
hi i have enabled soundrecorder in android eclair. With sd card as the storage media, i am able to record and the file is also getting created as .3gp but i am not able to playback the recorded file.
Thanks.
It works.
Hi. I have your helper class http://pastebin.com/JVzgmGCR
and my activity http://pastebin.com/Vs2dAaFv
For whatever reason the .start() and .stop() of your helper class just make the app crash every time.
Adding the permission which I didnt know was needed, fixed the .start()
But the .stop() is still making the application crash. The file is being created in the /sdcard/test directory but is 0 seconds long. I figure this has to do with not stopping and releasing the stream.
Does anyone know why the method would cause a crash?
public void stop() throws IOException {
recorder.stop();
recorder.release();
}
I now have the phone recording and not crashing on the start stop or release. But when I check the file on the card it still comes out as 0 seconds long. Im giving it time and speaking into it just to be sure. Is there any piece I’m missing in making the file store what is supposedly recording?
Hello Ben:
I saw two men ask the same question but you as well as others didn’t answer it. I really want to kown the response.I play the audio in the emulator which is just recorded but it is half speed. And the quality is terrible. Why ? How to deal with it.
Hope to receive your response.
My program started working fine and now records and plays it back all within the same activity. Not sure what I did to fix it if anything.
Hey Ben,
first thanks for your great tutorial….it does work 😀 I guess I don’t tell anything new.
Is it possible to set the AudioSource to the Speaker??? So I could record what i’m playing at the same time??
Hope u got a quick answere for me 🙂
Thanks again
Great tutorial!
but please can anyone give the complete code along with the xml code, please!
Hello, can anybody paste the Entire code (along with MainActivity , xmls , and Android Manifest )… ?
Instead of writing in broken format write it in entire!
@vibs, this isn’t broken format. What you are asking is for someone to make an app for you so that you can take the entire source code and put your name on it. Not very fair if you ask me!
Why don’t you try posting something helpful before asking others to write an entire app for you? Come on!
Hi All,
I am also facing the same problem as Invenco has mentioned. The quality of the sound recorded using MediaRecorder as given in the code by Ben is really terrible. Also, the speed is low.
Does anybody know the solution to this problem?
Regards,
Nilesh
Hi, I have one question.
Is that possible to pause or resume the recording on the eclair or froyo?
As I checked, there is no API to pause or resume the recording in the android framework.
But I found an application to support the pause/resume on the eclair.
When checking the logs, it seems not to use the opencore PV layer. It was different with the native sound recorder logs. That means there’s way to pause or resume in the android platfom (withoug using the opencore????)….
Does anybody know how to pause or resume the recording?
Sincerely,
Clair
Hello Ben (or Anyone),
Thanks for the tutorial! I was able to run it.. It works well..
Does anyone have any idea if I want to store the recorded audio in internal memory?
Thanks in advance..
Hi,
How can I measure the start,stop,duration and pause time with progress bar for different video which is streaming from website?
i’ve a problem, may be in the prepare or after it
i have no errors or exception
i got output file .3gp
but the file is 0 size, with no header, not data, nothing just empty file created
i’m using the MediaRecorder.AudioSource.VOICE_CALL as audio source
i’ve the following permissions
can any one help me with the 0 size file issue, i want it to record the call
Great tutorial!
but please can anyone give me the code to record the conversation on external memory , please!
Is it possible to lift,cut,intercept a incoming call programatically. any one plz help in figuring this.
Hi , i followed your code its very nice ,,, but the thing is i’m getting errors like
09-24 16:28:52.179: ERROR/audio_input(31): unsupported parameter: x-pvmf/media-input-node/cap-config-interface;valtype=key_specific_value
09-24 16:28:52.241: ERROR/audio_input(31): VerifyAndSetParameter failed
09-24 16:28:50.297: ERROR/PVOMXEncNode(31): PVMFOMXEncNode-Audio_AMRNB::DoPrepare(): Got Component OMX.PV.amrencnb handle
here is my code … pls help me out…. http://pastebin.com/hed45LD6
Hi make use of the following code
http://pastebin.com/JVzgmGCR
and my activity http://pastebin.com/Vs2dAaFv
The thing is i’m not finding “sdcard/test/tmp.3gp” and its also showing errors in logcat as
09-24 17:13:58.708: ERROR/audio_input(31): unsupported parameter: x-pvmf/media-input-node/cap-config-interface;valtype=key_specific_value
09-24 17:13:58.817: ERROR/audio_input(31): VerifyAndSetParameter failed
Please help me out….
Hello!!! I’m trying to record some files into the internal memory!!
Does anybody know how to access to the internal memory. What is the command to access /data/data/ and the record the file there?
Anybody knows how to deletea file from the internal memory?
Thanks in advance
We are getting a .6 seconds of dead space at the beginning of each recording when using this code. Is this the norm or maybe its something screwy I am doing. Feedback appreciated.
how to sned stream to socket but not save as local file?
Can any one tell at what sampling rate this record application records?
If i want to have option to select sampling rate in my application what changes i need to do?
Thanks in advance,
Rajiv
Hi,
Thanks for your nice tutorial.
I am trying a similar solution where my idea is to record and send the voice from android to an ip camera, where it uses a http:///axis-cgi/transmit.cgi. then it should play in ip camera speaker.
please help me how can i proceed in this task if you have some suggestions.
Thanks & Regards,
Karumanchi
can anyone help me ,
i get this error wen i run the below code to record the voice
12-08 05:57:13.441: ERROR/MediaRecorder(292): setOutputFormat called in an invalid state: 1
12-08 05:57:13.491: WARN/System.err(292): java.lang.IllegalStateException
12-08 05:57:13.541: WARN/System.err(292): at com.android.manage.Sending$AudioRecorder.start(Sending.java:101)
here i have created 3 btns record,stop,play
wen i click on stop it gives me the below error
12-08 05:57:15.521: ERROR/MediaRecorder(292): stop called in an invalid state: 1
iam new to android please can anyone help me
public class AudioRecorder {
MediaRecorder recorder = new MediaRecorder();
final String path;
public AudioRecorder(String path) {
this.path = sanitizePath(path);
}
private String sanitizePath(String path) {
if (!path.startsWith(“/”)) {
path = “/” + path;
}
if (!path.contains(“.”)) {
path += “.3gp”;
}
return Environment.getExternalStorageDirectory().getAbsolutePath() + path;
}
public void start() throws IOException {
String state = android.os.Environment.getExternalStorageState();
if(!state.equals(android.os.Environment.MEDIA_MOUNTED)) {
throw new IOException(“SD Card is not mounted. It is ” + state + “.”);
}
// make sure the directory we plan to store the recording in exists
File directory = new File(path).getParentFile();
if (!directory.exists() && !directory.mkdirs()) {
throw new IOException(“Path to file could not be created.”);
}
try{
System.out.println(“starting audio “);
recorder.setAudioSource(AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path);
recorder.prepare();
recorder.start();
}
catch(Exception e){
e.printStackTrace();
}
}
public void stop() throws IOException {
recorder.stop();
recorder.release();
}
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.message);
record=(Button)findViewById(R.id.record);//record button
record.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
final AudioRecorder recorder = new AudioRecorder(“/res/raw”);
try {
recorder.start();
} catch (IOException e) {
e.printStackTrace();
}
}
});
stop=(Button)findViewById(R.id.stop);//Stop button
stop.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
recorder.stop();
recorder.release();
}
});
I have microphone instead of phone. So it will throws SD card is removed error. What can i do? How can i change the path? and is it possible in windows?
xyz i get the same error, i’m running the application in the emulator, did you solve your problem?