安卓录屏保存成MP4

/**
 * Created by leilu on 2017/12/25.
 */
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class MyScreenActivity extends Activity {

    private static final int REQUEST_CODE = 10;

    private MediaProjectionManager mediaProjectionManager;
    private MediaCodec mediaCodec;
    private MediaMuxer mediaMuxer;
    private VirtualDisplay virtualDisplay;
    private int videoTrackIndex;

    private boolean isRecording;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_screen);
    }


    public void start(View view) {
        mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        Intent intent = mediaProjectionManager.createScreenCaptureIntent();
        startActivityForResult(intent, REQUEST_CODE);
    }

    public void stop(View view) {
        isRecording = false;
    }

    @Override
    protected void onActivityResult(int requestCode, final int resultCode, final Intent data) {
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    startRecord(resultCode, data);
                }
            }).start();
            moveTaskToBack(true);
        }
    }

    private void startRecord(int resultCode, Intent data) {
        MediaProjection mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
        Surface surface = init();
        if (surface == null) {
            throw new RuntimeException("不能录屏!");
        }
        virtualDisplay = mediaProjection.createVirtualDisplay(getClass().getName(), getScreenWidth(), getScreenHeight(), getResources().getDisplayMetrics().densityDpi
                , DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, surface, null, null);
        isRecording = true;
        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
        while (isRecording) {
            int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 10000);
            if (outputBufferIndex > 0) {
                ByteBuffer byteBuffer = mediaCodec.getOutputBuffer(outputBufferIndex);
                mediaMuxer.writeSampleData(videoTrackIndex, byteBuffer, bufferInfo);
                mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
            } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                resetOutputFormat();
            }
        }
        release();
    }

    private void resetOutputFormat() {
        MediaFormat mediaFormat = mediaCodec.getOutputFormat();
        videoTrackIndex = mediaMuxer.addTrack(mediaFormat);
        mediaMuxer.start();
    }

    private void release() {
        if (mediaCodec != null) {
            mediaCodec.stop();
            mediaCodec.release();
        }
        if (virtualDisplay != null) {
            virtualDisplay.release();
        }
        if (mediaMuxer != null) {
            mediaMuxer.release();
        }
    }

    private Surface init() {
        Surface surface = null;
        try {
            MediaFormat mediaFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, getScreenWidth(), getScreenHeight());
            mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
            mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 96000);
            mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
            mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
            mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 5);
            mediaCodec = MediaCodec.createEncoderByType(MediaFormat.MIMETYPE_VIDEO_AVC);
            mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            surface = mediaCodec.createInputSurface();
            mediaCodec.start();
            mediaMuxer = new MediaMuxer("/sdcard/screen.mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return surface;
    }

    private int getScreenWidth() {
        return getResources().getDisplayMetrics().widthPixels;
    }

    private int getScreenHeight() {
        return getResources().getDisplayMetrics().heightPixels;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值