Recording video

NOTE : Video recording quality is bad at 1028x720. Refer this code for good quality

1) Set up storage location. Make sure the file names dont clash

// set up storage location
    private File mVideoFolder;
    private File mVideoFile;
    private String mVideofileName;

    // to be called under onCreate
    private void createVideoFolder(){
        // get the storage dir for movies
        File moviewFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
        // create a new directory for your app under this directory
        mVideoFolder = new File(moviewFile, "camera2videoImage");
        if(!mVideoFolder.exists())
            mVideoFolder.mkdirs();

    }

    // to be called when recording has been started
    private void createVideoFileName(){
        //create unique name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String prepend = "VIDEO_" + timeStamp + "_";

        File videoFile = null;
        try {
            videoFile = File.createTempFile(prepend, ".mp4", mVideoFolder);
        } catch (IOException e) {
            e.printStackTrace();
        }
        mVideofileName = videoFile.getAbsolutePath();
        mVideoFile = videoFile;
    }

2) Set up media recorder. First get the video size for media recorder in setUpCamera

In setUpCamera

mTotalRotation = calcSize.totalRotation;
    mVideoSize = calcSize.chooseOptimalSize(map.getOutputSizes(MediaRecorder.class));

MediaRecorder setup

private MediaRecorder mMediaRecorder;

    // to be called when recording have to be saved
    private void setUpMediaRecorder(){
        // the order is important
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setOutputFile(mVideofileName);
        mMediaRecorder.setVideoEncodingBitRate(1000000);
        mMediaRecorder.setVideoFrameRate(24);
        mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
        //mMediaRecorder.setVideoSize(640, 480);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mMediaRecorder.setOrientationHint(mTotalRotation);
        try {
            mMediaRecorder.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

3) Create Capture Request for recording. (This should replace the CaptureRequestBuilder from preview)

private void startRecord(){

        if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            Toast.makeText(this,"No permission to access storage", Toast.LENGTH_SHORT).show();
            return;
        }

        createVideoFileName();

        setUpMediaRecorder();
        // record surface
        Surface recordSurface = mMediaRecorder.getSurface();
        //surface to preview recording
        SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
        surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
        Surface previewSurface =  new Surface(surfaceTexture);

        try {
            mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            mCaptureRequestBuilder.addTarget(previewSurface);
            mCaptureRequestBuilder.addTarget(recordSurface);

            mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, recordSurface),
                    new CameraCaptureSession.StateCallback() {
                        @Override
                        public void onConfigured(CameraCaptureSession session) {
                            try {
                                session.setRepeatingRequest(mCaptureRequestBuilder.build(),null,mBAckgroundHandler);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }

                            MainActivity.this.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mMediaRecorder.start();
                                }
                            });
                        }

                        @Override
                        public void onConfigureFailed(CameraCaptureSession session) {

                        }
                    }, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

4) When recoding is stopped, reset MediaRecorder and start the preview

private void stopRecord(){
        if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
            mMediaRecorder.stop();
            mMediaRecorder.reset();
            // open an alert dialog. delete file if save is not intended
            saveVideo();
            //revert back to preview mode
            startPreview();
        }
    }

5) Recording request should be started when record button is clicked.

Under onCreate

mRecordButton = (ImageButton) findViewById(R.id.imageButton2);
        mRecordButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mIsRecording){
                    mIsRecording = false;
                    mRecordButton.setImageResource(android.R.drawable.presence_video_online);
                    stopRecord();
                }else{
                    mIsRecording = true;
                    mRecordButton.setImageResource(android.R.drawable.presence_video_busy);
                    startRecord();
                }
            }
        });