Android Lollipop (5.0) 屏幕录制实现
2016-07-12 16:48
477 查看
引言
网上很多关于 Android 录屏的解决方案是通过读取/dev/graphics/fb0里面的 frame buffer,然后再通过各种开源编码器转为视频,但必须要
root才行,而且有些手机即便你
root还是不能成功,获取到的 framebuffer 全是 0, 所以不是一个很好的解决方案。从 Android 4.4 Google 引入了通过
adb命令录屏的功能,需要通过 USB 调试连接到 PC,运行
adb shell screenrecord /sdcard/xxxx.mp4开始录屏,并且录屏限制时长最长 3 分钟。Android 5.0 引入
MediaProject,可以不需要
adb,也不用
root就可以录屏,但需要弹权限获取窗口,需要用户允许才行,这里主要介绍 Android 5.0+ 利用
MediaProject在非
root情况下实现屏幕录制。转载请注明出处:单刀土豆
基本原理
在 Android 5.0,Google 终于开放了视频录制的接口,其实严格来说,是屏幕采集的接口,也就是MediaProjection和
MediaProjectionManager。
具体实现步骤
1 申请权限
在 AndroidManifest 中添加权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/>
Android 6.0 加入的动态权限申请,如果应用的
targetSdkVersion是 23,申请敏感权限还需要动态申请
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_REQUEST_CODE); } if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.RECORD_AUDIO}, AUDIO_REQUEST_CODE); }
2 获取 MediaProjectionManager 实例
MediaProjectionManager也是系统服务的一种,通过
getSystemService来获取实例
MediaProjectionManager projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
3 发起屏幕捕捉请求
Intent captureIntent= projectionManager.createScreenCaptureIntent(); startActivityForResult(captureIntent, REQUEST_CODE);
4 获取 MediaProjection
通过onActivityResult返回结果获取
MediaProjection
protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) { mediaProjection = projectionManager.getMediaProjection(resultCode, data); } }
5 创建虚拟屏幕
这一步就是通过MediaProject录制屏幕的关键所在,
VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR参数是指创建屏幕镜像,所以我们实际录制内容的是屏幕镜像,但内容和实际屏幕是一样的,并且这里我们把
VirtualDisplay的渲染目标 Surface 设置为
MediaRecorder的
getSurface,后面我就可以通过
MediaRecorder将屏幕内容录制下来,并且存成 video 文件
private void createVirtualDisplay() { virtualDisplay = mediaProjection.createVirtualDisplay( "MainScreen", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null); }
6 录制屏幕数据
这里利用MediaRecord将屏幕内容保存下来,当然也可以利用其它方式保存屏幕内容,例如:
ImageReader
private void initRecorder() { File file = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".mp4"); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mediaRecorder.setOutputFile(file.getAbsolutePath()); mediaRecorder.setVideoSize(width, height); mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024); mediaRecorder.setVideoFrameRate(30); try { mediaRecorder.prepare(); } catch (IOException e) { e.printStackTrace(); } } public boolean startRecord() { if (mediaProjection == null || running) { return false; } initRecorder(); createVirtualDisplay(); mediaRecorder.start(); running = true; return true; }
源码地址
完整代码地址文/单刀土豆(简书作者)
原文链接:http://www.jianshu.com/p/e9a9771eb7b8
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
相关文章推荐
- Android 百分比布局揭秘
- Android NDK(二)最最简单的方法利用NDK实现MP3录音
- Android Studio 复制粘贴图片到drawable文件夹没有效果 - 解决方法
- Android HandlerThread 完全解析
- Android获取屏幕高度
- Android散打之ScrollView
- Android自定义控件:仿美团下拉菜单及相关代码优化
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- android属性动画与补间动画的区别及用法
- 2K&4K高清播放时代的主流
- Android设置点击可变图片按钮
- android之服务
- [置顶] MPAndroidChart开源图表库,柱状图和折线图CombinedChart
- 读《疯狂Android讲义》之Service运用总结
- Android 中使用Lambda表达式
- Android Studio安装后第一次进不去
- Qt for android QML无法运行问题处理
- Android :Activity中finish() onDestroy() 和System.exit()的区别
- 我的Android进阶之旅------>Java全角半角的转换方法
- 华为手机打开log日志的方法[Android]