3

我正在尝试创建一个从前置摄像头录制视频的 Android 应用程序。预览工作正常,但一旦我开始录制应用程序崩溃并出现错误“java.lang.RuntimeException:启动失败”。我用后置摄像头尝试了同样的方法,但它有同样的问题。我正在使用运行 Android ICS 4.0.3 的三星 Tab 2 P5110。

这是我的 Activity 类,它显示预览并且应该开始录制。

    import java.io.IOException;
    import java.lang.reflect.Method;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Field;

    import android.app.Activity;
    import android.content.Intent;
    import android.hardware.Camera;
    import android.media.CamcorderProfile;
    import android.media.MediaRecorder;
    import android.os.Bundle;
    import android.os.CountDownTimer;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.view.Window;
    import android.view.WindowManager;
    import android.view.View.OnClickListener;
    import android.widget.ProgressBar;
    import android.widget.TextView;
    import android.widget.FrameLayout;

    public class VideoActivity extends Activity implements OnClickListener,
    SurfaceHolder.Callback, MediaRecorder.OnInfoListener {

      MediaRecorder recorder;
      SurfaceHolder holder;
      Camera camera;

      boolean recording = false;
      public static final String TAG = "VIDEOCAPTURE";
      private int show_id;
      private CamcorderProfile mProfile;
      private CountDownTimer cdt = null;

      private static final int max_length_in_ms = 30000;


      @Override 
      public void onCreate(Bundle savedInstanceState) 
      {
          super.onCreate(savedInstanceState);

          requestWindowFeature( Window.FEATURE_NO_TITLE );
          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN );

          show_id = getIntent().getIntExtra(Database.SHOW_ID, -1);

          camera = this.openFrontFacingCamera(); // frontfacing camera

                  camera = camera.open(); //rearfacing

          recorder = new MediaRecorder();
          recorder.setCamera(camera);


          setContentView(R.layout.video);

          FrameLayout cameraView = (FrameLayout) findViewById(R.id.CameraView);

          CameraSurfaceView cameraSurface = new CameraSurfaceView(getBaseContext(), camera);
          cameraView.addView(cameraSurface);

          holder = cameraSurface.getHolder();

          cameraView.setClickable(true);
          findViewById(R.id.recBtn).setOnClickListener(this);
      }

      private void initRecorder() {
          recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
          recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

          recorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));


          recorder.setOutputFile("/sdcard/videotemp.mp4");
          recorder.setMaxDuration(VideoActivity.max_length_in_ms); 
          recorder.setMaxFileSize(50000000); // Approximately 50 megabytes
      }

      private void prepareRecorder() {
          recorder.setPreviewDisplay(holder.getSurface());

          try {
              recorder.prepare();
          } catch (IllegalStateException e) {
              e.printStackTrace();
              finish();
          } catch (IOException e) {
              e.printStackTrace();
              finish();
          }
      }

      public void onClick(View v) {
          if (recording) {
              recorder.stop(); 
              recorder.release();
              recording = false;
              camera.release();
              Log.v(TAG, "Recording Stopped");
              // Let's initRecorder so we can record again
              Intent intent = new Intent(this, UploadActivity.class);
              intent.putExtra(Database.SHOW_ID, show_id);
              intent.putExtra(Database.FILENAME, "/sdcard/videotemp.mp4");
              intent.putExtra(Database.EXTENTION, ".mp4");
              startActivity(intent);
              finish();
          } else {
              recording = true;

              initRecorder();

              prepareRecorder();

              recorder.start(); 

              ProgressBar pb = (ProgressBar) findViewById(R.id.videoProgress);
              pb.setMax(VideoActivity.max_length_in_ms);

              this.cdt = new CountDownTimer(VideoActivity.max_length_in_ms, 50) {

                   public void onTick(long millisUntilFinished) {  
                       ProgressBar pb = (ProgressBar) findViewById(R.id.videoProgress);

                       pb.setProgress( VideoActivity.max_length_in_ms - (int)((millisUntilFinished) )); 
                   }

                   public void onFinish() {
                       ProgressBar pb = (ProgressBar) findViewById(R.id.videoProgress);
                       pb.setProgress(100);
                   }
                };
                this.cdt.start();

              Log.v(TAG, "Recording Started");
          }
      }

      private Camera openFrontFacingCamera() {
            Camera camera = null;

            // Look for front-facing camera, using the Gingerbread API.
            // Java reflection is used for backwards compatibility with
            // pre-Gingerbread APIs.
            try {
                Class<?> cameraClass = Class.forName("android.hardware.Camera");
                Object cameraInfo = null;
                Field field = null;
                int cameraCount = 0;
                Method getNumberOfCamerasMethod = cameraClass
                        .getMethod("getNumberOfCameras");
                if (getNumberOfCamerasMethod != null) {
                    cameraCount = (Integer) getNumberOfCamerasMethod.invoke(null,
                            (Object[]) null);
                }
                Class<?> cameraInfoClass = Class
                        .forName("android.hardware.Camera$CameraInfo");
                if (cameraInfoClass != null) {
                    cameraInfo = cameraInfoClass.newInstance();
                }
                if (cameraInfo != null) {
                    field = cameraInfo.getClass().getField("facing");
                }
                Method getCameraInfoMethod = cameraClass.getMethod("getCameraInfo",
                        Integer.TYPE, cameraInfoClass);
                if (getCameraInfoMethod != null && cameraInfoClass != null
                        && field != null) {
                    for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
                        getCameraInfoMethod.invoke(null, camIdx, cameraInfo);
                        int facing = field.getInt(cameraInfo);
                        if (facing == 1) { // Camera.CameraInfo.CAMERA_FACING_FRONT
                            try {
                                Method cameraOpenMethod = cameraClass.getMethod(
                                        "open", Integer.TYPE);
                                if (cameraOpenMethod != null) {
                                    camera = (Camera) cameraOpenMethod.invoke(null,
                                            camIdx);
                                    mProfile = CamcorderProfile
                                            .get(camIdx, CamcorderProfile.QUALITY_LOW);
                                }
                            } catch (RuntimeException e) {
                                Log.e(TAG,
                                        "Camera failed to open: "
                                                + e.getLocalizedMessage());
                            }
                        }
                    }
                }
            }
            // Ignore the bevy of checked exceptions the Java Reflection API throws
            // - if it fails, who cares.
            catch (ClassNotFoundException e) {
                Log.e(TAG, "ClassNotFoundException" + e.getLocalizedMessage());
            } catch (NoSuchMethodException e) {
                Log.e(TAG, "NoSuchMethodException" + e.getLocalizedMessage());
            } catch (NoSuchFieldException e) {
                Log.e(TAG, "NoSuchFieldException" + e.getLocalizedMessage());
            } catch (IllegalAccessException e) {
                Log.e(TAG, "IllegalAccessException" + e.getLocalizedMessage());
            } catch (InstantiationException e) {
                Log.e(TAG, "InstantiationException" + e.getLocalizedMessage());
            } catch (SecurityException e) {
                Log.e(TAG, "SecurityException" + e.getLocalizedMessage());
            } catch (IllegalArgumentException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (InvocationTargetException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }

            if (camera == null) {
                // Try using the pre-Gingerbread APIs to open the camera.
                try {
                    camera = Camera.open();
                } catch (RuntimeException e) {
                    Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage());
                }
            }

            return camera;
        }

    }

对于预览,我正在使用 SurfaceView 的扩展版本

 package nl.raakict.android.VideoCapture;
    import java.io.IOException;

    import android.content.Context;
    import android.hardware.Camera;
    import android.util.Log;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;

    public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder mHolder;
        private Camera mCamera;

        public CameraSurfaceView(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 {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d("DEBUG", "Error setting camera preview: " + e.getMessage());
            }


        }

        public void surfaceDestroyed(SurfaceHolder holder) {

        }

        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("DEBUG", "Error starting camera preview: " + e.getMessage());
            }
        }
    }

任何帮助将不胜感激。

4

0 回答 0