Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Record Video using surface view android

I have to create an android app in which i am trying to record video and capture image using surface view. Up to now i am able to capture video but facing problem in record video. My code for video recording is -

onCreate(){
      ..
     surfaceHolder = surfaceView.getHolder();
     surfaceHolder.addCallback(this);
     surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
     startRecording();
     .
     .
}


protected void startRecording() throws IOException
    {
        if(mCamera==null)
            mCamera = Camera.open();

         String filename;
         String path;

         path= Environment.getExternalStorageDirectory().getAbsolutePath().toString();

         Date date=new Date();
         filename="/rec"+date.toString().replace(" ", "_").replace(":", "_")+".mp4";

         File file=new File(path,filename);

        mrec = new MediaRecorder(); 

        mCamera.lock();
        mCamera.unlock();


        mrec.setCamera(mCamera);    
        mrec.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mrec.setAudioSource(MediaRecorder.AudioSource.MIC);     
        mrec.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mrec.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
        mrec.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        mrec.setPreviewDisplay(surfaceHolder.getSurface());
        mrec.setOutputFile(path+filename);
        mrec.setMaxDuration(10000); 
  }
       @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int                height) {      

        Camera.Parameters parameters = mCamera.getParameters();      
        parameters.setPreviewSize(width, height);     
        try {
            mCamera.setPreviewDisplay(surfaceHolder);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mCamera.setParameters(parameters);       
        mCamera.startPreview(); 

    }

but app force close when onSurfaceChange method code is called at line - mCamera.setPreviewDisplay(surfaceHolder); with exception java.lang.RuntimeException: setParameters failed

so how can i manage it so i can start video recording. Thanks in advance.

like image 417
Ravi Bhandari Avatar asked May 30 '14 06:05

Ravi Bhandari


People also ask

How do I record a video on my Android screen?

Open Play Store and install Record Video With Screen Off app. Tap on Allow to provide all the necessary permissions. Click on the record button to start recording video in the background while your screen is turned off. To turn off the recording, tap on the button again to stop it.

What is camera surface android?

Explanation: SurfaceView is a type of View which contains a SurfaceHolder. SurfaceHolder holds the surface on which we can display our media (generally frames). mCamera is a Camera object which will contains the camera instance.


1 Answers

Check this code, hopefully it works..

import java.io.IOException;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ToggleButton;

public class MediaRecorderRecipe extends Activity implements SurfaceHolder.Callback {
private final String VIDEO_PATH_NAME = "/mnt/sdcard/VGA_30fps_512vbrate.mp4";

private MediaRecorder mMediaRecorder;
private Camera mCamera;
private SurfaceView mSurfaceView;
private SurfaceHolder mHolder;
private View mToggleButton;
private boolean mInitSuccesful;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.media_recorder_recipe);

    // we shall take the video in landscape orientation
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
    mHolder = mSurfaceView.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    mToggleButton = (ToggleButton) findViewById(R.id.toggleRecordingButton);
    mToggleButton.setOnClickListener(new OnClickListener() {
        @Override
        // toggle video recording
        public void onClick(View v) {
            if (((ToggleButton)v).isChecked()) {
                mMediaRecorder.start();
                try {
                    Thread.sleep(10 * 1000); // This will recode for 10 seconds, if you don't want then just remove it.
                } catch (Exception e) {
                    e.printStackTrace();
                }
                finish();
            }
            else {
                mMediaRecorder.stop();
                mMediaRecorder.reset();
                try {
                    initRecorder(mHolder.getSurface());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    });     
}

/* Init the MediaRecorder, the order the methods are called is vital to
 * its correct functioning */
private void initRecorder(Surface surface) throws IOException {
    // It is very important to unlock the camera before doing setCamera
    // or it will results in a black preview
    if(mCamera == null) {
        mCamera = Camera.open();
        mCamera.unlock();
    }

    if(mMediaRecorder == null)  mMediaRecorder = new MediaRecorder();
    mMediaRecorder.setPreviewDisplay(surface);
    mMediaRecorder.setCamera(mCamera);

    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
   //       mMediaRecorder.setOutputFormat(8);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
    mMediaRecorder.setVideoFrameRate(30);
    mMediaRecorder.setVideoSize(640, 480);
    mMediaRecorder.setOutputFile(VIDEO_PATH_NAME);

    try {
        mMediaRecorder.prepare();
    } catch (IllegalStateException e) {
        // This is thrown if the previous calls are not called with the 
        // proper order
        e.printStackTrace();
    }

    mInitSuccesful = true;
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    try {
        if(!mInitSuccesful)
            initRecorder(mHolder.getSurface());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    shutdown();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}

private void shutdown() {
    // Release MediaRecorder and especially the Camera as it's a shared
    // object that can be used by other applications
    mMediaRecorder.reset();
    mMediaRecorder.release();
    mCamera.release();

    // once the objects have been released they can't be reused
    mMediaRecorder = null;
    mCamera = null;
}

Permissions

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera.autofocus" />

XML FILE

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ToggleButton
 android:id="@+id/toggleRecordingButton"
 android:layout_width="fill_parent"
 android:textOff="Start Recording" 
 android:textOn="Stop Recording"
 android:layout_height="wrap_content"
/>
<FrameLayout
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <SurfaceView android:id="@+id/surfaceView" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"></SurfaceView>

</FrameLayout>
</LinearLayout>

Create a File for saving an image or video

private static File getOutputMediaFile(int type){
    // To be safe, you should check that the SDCard is mounted
    // using Environment.getExternalStorageState() before doing this.

    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
              Environment.DIRECTORY_PICTURES), "MyCameraApp");
    // This location works best if you want the created images to be shared
    // between applications and persist after your app has been uninstalled.

    // Create the storage directory if it does not exist
    if (! mediaStorageDir.exists()){
        if (! mediaStorageDir.mkdirs()){
            Log.d("MyCameraApp", "failed to create directory");
            return null;
        }
    }

    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File mediaFile;
    if (type == MEDIA_TYPE_IMAGE){
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "IMG_"+ timeStamp + ".jpg");
    } else if(type == MEDIA_TYPE_VIDEO) {
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
        "VID_"+ timeStamp + ".mp4");
    } else {
        return null;
    }

    return mediaFile;
}
like image 100
Aniruddha Avatar answered Sep 20 '22 06:09

Aniruddha