MediaRecorder crashes when record a second audio clip
I am trying to record audio clips with MediaRecorder, but I keep getting these errors in my Logcat when I start, stop, and start again; the activity would also close:
INFO/DEBUG(1285): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
INFO/DEBUG(1285): Build fingerprint: 'LGE/thunderg/thunderg/thunderg:2.2.1/FRG83/eng.nikech.choi.20110126.134422:user/release-keys'
INFO/DEBUG(1285): signal 11 (SIGSEGV), fault addr 00000010
INFO/DEBUG(1285): r0 00000000 r1 00000000 r2 a930cc98 r3 00000001
……
INFO/DEBUG(1285): #00 pc 00033c28 /system/lib/libmedia.so
INFO/DEBUG(1285): #01 pc 0000780e /system/lib/libmedia_jni.so
……
INFO/DEBUG(1285): code around pc:
INFO/DEBUG(1285): a9033c08 2001e001 1c1861a0 46c0bd70 00029a58
……
INFO/DEBUG(1285): code around lr:
INFO/DEBUG(1285): a93077f0 f7ffb510 bd10ffcf b082b570 ae011c05
……
INFO/DEBUG(1285): stack:
INFO/DEBUG(1285): bef054d0 00000001
……
An audio clip is recorded and can be played on the computer, but if I want to record another one, the above happens. I have already asked for permission in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
I used this code from Ben McCann:
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.reset();
System.out.println("reset");
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
System.out.println("setAudioSource");
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
System.out.println("setOutputFormat");
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
System.out.println("setAudioEncoder");
recorder.setOutputFile(path);
System.out.println("setOutputFile");
recorder.prepare();
System.out.println("prepare");
recorder.start();
System.out.println("start");
}
/**
* Stops a recording that has been previously started.
*/
public void stop() throws IOException {
recorder.stop();
System.out.println("stopped");
recorder.release();
System.out.println("released");
}
}
My code:
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class TestActivity extends Activity implements OnClickListener {
private final String TAG = TestActivity.class.getSimpleName();
Button startRecord;
Button stopRecord;
boolean recordStarted = false;
private static String fileName = "/Recordings/event.3gp";
AudioRecorder audioRecorder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.record);
startRecord = (Button)findViewById(R.id.buttonStartRecord);
stopRecord = (Button)findViewById(R.id.buttonStopRecord);
startRecord.setOnClickListener(this);
stopRecord.setOnClickListener(this);
audioRecorder = new AudioRecorder(fileName);
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "resumed");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "paused");
}
@Override
public void onClick(View v) {
if (v == startRecord){
try {
audioRecorder.start();
Toast.makeText(this, R.string.msgRecordSuccessful,
Toast.LENGTH_SHORT).show();
recordStarted = true;
Log.e(TAG, String.format("recording: %s", recordStarted));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, R.string.msgRecordFail, Toast.LENGTH_SHORT).show();
}
} else if (v == stopRecord){
if (recordStarted == true) {
try {
audioRecorder.stop();
recordStarted = false;
Log.e(TAG, String.format("recording: %s", recordStarted));
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, R.string.msgNotRecording, Toast.LENGTH_SHORT).show();
}
}
} // end onClick
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layou开发者_开发问答t_width="match_parent"
android:layout_height="match_parent">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="start"
android:id="@+id/buttonStartRecord"></Button>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/buttonStopRecord"
android:text="Stop"></Button>
</LinearLayout>
Strings:
<string name="msgReset">reset</string>
<string name="msgSetAudioSource">setAudioSource</string>
<string name="msgSetOutputFormat">setOutputFormat</string>
<string name="msgSetAudioEncoder">setAudioEncoder</string>
<string name="msgSetOutputFile">setOutputFile</string>
<string name="msgPrepare">prepare</string>
<string name="msgStart">start</string>
I don't have a lot of programming experience and I have no idea what this means or how to even search for this problem in Google... if anybody can point me in a general direction that would be really nice :D
Thank you!!
------------ updates ---------------
@ Tim the few lines after the debug block from logcat:
INFO/ActivityManager(1362): Process com.bcit.chairlogger (pid 26461) has died.
INFO/WindowManager(1362): WIN DEATH: Window{44f04e20 com.bcit.chairlogger/com.bcit.chairlogger.TestActivity paused=false}
INFO/ActivityManager(1362): Displayed activity com.bcit.chairlogger/.TestActivity: 106629 ms (total 106629 ms)
INFO/UsageStats(1362): Unexpected resume of com.lge.launcher while already resumed in com.bcit.chairlogger
WARN/Flex(1456): getString FLEX_OPERATOR_CODE TLS
WARN/Flex(1456): getString FLEX_OPERATOR_CODE TLS
INFO/#LGIME(1442): #### onStartInput: restarting=false, fieldId=-1
WARN/InputManagerService(1362): Got RemoteException sending setActive(false) notification to pid 26461 uid 10071
i had same error, solution that worked for me "And MediaRecorder recorder = new MediaRecorder();
at the beginning of start()" (Several audio recording in Android)
I solved this issue by adding the recorder in stop functionality.
You need to add this 4 line code inside stop() then only you can start the second audio clip:
myRecorder = new MediaRecorder();
myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myRecorder.setOutputFile(outputFile);
Refer below code:
public void stop(View view) {
try {
myRecorder.stop();
myRecorder.reset();
myRecorder.release();
stopBtn.setEnabled(false);
playBtn.setEnabled(true);
startBtn.setEnabled(true);
myRecorder = new MediaRecorder();
myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
myRecorder.setOutputFile(outputFile);
} catch (IllegalStateException e) {
// it is called before start()
e.printStackTrace();
} catch (RuntimeException e) {
// no valid audio/video data has been received
e.printStackTrace();
}
}
Turns out it was due to the AudioRecorder class. Since the new MediaRecorder object is created at the beginning of the class rather than in the "start" method, the object is released every time in the "stop" method, rendering it useless.
精彩评论