Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.example.stw.myapplication;
- import android.app.Activity;
- import android.content.Context;
- import android.content.Intent;
- import android.hardware.display.DisplayManager;
- import android.media.MediaCodec;
- import android.media.MediaCodecInfo;
- import android.media.MediaFormat;
- import android.media.MediaMuxer;
- import android.media.projection.MediaProjection;
- import android.media.projection.MediaProjectionManager;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Looper;
- import android.util.DisplayMetrics;
- import android.view.Display;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.view.Surface;
- import android.view.SurfaceView;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- public class MainActivity extends Activity {
- private boolean recording=false;
- private Button button;
- private MediaProjectionManager mMediaProjectionManager;
- private static final int REQUEST_CODE_CAPTURE_PERM = 1234;
- private MediaProjection mMediaProjection;
- private static final String VIDEO_MIME_TYPE = "video/avc";
- private static final int VIDEO_WIDTH = 1280;
- private static final int VIDEO_HEIGHT = 720;
- private DisplayMetrics metrics;
- private int screenDensity;
- private int screenWidth;
- private int screenHeight;
- // …
- private boolean mMuxerStarted = false;
- private Surface mInputSurface;
- private MediaMuxer mMuxer;
- private MediaCodec mVideoEncoder;
- private MediaCodec.BufferInfo mVideoBufferInfo;
- private int mTrackIndex = -1;
- private SurfaceView mSurfaceView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mMediaProjectionManager = (MediaProjectionManager) getSystemService(
- android.content.Context.MEDIA_PROJECTION_SERVICE);
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.menu_main, menu);
- return true;
- }
- public void buttonOnClick(View view){
- button=(Button) view;
- if(recording){
- recording=false;
- ((Button) view).setText("Start Recording");
- releaseEncoders();
- }
- else {
- recording=true;
- ((Button) view).setText("Stop Recording");
- Intent permissionIntent = mMediaProjectionManager.createScreenCaptureIntent();
- startActivityForResult(permissionIntent, REQUEST_CODE_CAPTURE_PERM);
- }
- }
- public void onActivityResult(int requestCode, int resultCode, Intent intent) {
- if (REQUEST_CODE_CAPTURE_PERM == requestCode) {
- if (resultCode == RESULT_OK) {
- mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, intent);
- startRecording();
- } else {
- }
- }
- }
- private final Handler mDrainHandler = new Handler(Looper.getMainLooper());
- private Runnable mDrainEncoderRunnable = new Runnable() {
- @Override
- public void run() {
- drainEncoder();
- }
- };
- // …
- private void startRecording() {
- DisplayManager dm = (DisplayManager)getSystemService(Context.DISPLAY_SERVICE);
- Display defaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
- if (defaultDisplay == null) {
- throw new RuntimeException("No display found.");
- }
- prepareVideoEncoder();
- try {
- mMuxer = new MediaMuxer(getFilesDir()+"/video7.mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
- } catch (IOException ioe) {
- throw new RuntimeException("MediaMuxer creation failed", ioe);
- }
- // Get the display size and density.
- metrics = getResources().getDisplayMetrics();
- screenDensity=metrics.densityDpi;
- screenHeight=metrics.heightPixels;
- screenWidth=metrics.widthPixels;
- // Start the video input.
- mMediaProjection.createVirtualDisplay("Recording Display", screenWidth,
- screenHeight, screenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, mInputSurface,
- null /* callback */, null /* handler */);
- // Start the encoders
- drainEncoder();
- }
- private void prepareVideoEncoder() {
- mVideoBufferInfo = new MediaCodec.BufferInfo();
- MediaFormat format = MediaFormat.createVideoFormat(VIDEO_MIME_TYPE, VIDEO_WIDTH, VIDEO_HEIGHT);
- int frameRate = 30; // 30 fps
- // Set some required properties. The media codec may fail if these aren't defined.
- format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
- MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
- format.setInteger(MediaFormat.KEY_BIT_RATE, 6000000); // 6Mbps
- format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
- format.setInteger(MediaFormat.KEY_CAPTURE_RATE, frameRate);
- format.setInteger(MediaFormat.KEY_REPEAT_PREVIOUS_FRAME_AFTER, 1000000 / frameRate);
- format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
- format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); // 1 seconds between I-frames
- // Create a MediaCodec encoder and configure it. Get a Surface we can use for recording into.
- try {
- mVideoEncoder = MediaCodec.createEncoderByType(VIDEO_MIME_TYPE);
- mVideoEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
- mInputSurface = mVideoEncoder.createInputSurface();
- mVideoEncoder.start();
- } catch (IOException e) {
- releaseEncoders();
- }
- }
- private boolean drainEncoder() {
- mDrainHandler.removeCallbacks(mDrainEncoderRunnable);
- while (true) {
- int bufferIndex = mVideoEncoder.dequeueOutputBuffer(mVideoBufferInfo, 0);
- if (bufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
- // nothing available yet
- break;
- } else if (bufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
- // should happen before receiving buffers, and should only happen once
- if (mTrackIndex >= 0) {
- throw new RuntimeException("format changed twice");
- }
- mTrackIndex = mMuxer.addTrack(mVideoEncoder.getOutputFormat());
- if (!mMuxerStarted && mTrackIndex >= 0) {
- mMuxer.start();
- mMuxerStarted = true;
- }
- } else if (bufferIndex < 0) {
- // not sure what's going on, ignore it
- } else {
- ByteBuffer encodedData = mVideoEncoder.getOutputBuffer(bufferIndex);
- if (encodedData == null) {
- throw new RuntimeException("couldn't fetch buffer at index " + bufferIndex);
- }
- if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
- mVideoBufferInfo.size = 0;
- }
- if (mVideoBufferInfo.size != 0) {
- if (mMuxerStarted) {
- encodedData.position(mVideoBufferInfo.offset);
- encodedData.limit(mVideoBufferInfo.offset + mVideoBufferInfo.size);
- mMuxer.writeSampleData(mTrackIndex, encodedData, mVideoBufferInfo);
- } else {
- // muxer not started
- }
- }
- mVideoEncoder.releaseOutputBuffer(bufferIndex, false);
- if ((mVideoBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
- break;
- }
- }
- }
- mDrainHandler.postDelayed(mDrainEncoderRunnable, 10);
- return false;
- }
- private void releaseEncoders() {
- mDrainHandler.removeCallbacks(mDrainEncoderRunnable);
- if (mMuxer != null) {
- if (mMuxerStarted) {
- mMuxer.stop();
- }
- mMuxer.release();
- mMuxer = null;
- mMuxerStarted = false;
- }
- if (mVideoEncoder != null) {
- mVideoEncoder.stop();
- mVideoEncoder.release();
- mVideoEncoder = null;
- }
- if (mInputSurface != null) {
- mInputSurface.release();
- mInputSurface = null;
- }
- if (mMediaProjection != null) {
- mMediaProjection.stop();
- mMediaProjection = null;
- }
- mVideoBufferInfo = null;
- mDrainEncoderRunnable = null;
- mTrackIndex = -1;
- }
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- // Handle action bar item clicks here. The action bar will
- // automatically handle clicks on the Home/Up button, so long
- // as you specify a parent activity in AndroidManifest.xml.
- int id = item.getItemId();
- //noinspection SimplifiableIfStatement
- if (id == R.id.action_settings) {
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement