Since android 5.0 they are providing mediaprojection library to capture screen content. but sample demo application provided by them is not clear. U can find sample app here. In that application they are projecting captured screen using virtualdisplay method
private void setUpVirtualDisplay() {
Log.i(TAG, "Setting up a VirtualDisplay: " +
mSurfaceView.getWidth() + "x" + mSurfaceView.getHeight() +
" (" + mScreenDensity + ")");
mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCapture",
mSurfaceView.getWidth(), mSurfaceView.getHeight(), mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mSurface, null, null);
mButtonToggle.setText(R.string.stop);
}
I want to convert captured screen into mp4 file for my screen recording application. Please help me to get through this.
The media projection APIs introduced in Android 5 (API level 21) enable you to capture the contents of a device display as a media stream that you can play back, record, or cast to other devices, such as TVs.
The first step is to request permission to capture the screen. Launching this intent will show a confirmation dialog to the user which allows them to authorise the screen capturing. Once they accept, you can use the result code and data intent returned in onActivityResult, we are able to create a MediaProjection.
But Android Service has no onActivityResult () method that MediaProjection need to do something. It seems that we can only call MediaProjection API like belows: Is there a way to use MediaProjection in an Android Service? My App has no Activity but only a Service.
This sample demonstrates how to use Media Projection API to capture device screen in real time and show it on a SurfaceView. Launch the app on a Lollipop device or emulator. On devices with display widths under 720dp, tap the Show Log button to show the sample's log.
There is a good explanation on how to use MediaProjection API to actually record the screen to an mp4 file on the external storage. This solution uses the MediaRecorder to store the video. You can find another solution on the page of Matt Snider. There the MediaMuxer is used to store the video on to the external storage.
Even though MediaProjection is a solid solution for taking screenshots, it too has major downsides. As it’s a very powerful mechanism that allows recording everything that’s happening on a display, that’s no surprise a user’s consent to initiate a capture session is required.
here is sample code refference from
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int PERMISSION_CODE = 1;
private int mScreenDensity;
private MediaProjectionManager mProjectionManager;
private static final int DISPLAY_WIDTH = 480;
private static final int DISPLAY_HEIGHT = 640;
private MediaProjection mMediaProjection;
private VirtualDisplay mVirtualDisplay;
private MediaProjectionCallback mMediaProjectionCallback;
private ToggleButton mToggleButton;
private MediaRecorder mMediaRecorder;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mScreenDensity = metrics.densityDpi;
mMediaRecorder = new MediaRecorder();
initRecorder();
prepareRecorder();
mProjectionManager = (MediaProjectionManager) getSystemService
(Context.MEDIA_PROJECTION_SERVICE);
mToggleButton = (ToggleButton) findViewById(R.id.toggle);
mToggleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onToggleScreenShare(v);
}
});
mMediaProjectionCallback = new MediaProjectionCallback();
}
@Override
public void onDestroy() {
super.onDestroy();
if (mMediaProjection != null) {
mMediaProjection.stop();
mMediaProjection = null;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != PERMISSION_CODE) {
Log.e(TAG, "Unknown request code: " + requestCode);
return;
}
if (resultCode != RESULT_OK) {
Toast.makeText(this,
"Screen Cast Permission Denied", Toast.LENGTH_SHORT).show();
mToggleButton.setChecked(false);
return;
}
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
mMediaProjection.registerCallback(mMediaProjectionCallback, null);
mVirtualDisplay = createVirtualDisplay();
mMediaRecorder.start();
}
public void onToggleScreenShare(View view) {
if (((ToggleButton) view).isChecked()) {
shareScreen();
} else {
mMediaRecorder.stop();
mMediaRecorder.reset();
Log.v(TAG, "Recording Stopped");
stopScreenSharing();
initRecorder();
prepareRecorder();
}
}
private void shareScreen() {
if (mMediaProjection == null) {
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), PERMISSION_CODE);
return;
}
mVirtualDisplay = createVirtualDisplay();
mMediaRecorder.start();
}
private void stopScreenSharing() {
if (mVirtualDisplay == null) {
return;
}
mVirtualDisplay.release();
//mMediaRecorder.release();
}
private VirtualDisplay createVirtualDisplay() {
return mMediaProjection.createVirtualDisplay("MainActivity",
DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mMediaRecorder.getSurface(), null /*Callbacks*/, null /*Handler*/);
}
private class MediaProjectionCallback extends MediaProjection.Callback {
@Override
public void onStop() {
if (mToggleButton.isChecked()) {
mToggleButton.setChecked(false);
mMediaRecorder.stop();
mMediaRecorder.reset();
Log.v(TAG, "Recording Stopped");
initRecorder();
prepareRecorder();
}
mMediaProjection = null;
stopScreenSharing();
Log.i(TAG, "MediaProjection Stopped");
}
}
private void prepareRecorder() {
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
finish();
} catch (IOException e) {
e.printStackTrace();
finish();
}
}
private void initRecorder() {
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(DISPLAY_WIDTH, DISPLAY_HEIGHT);
mMediaRecorder.setOutputFile("/sdcard/capture.mp4");
}
}
You're passing the Surface from a SurfaceView into createVirtualDisplay()
. Replace that with the Surface from a MediaRecorder.
Look at this POST. There is a good explanation on how to use MediaProjection API to actually record the screen to an mp4 file on the external storage. This solution uses the MediaRecorder to store the video.
You can find another solution on the page of Matt Snider. There the MediaMuxer is used to store the video on to the external storage. But note that the output of the MediaMuxer is not streamable.
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