Android Basic Training Course: Video Recording

    In previous chapter, I have guided about working with Camera and Gallery in Android. There is a popular another case is recording video by device camera. So, in this example, we are going to see the use of Android Video API in a more detailed way, and develop a simple application that captures video, switches between the front and the back camera of our mobile device and saving the video file to SD card.

Request Camera and start Video Recorder Intent

    In order to use device camera and writing the video file to sd card, you must provide these permissions in AndroidManifest.xml:
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    With this declaration, your application can be installed only in devices which has a camera! Request code for starting video recorder intent:
// create new Intentwith with Standard Intent action that can be
// sent to have the camera application capture an video and return it.
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

// create a file to save the video
fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);

// set the image file name
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

// set the video image quality to high
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);

// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
    Like taking photo from camera, you must override onActivityResult() method of Activity class to get data from a sub-Activity:
    @SuppressLint("SetTextI18n")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                noticeText.setText("Video file has been saved!");
            } else if (resultCode == RESULT_CANCELED) {
                noticeText.setText("User cancelled the video capture.");
            } else {
                noticeText.setText("Video capture failed.");
            }
        }
    }
    And providing a function which saving data (video file) to a folder in SD Card:
    @SuppressLint({"SetTextI18n", "SimpleDateFormat"})
    private File getOutputMediaFile(int type) {

        // Check that the SDCard is mounted
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DevExVideo");

        // Create the storage directory("DevExVideo") if it does not exist
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                noticeText.setText("Failed to create directory DevExVideo");
                return null;
            }
        }

        // Create a media file name
        // For unique file name appending current timeStamp with file name
        java.util.Date date = new java.util.Date();
        timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date.getTime());

        File mediaFile;
        if (type == MEDIA_TYPE_VIDEO) {
            // For unique video file name appending current timeStamp with file name
            mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");

        } else return null;

        return mediaFile;
    }

Full project code

    This is our main activity, which running after application launched:
MainActivity.java
package info.devexchanges.recordingvideo;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;
import java.text.SimpleDateFormat;

public class MainActivity extends AppCompatActivity {

    private Uri fileUri;
    private String timeStamp;
    public static final int MEDIA_TYPE_VIDEO = 2;
    private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;

    public TextView noticeText;
    private Button buttonRecording;

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

        buttonRecording = (Button) findViewById(R.id.btn_record);
        noticeText = (TextView) findViewById(R.id.text_view);

        buttonRecording.setOnClickListener(new Button.OnClickListener() {

            @Override
            public void onClick(View arg0) {

                // create new Intentwith with Standard Intent action that can be
                // sent to have the camera application capture an video and return it.
                Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

                // create a file to save the video
                fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);

                // set the image file name
                intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

                // set the video image quality to high
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);

                // start the Video Capture Intent
                startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
            }
        });
    }

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

    /**
     * Create a File for saving an image or video
     */
    @SuppressLint({"SetTextI18n", "SimpleDateFormat"})
    private File getOutputMediaFile(int type) {

        // Check that the SDCard is mounted
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DevExVideo");

        // Create the storage directory("DevExVideo") if it does not exist
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                noticeText.setText("Failed to create directory DevExVideo");
                return null;
            }
        }

        // Create a media file name
        // For unique file name appending current timeStamp with file name
        java.util.Date date = new java.util.Date();
        timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date.getTime());

        File mediaFile;
        if (type == MEDIA_TYPE_VIDEO) {
            // For unique video file name appending current timeStamp with file name
            mediaFile = new File(mediaStorageDir.getPath() + File.separator + "VID_" + timeStamp + ".mp4");

        } else return null;

        return mediaFile;
    }


    @SuppressLint("SetTextI18n")
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                noticeText.setText("Video file has been saved!");
            } else if (resultCode == RESULT_CANCELED) {
                noticeText.setText("User cancelled the video capture.");
            } else {
                noticeText.setText("Video capture failed.");
            }
        }
    }

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

        savedInstanceState.putString("text", noticeText.getText().toString());
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        if (savedInstanceState != null) {
            noticeText.setText(savedInstanceState.getString("text"));
        }
    }
}
    And it's layout:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="@dimen/activity_horizontal_margin">

    <Button
        android:id="@+id/btn_record"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Capture Video" />

    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

Output - running application

    After launching, you will see this output:
    Click at the button, the Video view will start:
    Click the record button, you 'll start video recording process. Moreover, if your device has 2 cameras (font and back), the "switch camera button" will appear like above.
    In recording process, Pause and Stop button will be displayed:
    Click stop button to finish recording, you will be redirect back to main screen:
    Your file stored at /Pictures/DevExVideo folder:

Conclusions

    As you can see, recording video in Android is very easy. From this basic step, now you can custom it to apply for your real application. Hope this is helpful with the beginners. Finally, you can view my project on @Github.

Share


Previous post
« Prev Post
Next post
Next Post »