I'm developing an android application that records sound using Mediarecorder class
The following is a part from my code:
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.DEFAULT);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setAudioEncodingBitRate(16);
recorder.setAudioSamplingRate(44100);
try {
recorder.setOutputFile(path);
} catch (IllegalStateException e) {
e.printStackTrace();
}
recorder.prepare();
recorder.start();
}
when the recorder stops , i played it using mediaplayer class but the result sound is very thick and slow .. what could be the problem?
As per the MediaRecorder documentation the sampling rate for AMRNB is 8kHZ and you are setting this to a different value. I suspect this as the issue.
Can you comment these lines and check if that works for you:
//recorder.setAudioEncodingBitRate(16);
//recorder.setAudioSamplingRate(44100);
Related
so from my understanding is that the mediarecorder saves audio samples and binds them with a timeStamp to be able to seek through the audio file later (by the help of a prgressbar):
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setOutputFile(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
recorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
recorder.start();
My question
Is there any way to get these timestamps of audio samples real time while recording a voice?
please I need your help.
I'm writing an application to record video from camera through surface.
Following code is for preparing MediaRecorder.
MediaRecorder mediaRecorder;
mediaRecorder = new MediaRecorder();
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setOutputFile(videoFilename);
mediaRecorder.setVideoEncodingBitRate(1000000);
mediaRecorder.setVideoFrameRate(30);
mediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight());
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
Getting outfile(videoFilename) like this,
File defaultExternalFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File videoFolder = new File(defaultExternalFolder, "My-Vids");
if (!videoFolder.exists()) {
videoFolder.mkdir();
}
String timestemp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String prepend = "MyVid_" + timestemp + "_";
File videoFile = File.createTempFile(prepend, ".mp4", videoFolder);
videoFilename = videoFile.getAbsolutePath();
return videoFile;
videoSize is nothing but a Object Size class.
When I try to initiate MediaRecorder I get java.io.IOException: prepare failed.
Strange thing is It's crashing in Nougat OS only, in other devices It's working correctly.
I guess you are running this code on emulator. Actually MediaRecorder is not supported on emulator.
see:MediaRecorder
Note: Currently, MediaRecorder does not work on the emulator.
Well, you can test that by comment Mic config and you will see its working.
MediaRecorder mediaRecorder;
mediaRecorder = new MediaRecorder();
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
//mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setOutputFile(videoFilename);
mediaRecorder.setVideoEncodingBitRate(1000000);
mediaRecorder.setVideoFrameRate(30);
mediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight());
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
I have tested your code on Android 7.1 ( Samsung Galaxy S8 ) and its working. Issue on emulator only.
For me, the MediaRecorder -2147483648 error
was device and OS level dependent. Usually, the recorder
would start 1 time and subsequent starts would fail.
The fix was to add a call to MediaRecorder.release().
...
try {
audioRecorderType_MR.stop();
audioRecorderType_MR.release(); // <<-- ADD THIS LINE
} catch (Exception e) {
J42CallerId.printStackTrace(new J42ProgramCheck("J42VM0072E:", e));
}
audioRecorderType_MR = null;
...
I have an app that encodes in amr_nb format and output the file in amr. I want the recorded file to be broken into a series of amr files of 2 KB each. Got no clue on how to achieve this.
Here is the function called upon clicking Record Button
private void startRecording() {
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Here is the method called upon clicking Stop Button,
private void stopRecording() {
if (null != recorder) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
}
http://developer.android.com/reference/android/media/MediaRecorder.html#setMaxFileSize(long)
Then register your listener to MediaRecorder that gets a callback when the max file size is reached, then set up MediaRecorder to record the next file. Be aware there's a (good?) chance this will not produce a series of gapless files.
I have a RuntimeException when I call the method "start()" on my MediaRecorder object. I can not paste the stack trace because I have discovered the bug on Google Analytics.
This is the code:
MediaPlayer p = new MediaPlayer();
final MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
final String path = getOutputAudioFilePath(activity);
if (path == null)
return;
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path);
recorder.setMaxDuration(300000);
try {
recorder.prepare();
} catch (IOException e) {
Toast.makeText(activity,e.getMessage(),Toast.LENGTH_LONG).show();
}
recorder.start();
I run your code and it's all right. It works. But I used
final String path = getFilesDir().getAbsolutePath()+"/myFile"
instead.
So make sure your getOutputAudioFilePath(activity) method is returning a valid path and a path that does not require manifest permissions you haven't added, cause it might lead to the exception you are getting.
I've used following code as base to create a recorder. I can start and stop audio recording and it gets saved properly in the location. But now I have a requirments to pause the voice recorder
How to pause the audio recorder? And resume voice recording? I've seen a voice recording appliation in my samsung galaxy Ace, it has a pause button.
Can someone enlighten me.
public class audio {
final MediaRecorder recorder = new MediaRecorder();
final String path;
/**
* Creates a new audio recording at the given path (relative to root of SD card).
*/
public audio(String path) {
this.path = sanitizePath(path);
}
private String sanitizePath(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
if (!path.contains(".")) {
path += ".3gpp";
}
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.");
}
try {
recorder.setAudioSource(MediaRecorder.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();
// TODO: handle exception
}
}
/**
* Stops a recording that has been previously started.
*/
public void stop() throws IOException {
recorder.stop();
recorder.reset();
recorder.release();
}
public void pause() {
}
}
check out these 2 pages
http://developer.android.com/guide/topics/media/index.html
http://developer.android.com/reference/android/media/MediaRecorder.html
according to the first article there is a pause()
but i dont see a pause() method on that second link so im not sure
the other thing that the first article references:
"When you call stop(), however, notice that you cannot call start() again until you prepare the MediaPlayer again.
Always keep the state diagram in mind when writing code that interacts with a MediaPlayer object, because calling its methods from the wrong state is a common cause of bugs."
so maybe u can just stop() prepare mediaplayer then start() again