时间:2021-05-20
本文介绍了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);成功后
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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
IOS开发之ios视频截屏的实现代码现在好多视频截屏软件,这里提供一个IOS视频截屏的方法,大家可以参考下,实现代码:?12345678910111213141
Android实现截屏功能的实例实现代码:publicclassScreenShot{//获取指定Activity的截屏,保存到png文件privatestat
大家都知道,手机截屏功能想必很多人都用过,但实际上手机还有一个录屏功能,主要是在我们需要截取连贯的长屏或者视频的时候使用,相比截屏功能,录屏功能更全面也更强大,
Android下调试手机截屏的方法Android开发过程中,难免会需要对手机进行截屏。以前截屏时一直到处找截屏软件,操作复杂。今天刚发现,原来ADT是自带截屏功
本文介绍了Android实现截屏方式整理,分享给大家。希望对大家有帮助可能的需求:截自己的屏截所有的屏带导航栏截屏不带导航栏截屏截屏并编辑选取一