android通过MediaProjectionManager录屏关联MediaCodec获取h264数据

android 5.0增加了MediaProjectionManager,通过它我们可以简单的完成录屏的需求。

本文会简单介绍MediaProjectionManager的使用流程,通过MediaCodec获取到的264数据

MediaProjectionManager的用法

1.获取MediaProjectionManager实例

     通过调用getSystemService方法获取MediaProjectionManager的实例

/**
     * 初始化MediaProjectionManager
     * **/
    private void InitMPManager(){
        mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
    }

2.创建屏幕捕捉的Intent

    获取到MediaProjectionManager的实例后,通过createScreenCaptureIntent方法获取Intnent,通过startActivityForResult启动Intent

/**
     * 开始截屏
     * **/
    private void StartScreenCapture(){
        Intent captureIntent = mMediaProjectionManager.createScreenCaptureIntent();
        startActivityForResult(captureIntent, REQUEST_CODE_A);
    }

3.在onActivityResult中获取MediaProjection实例

        通过startActivityForResult启动intent后,在onActivityResult的回掉中获取MediaProjection的实例,这时候要开始初始化MediaCodec了,通过MediaCodec可以拿到Surface对像,通过MediaProjection对象的createVirtualDisplay方法,拿到VirtureDisplay对象,拿这个对象的时候,需要把Surface对象传进去。
  • 获取MediaProjection
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        try {
            MediaProjection mediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);
        }
        catch (Exception e){

        }
    }

  • 初始化MediaCodec,获取Surface对象
try{
            MediaFormat format = MediaFormat.createVideoFormat(Constant.MIME_TYPE, Constant.VIDEO_WIDTH, Constant.VIDEO_HEIGHT);
            format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
                    MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
            format.setInteger(MediaFormat.KEY_BIT_RATE, Constant.VIDEO_BITRATE);
            format.setInteger(MediaFormat.KEY_FRAME_RATE, Constant.VIDEO_FRAMERATE);
            format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, Constant.VIDEO_IFRAME_INTER);
            mEncoder = MediaCodec.createEncoderByType(Constant.MIME_TYPE);
            mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
            mSurface = mEncoder.createInputSurface();
            mEncoder.start();
        }catch (IOException e){

        }

  • 获取VirtureDisplay对象
mVirtualDisplay =mMediaProjection.createVirtualDisplay(TAG + "-display", Constant.VIDEO_WIDTH, Constant.VIDEO_HEIGHT, Constant.VIDEO_DPI, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
                mSurface, null, null);

4.通过MediaCodec获取h264数据

通过MediaCodec获取264的代码,可以参考我的这个项目:Github

或者参考我之前的博客内容:android编码h264(二):MediaCodec 硬编码 h264(硬编码)

MediaCodec.BufferInfo mBufferInfo = new MediaCodec.BufferInfo();
                int outputBufferIndex  = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
                while (outputBufferIndex >= 0){
                    ByteBuffer outputBuffer = mEncoder.getOutputBuffers()[outputBufferIndex];
                    byte[] outData = new byte[mBufferInfo.size];
                    outputBuffer.get(outData);
                    if(mBufferInfo.flags == 2){
                        configbyte = new byte[mBufferInfo.size];
                        configbyte = outData;
                    }else if(mBufferInfo.flags == 1){
                        byte[] keyframe = new byte[mBufferInfo.size + configbyte.length];
                        System.arraycopy(configbyte, 0, keyframe, 0, configbyte.length);
                        System.arraycopy(outData, 0, keyframe, configbyte.length, outData.length);
                        if(outputStream != null){
                            outputStream.write(keyframe, 0, keyframe.length);
                        }
                    }else{
                        if(outputStream != null){
                            outputStream.write(outData, 0, outData.length);
                        }
                    }
                    mEncoder.releaseOutputBuffer(outputBufferIndex, false);
                    outputBufferIndex = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
                }

到此,就基本结束了,写这个是为了一个项目做基础准备的,这个项目要解决如下问题:

不知道大家有没有遇到过,app开发完成后要给领导或者客户演示,如果领导在还好,如果不在,那么就会通过本地录像的方式来演示,我像通过rtsp或者rtmp流媒体的方式,将屏幕内容来实时的演示,目前项目才开始,代码会慢慢提交的。

项目地址:GitHub

这篇博客的代码也在这个工程里

你可能感兴趣的:(Android)