全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

android视频截屏&手机录屏实现代码

本文介绍了android视频截屏&手机录屏实现代码,分享给大家,希望对大家有帮助

问题

在android中有时候我们需要对屏幕进行截屏操作,单一的截屏操作好解决可以通过activity的顶层view DecorView获取一个bitmap,得到就是当前activity上面的全部视图。

 View view = activity.getWindow().getDecorView();
    view.setDrawingCacheEnabled(true);
    view.buildDrawingCache();
    Bitmap bmp = view.getDrawingCache();
    DisplayMetrics dm = new DisplayMetrics();
    activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
    Bitmap ret = Bitmap.createBitmap(bmp, 0, 0, dm.widthPixels, dm.heightPixels);
    view.destroyDrawingCache();

如果activity中包含一些视频播放器比如SurfaceView GLSurfaceView TextureView,在调用截屏代码会发现播放视频的部分是黑屏的,原因是这几种视频渲染的view通过以上代码拿到的是缓冲区不是真正的图像。

解决办法

android5.0以上系统提供了一个 MediaProjectionManager类来对手机进行录屏操作,也支持获取手机的Image图像的操作,知道了这些我们就可以通过提供的api来进行截屏操作了。

这里通过Service来操作截屏和录屏的api

1.绑定截屏的Service

 Intent intent = new Intent(this, ScreenService.class);
 bindService(intent, mServiceConnection, BIND_AUTO_CREATE);

 public void onServiceConnected(ComponentName className, IBinder service) {
       DisplayMetrics metrics = new DisplayMetrics();
       getWindowManager().getDefaultDisplay().getMetrics(metrics);
       ScreenService.RecordBinder binder = (ScreenService.RecordBinder) service;
       recordService = binder.getRecordService();
       recordService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);
       mButton.setEnabled(true);
       mButton.setText(recordService.isRunning() ? "结束" : "开始");
 }

2.请求权限 onActivityResult 方法中回调。

 Intent captureIntent = projectionManager.createScreenCaptureIntent();
 startActivityForResult(captureIntent, RECORD_REQUEST_CODE);

成功后

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
     if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {

       //######## 截屏逻辑 ########
       mediaProjection = projectionManager.getMediaProjection(resultCode, data);
       recordService.setMediaProject(mediaProjection);
       recordService.initImageReader();

     }
 }

3. 获取截屏

 @Override
 public void onClick(View view) {

  //######## 截屏逻辑 ########
   Bitmap bitmap = recordService.getBitmap();
   mImageView.setImageBitmap(bitmap);
 }

录屏

录屏需要初始化一些录屏参数,输入麦克风类型视频类型,保存路径等

 private void initRecorder() {
     mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
     mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
     mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
     mediaRecorder.setOutputFile(
         getSavePath() + System.currentTimeMillis() + ".mp4");
     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();
     }
 }

开始录屏

mediaRecorder.start();

保存路径

完整Service代码

public class ScreenService extends Service {
private MediaRecorder mediaRecorder;
private VirtualDisplay virtualDisplay;
private boolean running;
private int width = 720;
private int height = 1080;
private int dpi;
private ImageReader mImageReader;
private MediaProjection mediaProjection;

 @Override
 public IBinder onBind(Intent intent) {
   return new RecordBinder();
 }


 @Override
 public void onCreate() {
   super.onCreate();
   running = false;
   mediaRecorder = new MediaRecorder();
 }


 @Override
 public int onStartCommand(Intent intent, int flags, int startId) {
   return super.onStartCommand(intent, flags, startId);
 }


 @Override
 public void onDestroy() {
   super.onDestroy();
 }


 public void setMediaProject(MediaProjection project) {
   mediaProjection = project;
 }


 public boolean isRunning() {
   return running;
 }


 public void setConfig(int width, int height, int dpi) {
   this.width = width;
   this.height = height;
   this.dpi = dpi;
 }


 /**
 * 开始录屏
 *
 * @return true
 */
 public boolean startRecord() {
   if (mediaProjection == null || running) {
     return false;
   }
   initRecorder();
   createVirtualDisplay();
   mediaRecorder.start();
   running = true;
   return true;
 }


 /**
 * 结束录屏
 *
 * @return true
 */
 public boolean stopRecord() {
   if (!running) {
     return false;
   }
   running = false;
   mediaRecorder.stop();
   mediaRecorder.reset();
   virtualDisplay.release();
   mediaProjection.stop();

   return true;
 }


 public void setMediaProjection(MediaProjection mediaProjection) {
   this.mediaProjection = mediaProjection;
 }


 /**
 * 初始化ImageRead参数
 */
 public void initImageReader() {
   if (mImageReader == null) {
     int maxImages = 2;
     mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, maxImages);
     createImageVirtualDisplay();
   }
 }


 /**
 * 创建一个录屏 Virtual
 */

 private void createVirtualDisplay() {
   virtualDisplay = mediaProjection
       .createVirtualDisplay("mediaprojection", width, height, dpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder
           .getSurface(), null, null);
 }


 /**
 * 创建一个ImageReader Virtual
 */
 private void createImageVirtualDisplay() {
   virtualDisplay = mediaProjection
       .createVirtualDisplay("mediaprojection", width, height, dpi,
           DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader
           .getSurface(), null, null);
 }


 /**
 * 初始化保存屏幕录像的参数
 */
 private void initRecorder() {
   mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
   mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
   mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
   mediaRecorder.setOutputFile(
       getSavePath() + System.currentTimeMillis() + ".mp4");
   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();
   }
 }


 /**
 * 获取一个保存屏幕录像的路径
 *
 * @return path
 */
 public String getSavePath() {
   if (Environment.getExternalStorageState()
          .equals(Environment.MEDIA_MOUNTED)) {
     String rootDir = Environment.getExternalStorageDirectory()
                   .getAbsolutePath() + "/" +
         "ScreenRecord" + "/";

     File file = new File(rootDir);
     if (!file.exists()) {
       if (!file.mkdirs()) {
         return null;
       }
     }
     return rootDir;
   } else {
     return null;
   }
 }


 /**
 * 请求完权限后马上获取有可能为null,可以通过判断is null来重复获取。
 */
 public Bitmap getBitmap() {
   Bitmap bitmap = cutoutFrame();
   if (bitmap == null) {
     getBitmap();
   }
   return bitmap;
 }


 /**
 * 通过底层来获取下一帧的图像
 *
 * @return bitmap
 */
 public Bitmap cutoutFrame() {
   Image image = mImageReader.acquireLatestImage();
   if (image == null) {
     return null;
   }
   int width = image.getWidth();
   int height = image.getHeight();
   final Image.Plane[] planes = image.getPlanes();
   final ByteBuffer buffer = planes[0].getBuffer();
   int pixelStride = planes[0].getPixelStride();
   int rowStride = planes[0].getRowStride();
   int rowPadding = rowStride - pixelStride * width;
   Bitmap bitmap = Bitmap.createBitmap(width +
       rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
   bitmap.copyPixelsFromBuffer(buffer);
   return Bitmap.createBitmap(bitmap, 0, 0, width, height);
 }


 public class RecordBinder extends Binder {
   public ScreenService getRecordService() {
     return ScreenService.this;
   }
 }

demo下载

github

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# android视频截屏  # android手机录屏  # android  # 截屏录屏  # Android实现截屏方式整理(总结)  # Android截屏保存png图片的实例代码  # android截屏功能实现代码  # 使用python编写android截屏脚本双击运行即可  # android实现手机截屏并保存截图功能  # Android 使用Shell脚本截屏并自动传到电脑上  # Android截屏SurfaceView黑屏问题的解决办法  # Android实现截屏并保存操作功能  # Android 屏幕截屏方法汇总  # Android实现截屏功能  # 可以通过  # 创建一个  # 的是  # 有可能  # 中有  # 作了  # 下一  # 给大家  # 几种  # 解决办法  # 绑定  # 作好  # 回调  # 大家多多  # 就可以  # 黑屏  # 知道了  # 视频播放器  # isRunning  # mButton 


相关文章: 网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  c# 在ASP.NET Core中管理和取消后台任务  如何解决ASP生成WAP建站中文乱码问题?  阿里云网站搭建费用解析:服务器价格与建站成本优化指南  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  网站图片在线制作软件,怎么在图片上做链接?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  如何用IIS7快速搭建并优化网站站点?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  如何选择适配移动端的WAP自助建站平台?  如何构建满足综合性能需求的优质建站方案?  建站主机解析:虚拟主机配置与服务器选择指南  C++用Dijkstra(迪杰斯特拉)算法求最短路径  如何在阿里云虚拟主机上快速搭建个人网站?  深圳企业网站制作设计,在深圳如何网上全流程注册公司?  小型网站制作HTML,*游戏网站怎么搭建?  高防服务器租用指南:配置选择与快速部署攻略  内部网站制作流程,如何建立公司内部网站?  油猴 教程,油猴搜脚本为什么会网页无法显示?  如何通过虚拟主机快速搭建个人网站?  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  如何用PHP工具快速搭建高效网站?  如何在阿里云服务器自主搭建网站?  西安专业网站制作公司有哪些,陕西省建行官方网站?  如何快速重置建站主机并恢复默认配置?  如何实现建站之星域名转发设置?  如何安全更换建站之星模板并保留数据?  韩国服务器如何优化跨境访问实现高效连接?  如何选择服务器才能高效搭建专属网站?  上海网站制作网页,上海本地的生活网站有哪些?最好包括生活的各个方面的?  在线流程图制作网站手机版,谁能推荐几个好的CG原画资源网站么?  网站规划与制作是什么,电子商务网站系统规划的内容及步骤是什么?  建站主机选择指南:服务器配置与SEO优化实战技巧  建站之星好吗?新手能否轻松上手建站?  建站之星伪静态规则如何设置?  怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?  css网站制作参考文献有哪些,易聊怎么注册?  安徽网站建设与外贸建站服务专业定制方案  建站之星收费标准详解:套餐费用及年费价格表一览  建站之星如何保障用户数据免受黑客入侵?  网站好制作吗知乎,网站开发好学吗?有什么技巧?  小型网站建站如何选择虚拟主机?  ,交易猫的商品怎么发布到网站上去?  建站之星后台密码遗忘如何找回?  子杰智能建站系统|零代码开发与AI生成SEO优化指南  网站网页制作专业公司,怎样制作自己的网页?  制作国外网站的软件,国外有哪些比较优质的网站推荐? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。