1 Star 4 Fork 0

周旺旺 / AndroidShow

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
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

	//开始截屏
    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 流媒体的方式,将屏幕内容来实时的演示,目前项目才开始,代码会慢慢提交的。

参考资料

原文android通过MediaProjectionManager录屏关联

空文件

简介

通过MediaProjectionManager采集android屏幕视频流,app中搭建简单rtsp server与客户端通信,通过rtp 协议传输视频流,vlc等客户端来观看手机的屏幕实时视频 展开 收起
Android
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Android
1
https://gitee.com/wangwang2020/AndroidShow.git
git@gitee.com:wangwang2020/AndroidShow.git
wangwang2020
AndroidShow
AndroidShow
master

搜索帮助