Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Mediaprojection library in android to capture screen and convert into mp4 file?

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.

like image 588
chandra mohan Avatar asked Apr 07 '15 21:04

chandra mohan


People also ask

What is media projection in Android?

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.

How do I give permission to media projection?

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.

Is there a way to use mediaprojection in an Android service?

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.

How to use media projection API to capture screen on surfaceview?

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.

How to record screen to an MP4 file?

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.

Is mediaprojection the best way to take a screenshot?

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.


Video Answer


3 Answers

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");
    }
}
like image 189
Uday Nayak Avatar answered Nov 03 '22 11:11

Uday Nayak


You're passing the Surface from a SurfaceView into createVirtualDisplay(). Replace that with the Surface from a MediaRecorder.

like image 44
fadden Avatar answered Nov 03 '22 10:11

fadden


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.

like image 35
Failster Avatar answered Nov 03 '22 11:11

Failster