MediaProjection实现截图,与MediaMuxer实现录屏为MP4,Gif格式
来源:互联网 发布:音乐软件下载 编辑:程序博客网 时间:2024/05/21 14:06
文/小码哥_WS
博客地址:http://my.csdn.net/King1425
MediaProjection可以用来捕捉屏幕,具体来说可以截取当前屏幕和录制屏幕视频 (5.0以上)
先总结下系统是如何实现组合键截屏的:
都应该知道Android源码中对按键的捕获位于文件PhoneWindowManager.Java中
当满足按键条件时会用一个mHandler 开始post一个runnable,进入这个runnable中执行takeScreenshot()方法。
使用AIDL绑定了service服务到”com.android.systemui.screenshot.TakeScreenshotService”,注意在service连接成功时,对message的msg.arg1和msg.arg2两个参数的赋值。其中在mScreenshotTimeout中对服务service做了超时处理。接着我们找到实现这个服务service的类TakeScreenshotService,该类在(frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot包下
引用SurfaceControl类,调用了screenshot方法, 传入了屏幕的宽和高,这两个参数,接着进入SurfaceControl类中,位于frameworks/base/core/java/android/view目录下
最终到达native方法中nativeScreenshot
面就是java层的部分,接着到jni层,在\frameworks\base\core\jni\android_view_SurfaceControl.cpp中
到jni中,映射nativeScreenshot方法的是nativeScreenshotBitmap函数
最后辗转来到c++层,就是\frameworks\native\libs\gui下的SurfaceComposerClient.cpp中,实现ScreenshotClient声明的函数update
当进入到CAPTURE_SCREEN中,data会读取IGraphicBufferProducer生成出的图像buffe,接着调用 reply->writeInt32(res);返回给client.然后再回调到java层。以上就是系统截屏的原理。
那对于多媒体这块可以通过MediaProjection来实现截屏
实现思路:
首先获取MediaProjectionManager,和其他的Manager一样通过 Context.getSystemService() 传入参数MEDIA_PROJECTION_SERVICE获得实例。
接着调用MediaProjectionManager.createScreenCaptureIntent()弹出dialog询问用户是否授权应用捕捉屏幕,同时覆写onActivityResult()获取授权结果。
如果授权成功,通过MediaProjectionManager.getMediaProjection(int resultCode, Intent resultData)获取MediaProjection实例,通过MediaProjection.createVirtualDisplay(String name, int width, int height, int dpi, int flags, Surface surface, VirtualDisplay.Callback callback, Handler handler)创建VirtualDisplay实例。实际上在上述方法中传入的surface参数,是真正用来截屏或者录屏的。
截屏
截屏这里用到ImageReader类,这个类的getSurface()方法获取到surface直接传入MediaProjection.createVirtualDisplay()方法中,此时就可以执行截取。通过ImageReader.acquireLatestImage()方法即可获取当前屏幕的Image,经过简单处理之后即可保存为Bitmap。
录屏1 mp4
主体思路:
逻辑:录屏不需要操作视频原始数据,因此使用InputSurface作为编码器的输入。
视频:MediaProjection通过createVirtualDisplay创建的VirtualDisplay获取当前屏幕的数据。然后传入到MediaCodec中(即传入的Surface是通过MediaCodec的createInputSurface方法返回的),然后MediaCodec对数据进行编码,于是只需要在MediaCodec的输出缓冲区中拿到编码后的ByteBuffer即可。
简单说就是重定向了屏幕录制的数据的方向,这个Surface提供的是什么,录制的视频数据就传到哪里。Surface提供的是本地某个SurfaceView控件,那么就会将屏幕内容显示到这个控件上,提供MediaCodec就是作为编码器的输入源最终获得编码后的数据,提供ImageReader就会作为ImageReader的数据源,最终获得了视频的原始数据流。
音频:录制程序获得音频原始数据PCM,传给MediaCodec编码,然后从MediaCodec的输出缓冲区拿到编码后的ByteBuffer即可。
最终通过合并模块MediaMuxer将音视频混合。
小结
录屏需要用到MediaCadec,这个类将原始的屏幕数据编码,在通过MediaMuxer分装为mp4格式保存。MediaCodec.createInputSurface()获取一个surface对象,传入
MediaProjection.createVirtualDisplay()即可获取屏幕原始多媒体数据.之后读取MediaCodec编码输出数据经过MediaMuxer封装处理为mp4即可播放,实现录屏。
录屏2 Gif
由于录制的是视频,得变成gif,有两种方案:
● 提取视频文件->解析视频->提取 Bitmap 序列(使用 MediaMetadataRetriever 提取某一时刻的图片,然后把很多某一时刻的图片串联起来编码成 gif。看来其也正是 gif 的原理,但实现出来的效果极差,无法准确提取到准确的图片,导致合成的 gif 图也无法连贯播放,播放起来也跳帧跳得很厉害。惨不忍睹)
● 利用FFmpeg直接转gif, 这种方法岗岗的。
之前我们演示过:
windows下编译最新版ffmpeg3.3-android,并通过CMake方式移植到Android studio2.3中 :http://blog.csdn.net/king1425/article/details/70338674
调用相关命令也可通过Jni实现。
github:https://github.com/WangShuo1143368701/VideoView/tree/master/mediaprojectionmediamuxer
一命二运三风水,四修阴德五读书!
刘桂林
微信号 : Android_LiuGuiLin
新浪微博:@刘某人程序员
- MediaProjection实现截图,与MediaMuxer实现录屏为MP4,Gif格式
- Android Multimedia实战(四)MediaProjection实现截图,与MediaMuxer实现录屏为MP4,Gif格式
- MediaProjection与MediaRecorder实现录屏
- Android MediaProjection截屏与录屏(surfaceview截图)
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
- Android5.0以上使用MediaProjection截图和录屏
- Android5.0以上使用MediaProjection截图和录屏
- Android MediaProjection 录屏
- Android MediaProjection 录屏
- Android实现全局截图以及录屏
- Android实现录屏直播(三)MediaProjection + VirtualDisplay + librtmp + MediaCodec实现视频编码并推流到rtmp服务器
- ffmpeg开发之旅(3):AAC编码格式分析与MP4文件封装(MediaCodec+MediaMuxer)
- ffmpeg开发之旅(3):AAC编码格式分析与MP4文件封装(MediaCodec+MediaMuxer)
- python实现将m3u8格式转换为mp4视频格式
- Android 之 Notification 必须掌握的知识
- Android 开发之 Kotlin 初始篇
- 高仿QQ空间广告位 ——— 一个位置来回切换两张广告图
- 自定义FlexibleLayout动态加载页面布局实现标题与内容分离
- 巧用第三方快速开发Android App 热门第三方SDK及框架
- MediaProjection实现截图,与MediaMuxer实现录屏为MP4,Gif格式
- Android打造不一样的圆盘签到
- 关于IE8和IE8以上加载CSS文件时的不能加载全的问题
- FloatingActionButton实现 展开/折叠 的多级悬浮菜单
- 自定义FlexibleLayout动态加载页面布局实现title与content分离
- 公开课 | 佐治亚理工大学宋乐教授:用Structure2Vec提取特征,解决网络数据的表征学习问题
- 用神经网络续写《权力的游戏》,这个脑洞有点大(附完整小说下载)
- 太上感应篇0036
- 022:第二章 导数的定义