How to record video from background of application : Android

前端 未结 3 1429
北恋
北恋 2020-11-28 18:08

I am developing an application which will be able to record video from background of application by using Service.

Problem description :

相关标签:
3条回答
  • 2020-11-28 18:19

    1- I have created a activity to start service like this:

    package com.android.camerarecorder;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.hardware.Camera;
    import android.os.Bundle;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.widget.Button;
    
    public class CameraRecorder extends Activity implements SurfaceHolder.Callback {
        private static final String TAG = "Recorder";
        public static SurfaceView mSurfaceView;
        public static SurfaceHolder mSurfaceHolder;
        public static Camera mCamera ;
        public static boolean mPreviewRunning;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
            mSurfaceHolder = mSurfaceView.getHolder();
            mSurfaceHolder.addCallback(this);
            mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    
            Button btnStart = (Button) findViewById(R.id.StartService);
            btnStart.setOnClickListener(new View.OnClickListener()
            {
                public void onClick(View v)
                {
                    Intent intent = new Intent(CameraRecorder.this, RecorderService.class);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startService(intent);
                    finish();
                }
            });
    
            Button btnStop = (Button) findViewById(R.id.StopService);
            btnStop.setOnClickListener(new View.OnClickListener()
            {
                public void onClick(View v)
                {
                    stopService(new Intent(CameraRecorder.this, RecorderService.class));
                }
            });
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
    
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
    
        }
    }
    

    2 - Now I have created a service to record the video in background like this:

        package com.android.camerarecorder;
        import java.io.IOException;
        import java.util.List;
        import android.app.Service;
        import android.content.Intent;
        import android.graphics.PixelFormat;
        import android.hardware.Camera;
        import android.hardware.Camera.Size;
        import android.media.MediaRecorder;
        import android.os.IBinder;
        import android.util.Log;
        import android.view.SurfaceHolder;
        import android.view.SurfaceView;
        import android.widget.Toast;
    
        public class RecorderService extends Service {
            private static final String TAG = "RecorderService";
            private SurfaceView mSurfaceView;
            private SurfaceHolder mSurfaceHolder;
            private static Camera mServiceCamera;
            private boolean mRecordingStatus;
            private MediaRecorder mMediaRecorder;
    
            @Override
            public void onCreate() {
                mRecordingStatus = false;
                //mServiceCamera = CameraRecorder.mCamera;
                mServiceCamera = Camera.open(1);
                mSurfaceView = CameraRecorder.mSurfaceView;
                mSurfaceHolder = CameraRecorder.mSurfaceHolder;
    
                super.onCreate();
                if (mRecordingStatus == false)
                    startRecording();
            }
    
            @Override
            public IBinder onBind(Intent intent) {
                // TODO Auto-generated method stub
                return null;
            }
    
            @Override
            public void onDestroy() {
                stopRecording();
                mRecordingStatus = false;
    
                super.onDestroy();
            }   
    
            public boolean startRecording(){
                try {
                    Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();
    
                    //mServiceCamera = Camera.open();
                    Camera.Parameters params = mServiceCamera.getParameters();
                    mServiceCamera.setParameters(params);
                    Camera.Parameters p = mServiceCamera.getParameters();
    
                    final List<Size> listSize = p.getSupportedPreviewSizes();
                    Size mPreviewSize = listSize.get(2);
                    Log.v(TAG, "use: width = " + mPreviewSize.width 
                                + " height = " + mPreviewSize.height);
                    p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
                    p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
                    mServiceCamera.setParameters(p);
    
                    try {
                        mServiceCamera.setPreviewDisplay(mSurfaceHolder);
                        mServiceCamera.startPreview();
                    }
                    catch (IOException e) {
                        Log.e(TAG, 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.MPEG_4);
                    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
                    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
                    mMediaRecorder.setOutputFile("/sdcard/video.mp4");
                    mMediaRecorder.setVideoFrameRate(30);
                    mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
                    mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
    
                    mMediaRecorder.prepare();
                    mMediaRecorder.start(); 
    
                    mRecordingStatus = true;
    
                    return true;
                } catch (IllegalStateException e) {
                    Log.d(TAG, e.getMessage());
                    e.printStackTrace();
                    return false;
                } catch (IOException e) {
                    Log.d(TAG, e.getMessage());
                    e.printStackTrace();
                    return false;
                }
            }
    
            public void stopRecording() {
                Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
                try {
                    mServiceCamera.reconnect();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                mMediaRecorder.stop();
                mMediaRecorder.reset();
    
                mServiceCamera.stopPreview();
                mMediaRecorder.release();
    
                mServiceCamera.release();
                mServiceCamera = null;
            }
        }
    

    It will create a file video.mp4 in your sd card. you may change the code for adding more functionality but the basic functionality is achieved through this code i.e. record video in background.

    NOTE: i have started the service through button click in activity but you can start it through any other way also like broadcastreceiver etc.

    Hope it helps!! Cheers.

    0 讨论(0)
  • 2020-11-28 18:30

    Here are some cool android projects regarding the same with some variations :

    https://github.com/zeitgeist87/SpartanTimeLapseRecorder/blob/master/src/at/andreasrohner/spartantimelapserec/recorder/VideoRecorder.java - Control FPS of camera

    https://www.sisik.eu/blog/android/media/camera2-from-service - Image from background camera

    https://github.com/kevalpatel2106/android-hidden-camera/blob/master/hiddencamera/src/main/java/com/androidhiddencamera/HiddenCameraService.java

    https://github.com/botyourbusiness/android-camera2-secret-picture-taker - Official

    https://gist.github.com/joseph-zhong/c2a52a5507d6588bec2db9869c860114

    https://github.com/ulysses4ever/Background-VideoRecorder

    0 讨论(0)
  • 2020-11-28 18:43

    Yes, you can record the background video like this:

    First, create a video app using service. Do not set its view so that it will not be visible. If you are doing it in service then that is better because...

    Second, you can use the AlarmManager for setting the alarm of particular time and then at that time, by using intent, start your service again. For stopping your app you can use AlarmManager, as well.

    0 讨论(0)
提交回复
热议问题