Screen Video Record of Current Activity Android
Asked Answered
G

6

30

Is it possible to record screen video of current running activity from same activity ?
I know how to take screenshot of current activity but don't have any idea about taking screen video record. How would I start with it ? I don't know how to start it.

Getup answered 15/1, 2013 at 11:4 Comment(10)
I think we have to use tools for recording..Philina
Well my requirements are not same as these play.google.com/store/apps/… but how they do it without any use of external tools ?Getup
yes it is possible capture screen and then add to videoPhilina
How would i do it without the use of any external tools ? Can you give me some guidelines ?Getup
you know how to capture screen next you add the images to get the videoPhilina
adding images into video requires use of NDK which i want to avoid. Is there any java libraries available for encoding images into video ? Also you didn't tell me about directly recording video of screen .Getup
can you explain what you want to achieve more exactly? there are many different ways to record video.Yovonnda
I want to capture device screen video programmatically i.e java in my android project.Getup
Android 4.4 added a command-line utility to record the screen. See developer.android.com/about/versions/…Jeanajeanbaptiste
@YamenImadNassif I ended up using github.com/jcodec/jcodec for encoding each screenshot. And for lollipop I used screen capture api.Getup
R
18

EDIT: This answer is superceded by the answer below from Danpe.

Programmatically recording video from within your app will require root access. You'll notice that the apps available to do this in the Play Store prominently list "REQUIRES ROOT" in their app descriptions. You'll also notice that there may also be some specific hardware requirements for this approach to work ("Does not work on Galaxy Nexus or Tegra 2/3..." -- from the description of the Screencast Video Recorder app.

I have never written this code myself, but I've put together a very high level idea of the approach required. It appears from this post that you have to access the frame buffer data via "/dev/graphics/fb0". The access mode for the frame buffer is 660, which means that you need root access to get to it. Once you have root access, you can use the frame buffer data to create screen shots (this project might work for this task) and then create video from these screenshots (see this other SO question on how to create video from an image sequence).

I've used the Screencast app and it works well on a Samsung Note. I suspect that this is the basic approach they've taken.

Rustler answered 2/2, 2013 at 19:5 Comment(2)
Although i am not getting concrete answer but you have provided some ideas about screenshot frame buffer and root access. I am going to research on it further.And marked it as right answer. Thanx for the guidelines.Getup
This chosen solution must be outdated because there are definitely apps in the Play Store that do not require root permission to record the device's screen. So it is safe to say that if those apps can record the entire screen of any app, you can just as well record an activity.Bisitun
H
33

Since Lollipop we can use the Media Projection API ! (API 21+)

Here is the following code that I use for recording, Note that we first need to get the user permissions for that ;)

private static final int CAST_PERMISSION_CODE = 22;
private DisplayMetrics mDisplayMetrics;
private MediaProjection mMediaProjection;
private VirtualDisplay mVirtualDisplay;
private MediaRecorder mMediaRecorder;

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

    mMediaRecorder = new MediaRecorder();

    mProjectionManager = (MediaProjectionManager) getSystemService
            (Context.MEDIA_PROJECTION_SERVICE);

    getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);

    prepareRecording();
}

private void startRecording() {
    // If mMediaProjection is null that means we didn't get a context, lets ask the user
    if (mMediaProjection == null) {
        // This asks for user permissions to capture the screen
        startActivityForResult(mProjectionManager.createScreenCaptureIntent(), CAST_PERMISSION_CODE);
        return;
    }
    mVirtualDisplay = createVirtualDisplay();
    mMediaRecorder.start();
}

private void stopRecording() {
    if (mMediaRecorder != null) {
        mMediaRecorder.stop();
        mMediaRecorder.reset();
    }
    if (mVirtualDisplay != null) {
        mVirtualDisplay.release();
    }
    if (mMediaProjection != null) {
        mMediaProjection.stop();
    }
    prepareRecording();
}

public String getCurSysDate() {
    return new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss").format(new Date());
}

private void prepareRecording() {
    try {
        mMediaRecorder.prepare();
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }

    final String directory = Environment.getExternalStorageDirectory() + File.separator + "Recordings";
    if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
        Toast.makeText(this, "Failed to get External Storage", Toast.LENGTH_SHORT).show();
        return;
    }
    final File folder = new File(directory);
    boolean success = true;
    if (!folder.exists()) {
        success = folder.mkdir();
    }
    String filePath;
    if (success) {
        String videoName = ("capture_" + getCurSysDate() + ".mp4");
        filePath = directory + File.separator + videoName;
    } else {
        Toast.makeText(this, "Failed to create Recordings directory", Toast.LENGTH_SHORT).show();
        return;
    }

    int width = mDisplayMetrics.widthPixels;
    int height = mDisplayMetrics.heightPixels;

    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
    mMediaRecorder.setVideoFrameRate(30);
    mMediaRecorder.setVideoSize(width, height);
    mMediaRecorder.setOutputFile(filePath);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode != CAST_PERMISSION_CODE) {
        // Where did we get this request from ? -_-
        Log.w(TAG, "Unknown request code: " + requestCode);
        return;
    }
    if (resultCode != RESULT_OK) {
        Toast.makeText(this, "Screen Cast Permission Denied :(", Toast.LENGTH_SHORT).show();
        return;
    }
    mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
    // TODO Register a callback that will listen onStop and release & prepare the recorder for next recording
    // mMediaProjection.registerCallback(callback, null);
    mVirtualDisplay = getVirtualDisplay();
    mMediaRecorder.start();
}

private VirtualDisplay getVirtualDisplay() {
    screenDensity = mDisplayMetrics.densityDpi;
    int width = mDisplayMetrics.widthPixels;
    int height = mDisplayMetrics.heightPixels;

    return mMediaProjection.createVirtualDisplay(this.getClass().getSimpleName(),
            width, height, screenDensity,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
            mMediaRecorder.getSurface(), null /*Callbacks*/, null /*Handler*/);
}

This is no the final code but a GOOD base for start :)

Hovey answered 23/6, 2015 at 14:11 Comment(5)
this is good. get mp4 video file in sdcard, but its contain black frame on video. any solution for full screen video and handle permeation popup?Greeley
Excellent! Thank you!Zimmermann
did not work in marshmallow on medirecorder.getsurface() illigalstateexceptionYean
It will ask for permission every time on app start? is there any other way?Shiverick
I created a library that handle all of this for you including the display of a notification, have a look at my answer - https://mcmap.net/q/467751/-screen-video-record-of-current-activity-androidHydrophane
R
18

EDIT: This answer is superceded by the answer below from Danpe.

Programmatically recording video from within your app will require root access. You'll notice that the apps available to do this in the Play Store prominently list "REQUIRES ROOT" in their app descriptions. You'll also notice that there may also be some specific hardware requirements for this approach to work ("Does not work on Galaxy Nexus or Tegra 2/3..." -- from the description of the Screencast Video Recorder app.

I have never written this code myself, but I've put together a very high level idea of the approach required. It appears from this post that you have to access the frame buffer data via "/dev/graphics/fb0". The access mode for the frame buffer is 660, which means that you need root access to get to it. Once you have root access, you can use the frame buffer data to create screen shots (this project might work for this task) and then create video from these screenshots (see this other SO question on how to create video from an image sequence).

I've used the Screencast app and it works well on a Samsung Note. I suspect that this is the basic approach they've taken.

Rustler answered 2/2, 2013 at 19:5 Comment(2)
Although i am not getting concrete answer but you have provided some ideas about screenshot frame buffer and root access. I am going to research on it further.And marked it as right answer. Thanx for the guidelines.Getup
This chosen solution must be outdated because there are definitely apps in the Play Store that do not require root permission to record the device's screen. So it is safe to say that if those apps can record the entire screen of any app, you can just as well record an activity.Bisitun
W
11

Normal Android apps lack permission to capture the frame buffer (specifically, they aren't members of the AID_GRAPHICS group). This is for security reasons - otherwise they could snoop passwords etc from the soft keyboard. So in general you CANNOT capture the screen from an Android app without some way of getting around the privilege issue.

You CAN more-or-less capture a snapshot of the screen area currently taken up by your application by traversing to the top View in your view hierarchy and drawing it into a Bitmap using View.draw(Canvas), however this will not record the status bar, soft keyboard, OpenGL surfaces etc.

If you want to do better than this you will need to use an external tool. Tools either need root or to use the ADB interface, since processes started via the ADB interface have the AID_GRAPHICS privilege. Using the latter method a non-privileged app can connect to a privileged server to do the recording.

Roughly tools can be divided into the following categories:

  • Root-only framebuffer recorder apps (e.g. Screencast). These record directly from the /dev/graphics/fb0 device but only works on devices where the framebuffer is readable (e.g, not on the Tegra 2 Nexus 7).

  • Root-only screen capture recorder apps (e.g. SCR, Rec etc). These capture the screen via SurfaceFlinger and work on a much wider range of devices.

  • Non root screen capture recorder apps (e.g., Recordable, Ascrecorder). These require the user to enable USB debugging and start a daemon while connected via a host PC. Thereafter the host PC is not required until the device is rebooted. Can record audio as well.

  • ADB tools (e.g., the built-in screenrecorder on Android 4.4). Require you to be connected via a USB and can't capture audio.

For completeness there are also USB tools (e.g., Mobizen) that stream the screen across USB (limited by low USB bandwdith and can't record audio) and some devices can also transmit the screen over wifi, which can then captured on a separate device.

Winegar answered 10/4, 2014 at 9:57 Comment(2)
granted the post is 7 years old, but clicking the link for .mobi takes you to what looks like a virusPineal
Yes, domain has been be squatted. Link removed.Winegar
H
6

I created a library that handles this for you. Including the display of a notification that is customizable and can be disabled if you don't want to show a notification.

It requires API 21>


Here is a simple demonstration on how to use it: (more info can be found in the library's readme):

First, declare and init it in your Activity:

public class MainActivity extends AppCompatActivity implements HBRecorderListener {
    //Declare HBRecorder
    HBRecorder hbRecorder;

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

        //Init HBRecorder
        hbRecorder = new HBRecorder(this, this);        

}

Then when you want to start the recording you can call:

private void startRecordingScreen() {
    MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
    Intent permissionIntent = mediaProjectionManager != null ? mediaProjectionManager.createScreenCaptureIntent() : null;
    startActivityForResult(permissionIntent, SCREEN_RECORD_REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == SCREEN_RECORD_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            //It is important to call this before starting the recording
            hbRecorder.onActivityResult(resultCode, data, this);
            //Start screen recording
            hbRecorder.startScreenRecording(data);
        }
    }
}

You can stop the recording by calling:

hbRecorder.stopScreenRecording();

The onCompleteListener lets you know when the file was created:

@Override
public void HBRecorderOnComplete() {
    //This is called once the file was created
}

I also added a bunch of parameters that can be set, like changing AudioBitrate, AudioSamplingRate etc.

Hydrophane answered 17/8, 2019 at 5:29 Comment(2)
Also, method hbRecorder.onActivityResult doesn't existEsque
@KonstantinKonopko open an issue on the library.Hydrophane
S
4

This is a quite old post but i hope this will help someone who is still searching for a way to record the screen of an android device:

Since Android 5.0 there is a new API that can be used for screen recording: MediaProjection The MediaProjection grants the ability to capture screen content, but not system audio. Also it won't capture secure screen content.

On the page of Matt Snider there is a good example on how to use the API to actually record the screen to a file on the sdcard: LINK

Sprawl answered 22/6, 2015 at 13:0 Comment(0)
B
2

you can capture the screen via using DDMS as adb runs and has permission to the framebuffer:

follow this link for more details :

http://thetechjournal.com/electronics/android/how-to-capture-screenshots-and-record-video-on-android-device.xhtml

ALSO check this links may be get some ideas about what you need :

http://answers.oreilly.com/topic/951-how-to-capture-video-of-the-screen-on-android/

http://www.mightypocket.com/2010/09/installing-android-screenshots-screen-capture-screen-cast-for-windows/

and check this project :

http://sourceforge.net/projects/ashot/

hope this help .

Brianna answered 1/2, 2013 at 17:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.