android视频截屏&手机录屏实现代码
程序员文章站
2023-11-21 17:53:28
本文介绍了android视频截屏&手机录屏实现代码,分享给大家,希望对大家有帮助
问题
在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下载
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。