2011-09-22 29 views
5

Tôi đang cố gắng ghi các clip âm thanh bằng MediaRecorder, nhưng tôi vẫn gặp phải các lỗi này trong Logcat khi bắt đầu, dừng và bắt đầu lại; hoạt động cũng sẽ đóng:MediaRecorder gặp sự cố khi ghi lại clip âm thanh thứ hai

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

Đoạn âm thanh được ghi và có thể phát trên máy tính, nhưng nếu tôi muốn ghi âm một clip khác, điều này sẽ xảy ra. Tôi đã xin phép trong biểu hiện:

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

tôi đã sử dụng mã này từ Bến 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"); 
    } 

} 

Mã của tôi:

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> 

Chuỗi:

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

Tôi không có nhiều kinh nghiệm lập trình và tôi không biết ý nghĩa của việc này hoặc cách tìm kiếm vấn đề này trong Google ... nếu ai đó có thể chỉ cho tôi một hướng chung thực sự tốt đẹp: D

Cảm ơn bạn !!

cập nhật ------------ ---------------

@ Tim vài dòng sau khi khối debug từ 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 
+0

Có một số một phần của Dấu vết ngăn xếp của bạn tham chiếu loại ngoại lệ nào được ném và dòng nào được ném bởi? Những gì bạn đã đăng là dấu vết ngăn xếp của bạn chứa chủ yếu là những gì dường như là địa chỉ bộ nhớ mà không có nghĩa là bất cứ điều gì để bất cứ ai đọc này. Hãy tìm một thứ gì đó trong Nhật ký Cát có từ Ngoại lệ trong đó và đăng phần đó. – FoamyGuy

+0

yeah đó là phần - KHÔNG CÓ NGOẠI LỆ !!! Vì vậy, tôi siêu bối rối và không biết những gì để tìm kiếm – Lily

+0

Ok tôi thấy ngoại lệ này trong màu da cam (cho Eclipse) sau khối gỡ lỗi ở trên: WARN/InputManagerService (1362): Got RemoteException gửi thông báo setActive (false) đến pid 26461 uid 10071 Điều này có ý nghĩa gì không? – Lily

Trả lời

1

Hoá ra là do lớp AudioRecorder. Vì đối tượng MediaRecorder mới được tạo ra ở đầu lớp thay vì trong phương thức "bắt đầu", đối tượng được giải phóng mỗi lần trong phương thức "dừng", làm cho nó vô dụng.

+0

Có, chúng tôi không được phép gọi 'mMediaRecorder.release();';) – Danpe

2

tôi đã cùng một lỗi, giải pháp mà làm việc cho tôi "Và MediaRecorder recorder = new MediaRecorder(); vào đầu start()" (Several audio recording in Android)

+0

Nếu điều đó khắc phục được sự cố, thì bạn có thể bị rò rỉ một số thành phần bên trong. Bạn có thể bắt đầu gặp sự cố sau một vài bản ghi nữa. – DariusL

0

tôi giải quyết vấn đề này bằng cách thêm các ghi trong chức năng dừng.

Bạn cần phải thêm mã 4 dòng này bên stop() sau đó chỉ có bạn mới có thể bắt đầu các clip âm thanh thứ hai:

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

Tham khảo bên dưới mã:

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(); 
    } 
} 
Các vấn đề liên quan