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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With