Video Recording Concept Without Preview In Android Phones

Posted By : Arun Kumar | 29-Apr-2020

In this blog post, you'll learn about video recording concept without preview in Android phones. By using the service in the foreground recording with camera but camera preview has not shown to user. This functionality can be implemented in case of online test.

 

In android when we implement the concept of video recording then it is required to open the camera of an android device for the video recording. But in this, We'll learn how to record video with preview the camera to the user (It is necessary to tell the user initially about the hidden video recording for the privacy policy purposes). We can use this concept in the case of an online test application and also a kind of survey application.

 

The following are required to record video by hiding camera preview;

 

1) Service Class: Create a service class extends with JobService class and make the media and Surface holder instance in it by copy the following code of service class,

           public class VideoJobService extends JobService {
    private static final String TAG = VideoJobService.class.getSimpleName();
    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;
    private static Camera mServiceCamera;
    private boolean mRecordingStatus;
    private MediaRecorder mMediaRecorder;

    String videoSavePathInDevice = null;
    private static final String VIDEO_RECORDER_FILE_EXT_MP4 = ".mp4";
    private static final String VIDEO_RECORDER_FOLDER = "AudioRecorder";
    private int currentFormat = 0;
    private String file_exts[] = { VIDEO_RECORDER_FILE_EXT_MP4};

    @Override
    public void onCreate() {
        mRecordingStatus = false;
        mServiceCamera = MainActivity.mCamera;
        mSurfaceView = MainActivity.mSurfaceView;
        mSurfaceHolder = MainActivity.mSurfaceHolder;

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("ddMMyyyyhhmm");
        final String format = simpleDateFormat.format(new Date());
        Log.e(TAG,"ts_: "+format);
//        videoSavePathInDevice = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + format + "videoRecording.mp4";
        videoSavePathInDevice = getFilename();
        super.onCreate();
    }


    @Override
    public int onStartCommand(Intent intent1, int flags1, int startId1) {
        super.onStartCommand(intent1, flags1, startId1);

        if (!mRecordingStatus)
            startRecording();

        return START_STICKY;
    }

   

    @Override
    public boolean onStartJob(JobParameters params) {
        Log.e(TAG, "Job started");
     //   doBackgroundWork(params);
        startRecording();
        return true;
    }

    @Override
    public void onDestroy() {
        stopRecording();
        mRecordingStatus = false;

        super.onDestroy();
    }

    public void startRecording(){
        try {
            Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();

//            mServiceCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            mServiceCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
            //mServiceCamera = camera;
            Camera.Parameters params = mServiceCamera.getParameters();
            mServiceCamera.setParameters(params);
            Camera.Parameters p = mServiceCamera.getParameters();

            final List listPreviewSize = p.getSupportedPreviewSizes();
           

            Camera.Size previewSize = listPreviewSize.get(0);
            p.setPreviewSize(previewSize.width, previewSize.height);
            mServiceCamera.setParameters(p);

            try {
                mServiceCamera.setPreviewDisplay(mSurfaceHolder);
                mServiceCamera.startPreview();
            }
            catch (IOException e) {
                Log.e(TAG, Objects.requireNonNull(e.getMessage()));
                e.printStackTrace();
            }

            mServiceCamera.unlock();

            mMediaRecorder = new MediaRecorder();
            mMediaRecorder.setCamera(mServiceCamera);
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            mMediaRecorder.setOutputFile(videoSavePathInDevice);
//            mMediaRecorder.setOutputFile(Environment.getExternalStorageDirectory().getPath() + "/"+format+".mp4");
//            mMediaRecorder.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+"recordVideo"+"/"+format+".mp4");
            mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

            mMediaRecorder.prepare();
            mMediaRecorder.start();

            mRecordingStatus = true;

        } catch (IllegalStateException e) {

            e.printStackTrace();

        } catch (IOException e) {
            Log.d(TAG, e.getMessage());
            e.printStackTrace();
        }
    }

    public void stopRecording() {
        if (null !=mMediaRecorder) {
            Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
            try {
                mServiceCamera.reconnect();

            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                mMediaRecorder.stop();
            } catch (RuntimeException stopException) {
                // handle cleanup here
            }
            mMediaRecorder.reset();

            //mServiceCamera.stopPreview();
            mMediaRecorder.release();

            mServiceCamera.release();
            mServiceCamera = null;

        }


    }


    private String getFilename() {
        String filepath =Environment.getExternalStorageDirectory() + File.separator
                + Environment.DIRECTORY_DCIM + File.separator + "MY_VIDEO_OK.mp4";
        File file = new File(filepath, VIDEO_RECORDER_FOLDER);
        if (!file.exists()) {
            file.mkdirs();
        }
        return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
    }


    @Override
    public boolean onStopJob(JobParameters params) {
        return true;
    }
}     
        

 

2) Created empty Activity, Suppose name is VideoRecorderActivity, Create two buttons for start and stop recording and also create a surface view with height 1 dp in the XML file of VideoRecorderActivity. 

 

            public class VideoRecorderActivity extends AppCompatActivity {

    private static final String TAG = VideoRecorderActivity.class.getSimpleName();
    public static SurfaceView mSurfaceView;
    public static SurfaceHolder mSurfaceHolder;
    public static Camera mCamera;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recorder_video);

        Button startVideo = (Button) findViewById(R.id.start_video);
        Button stopVideo = (Button) findViewById(R.id.stop_video);
        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);


        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
            // todo--keep this methods exmpty
            }

            @Override
            public void surfaceChanged(SurfaceHolder myholder, int formatInt, int widths, int heights) {
            // todo--keep this methods exmpty
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                // todo--keep this methods exmpty
            }
        });
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);




        startVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                    startService(new Intent(VideoRecorderActivity.this, VideoJobService.class));


            }
        });
        stopVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(new Intent(VideoRecorderActivity.this, VideoJobService.class));
            }
        });


    }
}    

3) Take the following required permission in the AndroidManifest.xml file,

<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-feature android:name="android.hardware.camera.autofocus" />

 

4)  Declaration of service class with the service tag in AndroidManifest.xml in the application tag,

 
 <service android:name=".VideoJobService" android:permission="android.permission.BIND_JOB_SERVICE" />  
 

 

 

Conclusion: In the blog post, We have covered a very important concept of Job service by using video recording with a different scenario when the camera is on the hidden state. Hope this blog will enhance the knowledge of the reader with the concepts of job services and media recording.


About Author

Author Image
Arun Kumar

He is very energetic, wonderful and enthusiastic, with amazing Brain!. He tries to achieve near perfection in his work, be it code quality or design of user interface. He is able to deliver his work before specified deadlines and norms.He is rising talent

Request for Proposal

Name is required

Comment is required

Sending message..