当前位置: 移动技术网 > 移动技术>移动开发>Android > android视频截屏&手机录屏实现代码

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文介绍了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下载


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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网