Android屏幕录制源码Demo下载
Android实现屏幕录制的方式介绍两种,第一种是通过adb shell命令,还一种使用SDK的提供的方法实现.
- adb shell 命令
语法: screenrecord [options] <filename>
Sample:adb shell screenrecord /sdcard/demo.mp4 开始录制(录制手机屏幕; 视频格式为mp4,存放到手机sd卡里,默认录制时间为180s)参数: --sizeadb shell screenrecord --size 1280*720 /sdcard/demo.mp4指定视频分辨率大小 (指定分辨率为1280*720;不指定则默认使用手机的分辨率,为获得最佳效果,请使用设备上的高级视频编码(AVC)支持的大小)参数: --bit-rateadb shell screenrecord --bit-rate 6000000 /sdcard/demo.mp4 指定视频的比特率 (指定视频的比特率为6Mbps; 如果不指定则默认为4Mbps, 你可以增加比特率以提高视频质量或为了让文件更小而降低比特率)参数: --time-limitadb shell screenrecord --time-limit 10 /sdcard/demo.mp4 限制录制时间 (限制视频录制时间为10s; 如果不限制,默认180s)参数: --verboseadb shell screenrecord --time-limit 10 --verbose /sdcard/demo.mp4在命令行显示录屏Log如下:xxxx:/ # screenrecord --time-limit 10 --verbose /sdcard/demo.mp4Main display is 1080x2160 @60.00fps (orientation=0)Configuring recorder for 1080x2160 video/avc at 4.00MbpsContent area is 1080x2160 at offset x=0 y=0Time limit reachedEncoder stopping; recorded 34 frames in 10 secondsStopping encoder and muxerExecuting: /system/bin/am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file:///sdcard/demo.mp4Broadcasting: Intent { act=android.intent.action.MEDIA_SCANNER_SCAN_FILE dat=file:///sdcard/demo.mp4 }Broadcast completed: result=0参数: --bugreport添加额外的信息,例如时间戳覆盖,这有助于捕获用于演示错误的视频参数: --help查看帮助导出视频:adb pull /sdcard/demo.mp4
如果在APP中使用,我们可以通过Process p = Runtime.getRuntime().exec(cmd)来调用shell命令.但是只有system app才能调用,可以在manifest节点中添加android:sharedUserId="android.uid.system"拥有系统级的权限
- 通过MediaProjection实现
1.动态申请录音和外部存储权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 10);}
2.获取屏幕录制的权限
MediaProjectionManager manager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);Intent intent = new Intent(manager.createScreenCaptureIntent());startActivityForResult(intent, REQUEST_CODE);
3.启动屏幕录制服务
Intent service = new Intent(this, ScreenRecordService.class);service.putExtra("resultCode", resultCode);service.putExtra("data", data);service.putExtra("mWidthPixels", mWidthPixels);service.putExtra("mHeightPixels", mHeightPixels);service.putExtra("mDensityDpi", mDensityDpi);startService(service);
屏幕录制服务
public class ScreenRecordService extends Service {private static final String TAG = "ScreenRecordService";private WindowManager mWindowManager;private WindowManager.LayoutParams wmParams;private LinearLayout mFloatLayout;private MediaProjection mMediaProjection;private MediaRecorder mMediaRecorder;private VirtualDisplay mVirtualDisplay;private boolean isScreenRecord;private int mScreenDensity, mWidthPixels, mHeightPixels;@Overridepublic IBinder onBind(Intent intent) {
// return new MyBinder();return null;}@Overridepublic void onCreate() {super.onCreate();initView();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {int resultCode = intent.getIntExtra("resultCode", -1);Intent data = intent.getParcelableExtra("data");mWidthPixels = intent.getIntExtra("mWidthPixels", 720);mHeightPixels = intent.getIntExtra("mHeightPixels", 1080);mScreenDensity = intent.getIntExtra("mDensityDpi", 1);Log.d(TAG, "initData --> mScreenDensity: " + mScreenDensity + " mWidthPixels: " + mWidthPixels + " mHeightPixels: " + mHeightPixels);mMediaProjection = ((MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE)).getMediaProjection(resultCode, data);return super.onStartCommand(intent, flags, startId);}private void startRecorder() {Log.d(TAG, "startRecord");isScreenRecord = true;createMediaRecorder();createVirtualDisplay(); // 在mediaRecorder.prepare() 之后调用,否则报错 failed to get surfacemMediaRecorder.start();}private void createVirtualDisplay() {mVirtualDisplay = mMediaProjection.createVirtualDisplay(TAG, mWidthPixels, mHeightPixels, mScreenDensity,DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder.getSurface(), null, null);}private void createMediaRecorder() {// 生成文件名SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");String curTime = formatter.format(new Date(System.currentTimeMillis()));mMediaRecorder = new MediaRecorder();//设置视频源: DEFAULT,Surface,CameramMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);//设置视频输出格式: amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gppmMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//设置视频编码格式: default, H263, H264, MPEG_4_SPmMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);// //设置音频源
// mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
//
// //设置音频编码格式: default,AAC,AMR_NB,AMR_WB
// mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);//设置视频尺寸大小mMediaRecorder.setVideoSize(mWidthPixels, mHeightPixels);//设置视频编码的码率mMediaRecorder.setVideoEncodingBitRate(5 * mWidthPixels * mHeightPixels); // mWidthPixels * mHeightPixels//设置视频编码的帧率mMediaRecorder.setVideoFrameRate(60); // 30//设置视频输出路径mMediaRecorder.setOutputFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/Ansen_" + curTime + ".mp4");try {mMediaRecorder.prepare();} catch (IOException e) {e.printStackTrace();Log.e(TAG, e.getMessage());}Log.d(TAG, "VideoSize: " + mWidthPixels + " X " + mHeightPixels + " VideoEncodingBitRate: "+ (5 * mWidthPixels * mHeightPixels) + " +VideoFrameRate: " + "60");}private void initView() {mWindowManager = (WindowManager) getApplication().getSystemService(getApplication().WINDOW_SERVICE);wmParams = new WindowManager.LayoutParams();wmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;// 设置window type为TYPE_SYSTEM_ALERTwmParams.format = PixelFormat.RGBA_8888;// 设置图片格式,效果为背景透明wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)wmParams.gravity = Gravity.LEFT | Gravity.TOP;// 默认位置:右下角wmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;wmParams.x = (ScreenUtils.getScreenWidth(getApplicationContext()) - wmParams.width) / 2;// 设置x、y初始值,相对于gravitywmParams.y = 10;// 浮动窗口布局mFloatLayout = (LinearLayout) LayoutInflater.from(getApplication()).inflate(R.layout.screen_recorder, null);mWindowManager.addView(mFloatLayout, wmParams);final LinearLayout screenrecord = (LinearLayout) mFloatLayout.findViewById(R.id.screenrecord);final TextView title = (TextView) mFloatLayout.findViewById(R.id.screenrecord_title);final TextView close = (TextView) mFloatLayout.findViewById(R.id.screenrecord_close);final ImageView image = (ImageView) mFloatLayout.findViewById(R.id.play_stop);mFloatLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));// 设置监听浮动窗口的触摸移动View.OnTouchListener mOnTouchListener = new View.OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {// getRawX是触摸位置相对于屏幕的坐标,getX是相对于按钮的坐标wmParams.x = (int) event.getRawX() - mFloatLayout.getMeasuredWidth() / 2;Log.i(TAG, "RawX" + event.getRawX() + " X" + event.getX());wmParams.y = (int) event.getRawY() - mFloatLayout.getMeasuredHeight() / 2 - 25;// 减25为状态栏的高度Log.i(TAG, "RawY" + event.getRawY() + " Y" + event.getY());mWindowManager.updateViewLayout(mFloatLayout, wmParams);// 刷新return false;}};mFloatLayout.setOnTouchListener(mOnTouchListener);screenrecord.setOnTouchListener(mOnTouchListener);screenrecord.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (isScreenRecord) {image.setImageResource(R.mipmap.screen_record_play);title.setText("开始");stopRecord();} else {image.setImageResource(R.mipmap.screen_record_stop);title.setText("停止");startRecorder();}}});close.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Log.d(TAG, "stopSelf");ScreenRecordService.this.stopSelf();}});}private void stopRecord() {Log.d(TAG, "stopRecord");isScreenRecord = false;mMediaRecorder.stop();mMediaRecorder.reset();}@Overridepublic void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy");if (isScreenRecord) {stopRecord();}mVirtualDisplay.release();mMediaProjection.stop();mWindowManager.removeView(mFloatLayout);}
}
代码地址
Android屏幕截图实现方式 & 系统截屏源码分析和三指截屏
Android长截屏(滚动截屏)实现原理
Android屏幕录制源码Demo下载相关推荐
- android实现阅读器底部菜单,android仿新闻阅读器菜单弹出效果实例(附源码DEMO下载)...
开发中碰到问题之后实现的,觉得可能有的开发者用的到或则希望独立成一个小功能DEMO,所以就放出来这么一个DEMO. 原本觉得是最后完成后发网站客户端的,可是这样体现不出一个功能一个功能的分析实现效果, ...
- 【转】Android 4.3源码的下载和编译环境的安装及编译
原文网址:http://jingyan.baidu.com/article/c85b7a641200e0003bac95a3.html 告诉windows用户一个不好的消息,windows环境下没法 ...
- Android源码编译详解【四】:Android 6.0_源码的下载与编译
1.AOSP源码下载 AOSP:即为"Android Open-Source Project"的缩写,中文意为 :"安卓开放源代码项目". Google官方 ...
- Android屏幕刷新——源码分析
Android屏幕刷新原理--源码分析 文章目录 Android屏幕刷新原理--源码分析 概述 VSync信号 三级缓冲 源码分析 消息队列的同步屏障 参考资料 概述 Android系统每16ms(一 ...
- 【LeanEAP.NET】精益企业应用平台---源码Demo下载
这个框架开发了很长时间,但是一个人开发,Demo和文档还不完善,现在把源代码上传上来,如果你有兴趣有时间并且了解框架开发,想为这个框架做点贡献,欢迎加入.如果你有项目外包也欢迎联系我. 下一步开发计划 ...
- K近邻算法讲解与python实现(附源码demo下载链接)
k近邻算法概述 对应demo源码及数据:传送门 K近邻(k-Nearest Neighbor,简称kNN)算法,是一种应用很广泛的监督学习算法.它非常有效且易于掌握,其工作机制也很简单:给定测试样本, ...
- android+锁屏代码+下载,安卓客户端开发的锁屏源码demo下载,可直接应用到APP中
安卓程序锁屏 好多安卓APP中都用到锁屏技术在这里只是一个Demo 但是可以直接运用到已经做好的APP中,在绘制锁屏中用到许多的Math函数. package com.weiqiang.lockpoi ...
- asp源码demo下载:微信公众号支付企业付款到零钱功能asp源码下载案例
最近接到一个开发需求,一个企业想用微信支付里面的,企业付款到零钱功能,利用此功能来给用会发红包,因为微信支付里的红包功能一次要付款1块钱,太多,所以他想利用此功能来发红包,这样红包金额可以低到每次3角 ...
- android与html注册登录,Android登录注册源码
Android登录注册源码 资源下载此资源下载价格为2D币,请先登录 资源文件列表 andoird96pk/.classpath , 348 andoird96pk/.project , 847 an ...
最新文章
- 初探linux内核编程,参数传递以及模块间函数调用
- python要学多久-零基础python培训需要学多久?
- Storm-源码分析-Stats (backtype.storm.stats)
- 计算机组成原理课程设计a,计算机组成原理课程设计报告.doc
- java 拦截jsp页面_JSP 过滤器
- 个人主页 — github + jekyll 搭建自己的个人主页
- Android万能布局检查器UI Automator Viewer使用教程、环境配置和Mac无法打开问题解决(uiautomatorviewer,android studio,layer,查看,错误)
- 根轨迹法和频率响应法设计PI控制器学习笔记
- letsencrypt证书-管理工具certbot
- form表单提交方式
- 【转载收藏】Unity预计算实时GI
- 后台管理系统 权限管理
- 手机品牌是否一定要自研芯片
- android跨应用调用方法是,Android如何实现不同应用之间的调用
- Sketch for UX Design Sketch UX设计教程 Lynda课程中文字幕
- 黑马程序员——阿龙的学习历程——Java初见
- 串口硬盘和并口硬盘的区别
- 码一些有用的东西网站的域名被拦截怎么办? 教你快速解除各种拦截
- OpenCV——LCC(Local Color Correction)的Python复现
- 加法器的实现(半加器,全加器,行波进位加法器,超前进位加法器,流水线加法器)