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.
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.
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 :)
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.
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.
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.
hbRecorder.onActivityResult
doesn't exist –
Esque 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
you can capture the screen via using DDMS as adb runs and has permission to the framebuffer:
follow this link for more details :
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/
and check this project :
http://sourceforge.net/projects/ashot/
hope this help .
© 2022 - 2024 — McMap. All rights reserved.