android 录像 - RuntimeException : stop failed

标签 android android-camera

我在 google play 中发布了我的应用。

此 Activity 通过前置摄像头录制视频,如果不可用,则使用后置摄像头

在崩溃部分我收到了这个输出:

java.lang.RuntimeException: stop failed.
at android.media.MediaRecorder.stop(Native Method)
at com.example.uploadvideo.MainActivity.onStopped(MainActivity.java:192)
at com.google.android.youtube.player.internal.s$4.c(Unknown Source)
at com.google.android.youtube.player.internal.f$a.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:326)
at com.google.android.youtube.player.internal.n.c(SourceFile:144)
at com.google.android.youtube.api.jar.client.e.run(SourceFile:797)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
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:1027)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:794)
at dalvik.system.NativeStart.main(Native Method)

我不知道这是什么原因,也没有任何搜索帮助...

但我相信这个是通过 surfaceCreated 方法实现的

我认为这部分的原因:

/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private String TAG = "CameraPreview";
    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.


        Log.d(TAG, "surfaceCreated camera id" + mCamera);

        try {
            CamcorderProfile profile ;

            int numCameras = Camera.getNumberOfCameras();
            if (numCameras > 1) {
            profile = (CamcorderProfile
                        .get(Camera.CameraInfo.CAMERA_FACING_FRONT,CamcorderProfile.QUALITY_HIGH));
            }
            else{

                profile = (CamcorderProfile
                        .get(Camera.CameraInfo.CAMERA_FACING_BACK,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(TAG, "Error setting camera preview: " + e.getMessage());
        }}



    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.





    }

    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.



         Log.d(TAG, "surfaceChanged to " + "," + w + "," +  h);

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



}











private boolean prepareVideoRecorder() {

    mMediaRecorder = new MediaRecorder();

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

mMediaRecorder.setCamera(mCamera);

// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)


int numCameras = Camera.getNumberOfCameras();
if (numCameras > 1) {
    mMediaRecorder.setProfile(CamcorderProfile
            .get(Camera.CameraInfo.CAMERA_FACING_FRONT,CamcorderProfile.QUALITY_HIGH));
}
else{

    mMediaRecorder.setProfile(CamcorderProfile
            .get(Camera.CameraInfo.CAMERA_FACING_BACK,CamcorderProfile.QUALITY_HIGH));
}







// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO)
        .toString());
outputFileName = getOutputMediaFile(MEDIA_TYPE_VIDEO).toString();
Log.d(TAG,"idan outputFileName" + outputFileName);


// Step 5: Set the preview output
// mMediaRecorder.setVideoSize(640, 480); //try


mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());

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

/** Create a file Uri for saving an image or video */
private  Uri getOutputMediaFileUri(int type) {
    return Uri.fromFile(getOutputMediaFile(type));
}

最佳答案

你可以使用这个代码来记录你的视频请检查

public class VideoCaptureActivity extends Activity {
    private static final String TAG = "VideoCaptureActivity";
///////////////--------------------------


    CountDownTimer ctimer;

    //private static final int H264 = 0;
    TextView timerText;

    Camera camera;

    ImageButton recordButton;

    ImageButton stopButton;

    FrameLayout cameraPreviewFrame;

    CameraPreview cameraPreview; 


    MediaRecorder mediaRecorder;

    File file;

    public String holdVideoName = new String();
////////////////----------------------------


    private String vpath;


    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        super.setContentView(R.layout.video_capture);





        this.cameraPreviewFrame = (FrameLayout)super.findViewById(R.id.camera_preview);
        this.recordButton = (ImageButton)super.findViewById(R.id.recordButton);
        this.stopButton = (ImageButton)super.findViewById(R.id.stopButton);
        this.timerText=(TextView)super.findViewById(R.id.textViewtimer);
        this.toggleButtons(false);

        //------------- we'll enable this button once the camera is ready

        this.recordButton.setEnabled(false);
    }



   @Override
    protected void onResume() {
        super.onResume();

        // initialize the camera in background, as this may take a while
        new AsyncTask<Void, Void, Camera>() {

            @Override
            protected Camera doInBackground(Void... params) {
                 Camera camera=null;
                try {
                    int numCameras = Camera.getNumberOfCameras();
                    System.out.println("number of cameara is"+numCameras );
                   if (numCameras ==1) {
                          System.out.println("camera 1");
                          camera = Camera.open(CameraInfo.CAMERA_FACING_BACK);
                    }
                    else{
                        camera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
                    }


                    return camera == null ? Camera.open() : camera;

                } catch (RuntimeException e) {

                    return null;
                }
            }

            @Override
            protected void onPostExecute(Camera camera) {
                if (camera == null) {

                    Toast.makeText(VideoCaptureActivity.this, R.string.cannot_record,
                            Toast.LENGTH_SHORT);
                } else {
                    VideoCaptureActivity.this.initCamera(camera);
                }
            }

        }.execute();
    }

    void initCamera(Camera camera) {
        // we now have the camera
        this.camera = camera;
        // create a preview for our camera
        this.cameraPreview = new CameraPreview(VideoCaptureActivity.this, this.camera);
        // add the preview to our preview frame
        this.cameraPreviewFrame.addView(this.cameraPreview, 0);
        // enable just the record button
        this.recordButton.setEnabled(true);
    }

    void releaseCamera() {
        if (this.camera != null) {
            this.camera.lock(); // unnecessary in API >= 14
            this.camera.stopPreview();
            this.camera.release();
            this.camera = null;
            this.cameraPreviewFrame.removeView(this.cameraPreview);
        }
    }

    void releaseMediaRecorder() {
        if (this.mediaRecorder != null) {
            this.mediaRecorder.reset(); // clear configuration (optional here)
            this.mediaRecorder.release();
            this.mediaRecorder = null;
        }
    }

    void releaseResources() {
        this.releaseMediaRecorder();
        this.releaseCamera();
    }

    @Override
    public void onPause() {
        super.onPause();
        this.releaseResources();
    }

    // gets called by the button press
    public void startRecording(View v) {
        Log.d(TAG, "startRecording()");
        // we need to unlock the camera so that mediaRecorder can use it
        this.camera.unlock(); // unnecessary in API >= 14
        // now we can initialize the media recorder and set it up with our
        // camera
        ctimer =  new CountDownTimer(10000, 1000) {

            @Override
            public void onTick(long millisUntilFinished) {
                // TODO Auto-generated method stub
                timerText.setText("seconds remaining \n 00: " + millisUntilFinished / 1000);
            }

            @Override
            public void onFinish() {
                // TODO Auto-generated method stub
                timerText.setText("done!");
                stopRecordingg();
            }
        };

        ctimer.start();


        this.mediaRecorder = new MediaRecorder();
        this.mediaRecorder.setCamera(this.camera);

        this.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        this.mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        this.mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
      //  this.mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));

        this.mediaRecorder.setMaxDuration(10000);


        this.mediaRecorder.setOutputFile(this.initFile().getAbsolutePath());
        this.mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        this.mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
       this.mediaRecorder.setVideoSize(640,480); 
       // this.mediaRecorder.setVideoFrameRate(12); 


       // this.mediaRecorder.setOnInfoListener(null);
       // this.mediaRecorder.setOutputFile("/sdcard/videocapture_example.mp4");


        try {
            this.mediaRecorder.setPreviewDisplay(this.cameraPreview.getHolder().getSurface());
            this.mediaRecorder.prepare();




            // start the actual recording
            // throws IllegalStateException if not prepared
            this.mediaRecorder.start();
            Toast.makeText(this, R.string.recording, Toast.LENGTH_SHORT).show();
            // enable the stop button by indicating that we are recording
            this.toggleButtons(true);
        }  catch (Exception e) {
            Log.wtf(TAG, "Failed to prepare MediaRecorder", e);
            Toast.makeText(this,"record nathi thatu...", Toast.LENGTH_SHORT).show();
            this.releaseMediaRecorder();
        }
    }

    protected void stopRecordingg() {
        // TODO Auto-generated method stub

        Log.d(TAG, "stopRecording()");
        assert this.mediaRecorder != null;
        try {
          //  this.mediaRecorder.stop();
            Toast.makeText(this, R.string.saved, Toast.LENGTH_SHORT).show();
            // we are no longer recording
            this.toggleButtons(false);
        } catch (RuntimeException e) {
            // the recording did not succeed
            Log.w(TAG, "Failed to record", e);
            if (this.file != null && this.file.exists() && this.file.delete()) {
                Log.d(TAG, "Deleted " + this.file.getAbsolutePath());
            }
            return;
        } finally {
            this.releaseMediaRecorder();
        }
        if (this.file == null || !this.file.exists()) {
            Log.w(TAG, "File does not exist after stop: " + this.file.getAbsolutePath());
        } else {
            Log.d(TAG, "Going to display the video: " + this.file.getAbsolutePath());
            Intent intent = new Intent(this, VideoPlayBack.class);
            intent.setData(Uri.fromFile(file));

            intent.putExtra("hold",getIntent().getExtras().getString("hold"));
            intent.putExtra("cwi",getIntent().getExtras().getString("cwi"));
         //   intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
            this.finish();
        }

    }

    // gets called by the button press
    public void stopRecording(View v) {
        Log.d(TAG, "stopRecording()");

        ctimer.cancel();

        assert this.mediaRecorder != null;
        try {
            this.mediaRecorder.stop();
            Toast.makeText(this, R.string.saved, Toast.LENGTH_SHORT).show();
            // we are no longer recording
            this.toggleButtons(false);
        } catch (RuntimeException e) {
            // the recording did not succeed
            Log.w(TAG, "Failed to record", e);
            if (this.file != null && this.file.exists() && this.file.delete()) {
                Log.d(TAG, "Deleted " + this.file.getAbsolutePath());
            }
            return;
        } finally {
            this.releaseMediaRecorder();
        }
        if (this.file == null || !this.file.exists()) {
            Log.w(TAG, "File does not exist after stop: " + this.file.getAbsolutePath());
        } else {
            Log.d(TAG, "Going to display the video: " + this.file.getAbsolutePath());
            Intent intent = new Intent(this, VideoPlayBack.class);
            intent.setData(Uri.fromFile(file));

            this.finish();
            super.startActivity(intent);
        }
    }

    private File initFile() {
    //  holdVideoName= getIntent().getExtras().getString("vpath","");
        //System.out.println("vpath is:"+vpath);

        //  File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES), "namefolder"); 

          File dir = new File("/sdcard/test/");

        if (!dir.exists() && !dir.mkdirs()) {
            Log.wtf(TAG, "Failed to create storage directory: " + dir.getAbsolutePath());

            this.file = null;
        } else {
          this.file = new File("/sdcard/test/"+getIntent().getExtras().getString("hold")+".mp4");
        }
        return this.file;
    }
}

关于android 录像 - RuntimeException : stop failed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16917916/

相关文章:

android - 动态数组输入

android - 在Android Studio中生成签名的apk后无法安装apk

android - 如何用阿尔法绘画?

java - 错误没有与给定名称匹配的资源(位于 "label",值为 "@string/about_title"

java - 相机只能开一次?

Android 相机图像未上传到服务器。使用多部分数据 Http post

android - 客户端(手机)如何拦截和修改http响应

java - 如何设置 cwac-camera preview 以使用 scaleType centerCrop?

android - Android 中某些相机分辨率的不同捕获输出大小

android - Camera.takePicture 返回一个旋转的 byteArray