为什么在设置MediaRecorder时会显示IllegalStateException错误?

8

我的代码设置了MediaRecorder,但在设置音质时出错。

mMediaRecorder = new MediaRecorder();

   // Step 1: Unlock and set camera to MediaRecorder
   mCamera.stopPreview();
   mCamera.unlock();
  mMediaRecorder.setCamera(mCamera);

  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setProfile(CamcorderProfile .get(CamcorderProfile.QUALITY_HIGH));
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);

    // Step 4: Set output file
    mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());

    // Step 5: Set the preview output
    mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

    // Step 6: Prepare configured MediaRecorder
   try {
    mMediaRecorder.prepare();
        Log.d("DEBUG", "IllegalStateException preparing MediaRecorder: "
                        + e.getMessage());
                releaseMediaRecorder();
                return false;
   } catch (IOException e) {
                Log.d("DEBUG",
                        "IOException preparing MediaRecorder: " + e.getMessage());
                releaseMediaRecorder();
                return false;
   }

示例:

java.lang.IllegalStateException

堆栈跟踪:

java.lang.IllegalStateException
    at android.media.MediaRecorder.setOutputFormat(Native Method)
    at android.media.MediaRecorder.setProfile(MediaRecorder.java:366)
    at jp.osaka.E028.prepareVideoRecorder(E028.java:1441)
    at jp.osaka.E028.access$16(E028.java:1403)
    at jp.osaka.E028$6.onClick(E028.java:344)
    at android.view.View.performClick(View.java:3517)
    at android.view.View$PerformClick.run(View.java:14155)
    at android.os.Handler.handleCallback(Handler.java:605)
    at android.os.Handler.dispatchMessage(Handler.java:92)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:4503)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:511)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)
    at dalvik.system.NativeStart.main(Native Method)

为什么在设置MediaRecorder时会显示IllegalStateException错误?


请发布您的堆栈跟踪。 - ChuongPham
您需要将 e.getMessage() 改为 e.fillInStackTrace()。然后,在此处发布您的堆栈跟踪! - ChuongPham
我已经提供了下面的答案。 - ChuongPham
2个回答

21

实际上你调用了两次mMediaRecorder.setOutputFormat():一次是显式调用,另外一次在mMediaRecorder.setProfile()中再次调用,正如您在堆栈跟踪中所看到的。

Android媒体录制器在这方面的鲁棒性非常低。

因此,请删除这行代码:

mMediaRecorder.setOutputFormat();

错误应该会消失。顺便说一下,删除

mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);

mMediaRecorder.setProfile()已经完成了这个操作。


当使用mMediaRecorder.setProfile()时,我可以设置setVideoFrameRate吗? - mum
很可能是的。视频帧率是摄像机配置文件的一部分,因此您不需要设置它,但根据我的过去经验,大多数相机仅将帧率用作最大值,并且实际帧率是由相机自身根据实际条件设置的,例如可用光线。因此,对于记录器启动的成功来说,这个参数是相当不关键的。 - Nantoka
你真是个天才啊。即使阅读了所有 Google 的官方文档,仍然在思考。是的,recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)) 已经为您设置了音频编码器和视频编码器。 - Morgan Koh

7
您可能需要在MediaRecorder开始之前释放相机对象,例如:

使用以下方式释放:

private void releaseCamera() {
   if (myCamera != null) {
      // Release the camera object so other classes can use it.
      myCamera.release();
      myCamera = null;
   }
}

在开始使用MediaRecorder方法之前,请调用上述方法。 重要提示:此外,以下方法必须按照以下顺序调用:
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoSize(640,480);
mMediaRecorder.setVideoFrameRate(30);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

这里重要的是setVideoEncodersetAudioEncoder被最后调用。

啊,我明白了。你可能需要将mMediaRecorder的方法移动到try/catch中,并查看返回的错误(如果有)。你提到的这三种方法将取决于Android API以及您的设备是否支持这些方法中声明的模式。你可能最终需要包含另一个第三方库来实现你想要的功能,例如ffmpeg。 - ChuongPham
在文档中,它只需要设置一个CamcorderProfile(需要API Level 8或更高版本)。 - mum
你在 AndroidManifest.xml 文件中设置了这些权限吗:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.RECORD_AUDIO" /> - ChuongPham
应该没问题。我刚刚建立了一个快速而简单的项目,对我来说运行良好。你遇到了什么问题 - 请详细说明。 - ChuongPham
你能否更新你上面的帖子,包括你所做的最新代码更改,这样我就可以看到你做了什么。 - ChuongPham
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接