录制第二个音频剪辑时,MediaRecorder崩溃

时间:2011-09-22 23:42:09

标签: android eclipse audio-recording logcat

我正在尝试使用MediaRecorder录制音频片段,但是当我开始,停止并重新开始时,我一直在我的Logcat中收到这些错误;活动也将结束:

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 
……

录制音频剪辑并可以在计算机上播放,但如果我想录制另一个,则会发生上述情况。我已经在清单中要求许可了:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>

我使用了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");
  }

}

我的代码:

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:layout_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>

的字符串:

<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>

我没有很多编程经验,我不知道这意味着什么,或者如何在Google中搜索这个问题......如果有人能指出一个非常好的大方向:D

谢谢!

------------更新---------------

@Tim 从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

3 个答案:

答案 0 :(得分:2)

我有同样的错误,解决方案对我有用“和MediaRecorder recorder = new MediaRecorder();在开始时开始()”(Several audio recording in Android

答案 1 :(得分:1)

原来这是由于AudioRecorder类。由于新的MediaRecorder对象是在类的开头而不是在“start”方法中创建的,因此每次在“stop”方法中释放该对象,使其无用。

答案 2 :(得分:0)

我通过在停止功能中添加录音机解决了这个问题。

您需要在 stop()中添加此4行代码,然后才能启动第二个音频剪辑:

myRecorder = new MediaRecorder();
        myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        myRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
        myRecorder.setOutputFile(outputFile);

请参阅以下代码:

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();
    }
}