【问题标题】:java.lang.RuntimeException: stop failed at android.media.MediaRecorder.stop(MediaRecorder.java)java.lang.RuntimeException:在 android.media.MediaRecorder.stop(MediaRecorder.java) 处停止失败
【发布时间】:2015-10-19 08:03:19
【问题描述】:

我在我的应用程序中集成了相机。当用户单击捕获按钮时,我正在隐藏工具栏,以便相机预览屏幕尺寸增加。这会使应用程序在停止在线录制时崩溃 - mMediaRecorder.stop();

java.lang.RuntimeException: stop failed.
       at android.media.MediaRecorder.stop(MediaRecorder.java)

但是,如果我不隐藏工具栏或从不显示工具栏,则不会发生崩溃。所以问题是因为在我隐藏工具栏后相机参数发生了变化。我该如何解决这个问题?我见过this回答并将代码添加到CameraPreview 类。

private Camera mCamera;
private CameraPreview mPreview;
mCamera = getCameraInstance();
mCamera.setDisplayOrientation(90);
mPreview = new CameraPreview(mActivity, mCamera);
preview = (FrameLayout) view.findViewById(R.id.camera_preview);
preview.addView(mPreview);
capture.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
mToolbar.setVisibility(View.GONE);
if (prepareVideoRecorder()) {
    // Camera is available and unlocked, MediaRecorder is prepared,
    // now you can start recording
    mMediaRecorder.start();
}
}
}):

stop.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
mMediaRecorder.stop();  // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); 
}
}):

CameraPreview.class

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;
    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
//            if(mCamera==null)
//            mCamera = getCameraInstance();
            CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewSize(profile.videoFrameWidth,profile.videoFrameHeight);
            mCamera.setParameters(parameters);
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d("error", "Error setting camera preview: " + e.getMessage());
        }
    }
    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
        Log.e("surfaceDestroyed issue","surfaceDestroyed called");
        if ((mCamera != null)&&(!CameraActivity.getInstance().getOnBackPressedListener().isPreview())) {
            Log.e("surfaceDestroyed issue","surface destroyed");
            try {
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
            }catch(Exception e){}
        }
    }
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.
        if (mHolder.getSurface() == null){
            // preview surface does not exist
            return;
        }
        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
            // ignore: tried to stop a non-existent preview
        }
        // set preview size and make any resize, rotate or
        // reformatting changes here
        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (Exception e){
            Log.d("error", "Error starting camera preview: " + e.getMessage());
        }
    }
    public static Camera getCameraInstance() {
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        } catch (Exception e) {
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

错误-

java.lang.RuntimeException: stop failed.
       at android.media.MediaRecorder.stop(MediaRecorder.java)
       at xyzCameraFragment$5.onClick(CameraFragment.java:208)
       at android.view.View.performClick(View.java:4761)
       at android.view.View$PerformClick.run(View.java:19767)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5312)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

【问题讨论】:

  • 发布你的堆栈跟踪!!
  • @JiTHiN 发布日志错误
  • 我认为问题是因为我需要在隐藏工具栏后更新相机参数?但我应该怎么做?
  • 能否检查一下隐藏工具栏时是否调用了surfaceChanged
  • @JiTHiN 是的,它叫

标签: android android-camera runtimeexception android-mediarecorder


【解决方案1】:

在你捕获点击设置一个boolean变量

capture.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
         mToolbar.setVisibility(View.GONE);
         startCapture = true;

}):

隐藏ToolBar 会导致surfaceChanged 被调用。

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.
        if (mHolder.getSurface() == null){
            // preview surface does not exist
            return;
        }
        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
            // ignore: tried to stop a non-existent preview
        }
        // set preview size and make any resize, rotate or
        // reformatting changes here
        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (Exception e){
            Log.d("error", "Error starting camera preview: " + e.getMessage());
        }
 //Check if capture is set and start recording

 if(startCapture)
  {
   if (prepareVideoRecorder()) {
    mMediaRecorder.start();
   }
   startCapture = false;
  }
 }

【讨论】:

  • 如果我注释掉surfaceChanged 的整个代码,那么它的工作原理......这是解决这个问题的更好方法吗?
  • 我不这么认为。当表面发生变化时,您需要重新启动相机预览。
  • 您可以做的另一件事是将工具栏作为覆盖物放在相机预览上。因此,当您隐藏工具栏时,表面不会改变
  • 我也可以这样做,如果 startcapture 为真,则不应调用 surfaceChanged 中的内容..
  • 很高兴你能帮我解决这个问题。stackoverflow.com/questions/33199834/…
猜你喜欢
  • 2016-11-23
  • 2014-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-29
  • 2013-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多