android通过MediaProjectionManager录屏关联MediaCodec获取h264数据
16lz
2021-01-26
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通过Apache HTTP访问HTTP资源
- android.widget.ListView
- 【Android】 解析Json 数据示例
- Android(安卓)高级自定义Toast及源码解析
- 把文件存放在SDCard
- Android(安卓)decoder->decode returned false for Bitmap downl
- Android获取时间
- Android通过Xutils注解实例化以及事件绑定
- android9.0解决http获取异常