May 29, 2011

[Android] Background Video Recorder on Android

In the Android, most developers provide the camera or video recorder application in the Android Market, but they only record the video on the foreground view. In that case, we can't keep to record video when other services are coming. For example, when you are recording the video, and then you want to change to other application to do some work. So you have to return to the home screen. This will stop the video recording process.
To solve the problem, we can apply the service for the video recording. When the video recorder is starting with a service, the video recorder can be run in the background. In that case, you can keep to record the video screen even though you are accessing other application.



This article shows an example for making video record as a service on Android.

1. First of all, you have to create a Android project for developing the video recorder application.
2. Initialize the camera and media record instances.
3. For starting the Service, you have to new an Intent instance to indicate which the service you want to start.

Indicate the source activity and the target service in intent variable.
The Intent.FLAG_ACTIVITY_NEW_TASK is set for intent to indicate the activity will become a new task.
When the service will be started, the first activity has to be closed. So we call the finish() to close the activity.

Intent intent = new Intent(CameraRecorder.this, RecorderService.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startService(intent);
finish();

4. You can reference to the Android SDK website: MediaRecorder for recording the video.

You have to follow the steps of MediaRecorder.



You can reference this code.

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(); 

The sample project implements a service for video recording is uploaded to the Github. You can find out the repository and download it from this link: CameraRecorder in Github.

16 comments:

  1. I was trying to put the following inside a for loop:

    public void onClick(View v)
    {

    for (int i = 0; i < 5; i++)
    {
    Intent intent = new Intent(CameraRecorder.this, RecorderService.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    startService(intent);
    finish();
    }
    }

    In the RecorderService class, I set a max time limit so it automatically records a video at a preset time interval. That works fine, but there is difficulty in trying to get it to record a new video.

    I am trying to see if it is possible to get a Service to automatically record 5 videos after an individual presses the "start" button. The for loop does not work. Would you know why?

    Thank you for this. It was very informative.

    ReplyDelete
    Replies
    1. I think you should manage the Camera by yourself, because you cannot launch one Camera in multiple services by this simple way. Maybe you should close the previous recording, and then start the new recording.

      Delete
  2. I would like to launch this without ever seeing an Activity. I have added the following code to accomplish this.

    @Override
    protected void onResume()
    {
    super.onResume() ;

    Runnable task = new Runnable() {
    public void run() {
    /* Do something… */
    if (mPreviewRunning)
    {
    mPreviewRunning = !mPreviewRunning;
    stopService(new Intent(CameraRecorder.this, RecorderService.class));
    finish();
    }
    else
    {
    mPreviewRunning = !mPreviewRunning;
    Intent intent = new Intent(CameraRecorder.this, RecorderService.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startService(intent);
    finish();
    }
    }
    };
    worker.schedule(task, 100, TimeUnit.MILLISECONDS);
    }

    Thank you so much for posting this!

    ReplyDelete
  3. private static final ScheduledExecutorService worker =
    Executors.newSingleThreadScheduledExecutor();

    Please modify my previous post to include this.

    ReplyDelete
  4. Thanks for the sample! One problem, though - how to restore the preview when the activity is brought back to the front (assume that finish(); wasn't called and the 'home' button was pressed, then I switch back to the activity via the 'recent activities list)?

    I've tried all possible permutations of setPreviewDisplay() for the camera and MediaRecorder, but it seems once recording, nothing will take effect anymore :(

    Thanks,
    .a

    ReplyDelete
  5. I have the same problem sasha :(

    ReplyDelete
  6. Hide your preview surface when you want to put recording in background.
    Show your preview surface when recording is foreground activity.
    Use surface APIs to do so.

    ReplyDelete
  7. 'Camera Recorder' in github..wow dude, god bless;thanx for sharing!
    very, very helpful. keep it up..

    ReplyDelete
    Replies
    1. its not working for me! it runs and all, but the camera never captures and save anything.

      Delete
  8. 01-22 04:43:44.890: E/AndroidRuntime(5457): FATAL EXCEPTION: main
    01-22 04:43:44.890: E/AndroidRuntime(5457): java.lang.RuntimeException: Unable to start service com.android.camerarecorder.RecorderService@41398eb8 with Intent { flg=0x10000000 cmp=com.android.camerarecorder/.RecorderService }: java.lang.RuntimeException: start failed.
    01-22 04:43:44.890: E/AndroidRuntime(5457): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2390)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at android.app.ActivityThread.access$1900(ActivityThread.java:128)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1224)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at android.os.Handler.dispatchMessage(Handler.java:99)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at android.os.Looper.loop(Looper.java:137)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at android.app.ActivityThread.main(ActivityThread.java:4517)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at java.lang.reflect.Method.invokeNative(Native Method)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at java.lang.reflect.Method.invoke(Method.java:511)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:995)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at dalvik.system.NativeStart.main(Native Method)
    01-22 04:43:44.890: E/AndroidRuntime(5457): Caused by: java.lang.RuntimeException: start failed.
    01-22 04:43:44.890: E/AndroidRuntime(5457): at android.media.MediaRecorder.start(Native Method)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at com.android.camerarecorder.RecorderService.startRecording(RecorderService.java:100)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at com.android.camerarecorder.RecorderService.onStartCommand(RecorderService.java:46)
    01-22 04:43:44.890: E/AndroidRuntime(5457): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2373)
    01-22 04:43:44.890: E/AndroidRuntime(5457): ... 10 more
    01-22 04:43:44.900: E/android.os.Debug(1979): !@Dumpstate > dumpstate -k -t -n -z -d -o /data/log/dumpstate_app_error

    ReplyDelete
  9. Awesome work Thanks A lot For this post
    Keep on blogging good things like this

    ReplyDelete
  10. This code crashes and doesn't works for android 4.0 can you explain the reason for it or can you modify this code for android 4.0

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. This code crashes and doesn't works for android 4.0 can you explain the reason for it or can you modify this code for android 4.0

    ReplyDelete
  13. This code crashes and doesn't works for android 4.0 can you explain the reason for it or can you modify this code for android 4.0

    ReplyDelete