# AndroidShow **Repository Path**: wangwang2020/AndroidShow ## Basic Information - **Project Name**: AndroidShow - **Description**: 通过MediaProjectionManager采集android屏幕视频流,app中搭建简单rtsp server与客户端通信,通过rtp 协议传输视频流,vlc等客户端来观看手机的屏幕实时视频 - **Primary Language**: Android - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 5 - **Forks**: 0 - **Created**: 2022-11-08 - **Last Updated**: 2024-12-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # AndroidShow 通过MediaProjectionManager采集android屏幕视频流,app中搭建简单rtsp server与客户端通信,通过rtp 协议传输视频流,vlc等客户端来观看手机的屏幕实时视频 # 使用方法 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 ```java //开始截屏 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 ```java @Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ try { MediaProjection mediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data); } catch (Exception e){ } } ``` * 初始化 MediaCodec,获取 Surface 对象 ```java 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 对象 ```java 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](https://github.com/sszhangpengfei/MediaCodecEncodeH264) 或者参考我之前的博客内容:[android 编码 h264(二):MediaCodec 硬编码 h264(硬编码)](http://blog.csdn.net/ss182172633/article/details/50256733) ```java 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 流媒体的方式,将屏幕内容来实时的演示,目前项目才开始,代码会慢慢提交的。** # 参考资料 [原文android通过MediaProjectionManager录屏关联](https://blog.csdn.net/ss182172633/article/details/79480853)