安卓录屏

来源:互联网 发布:c语言写学生管理系统 编辑:程序博客网 时间:2024/05/22 15:24

转载自http://www.jianshu.com/p/e9a9771eb7b8

引言

网上很多关于 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 终于开放了视频录制的接口,其实严格来说,是屏幕采集的接口,也就是 MediaProjectionMediaProjectionManager

具体实现步骤

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 设置为 MediaRecordergetSurface,后面我就可以通过 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;}

源码地址

https://github.com/GLGJing/ScreenRecorder

作者:单刀土豆
链接:http://www.jianshu.com/p/e9a9771eb7b8
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。