自己实现了Android的屏幕录制App。

用了MediaProjection类来作为源,MediaRecoder来捕捉,编码转换为本地视频。

效果图:

主要是这段代码开始录像:

startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);//开始录像

录像结束后在回调函数中处理:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data); if (requestCode != REQUEST_CODE) {
Log.e(TAG, "Unknown request code: " + requestCode);
return;
}
if (resultCode != RESULT_OK) {
Toast.makeText(this,
"Screen Cast Permission Denied", Toast.LENGTH_SHORT).show();
mToggleButton.setChecked(false);
return;
}
  //应用最小化 后台运行
  Intent intent = new Intent(Intent.ACTION_MAIN);
  intent.addCategory(Intent.CATEGORY_HOME);
  intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  startActivity(intent); mMediaProjectionCallback = new MediaProjectionCallback();//回调类
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
mMediaProjection.registerCallback(mMediaProjectionCallback, null);//注册回调类
mVirtualDisplay = createVirtualDisplay();
mMediaRecorder.start();
}

回调处理的事情其实就是将录像的类全都关闭释放:

private class MediaProjectionCallback extends MediaProjection.Callback {
@Override
public void onStop() {
if (mToggleButton.isChecked()) {
mToggleButton.setChecked(false);
mMediaRecorder.stop();
mMediaRecorder.reset();
Log.v(TAG, "Recording Stopped");
}
mMediaProjection = null;
stopScreenSharing();
}
}

createVirtualDisplay()是我们自己定义的

/*
参数说明:
* 第一个参数:虚拟画面名称
* 第二个参数:虚拟画面的宽度
* 第三个参数:虚拟画面的高度
* 第四个参数:虚拟画面的标志
* 第五个参数:虚拟画面输出的Surface
* 第六个参数:虚拟画面回调接口
其中最重要的就是第五个参数,录制画面输出的地方,他这里介绍的是一个Surface类型,那么我们如果想操作录制之后的视频数据,就需要创建一个Surface类型即可。
1、如果想截屏,那么可以使用ImageReader类的getSurface方法获取
2、如果想录制视频进行编码,可以使用MediaRecorder类的getSurface方法获取
*/
    private VirtualDisplay createVirtualDisplay() {
return mMediaProjection.createVirtualDisplay("MainActivity",
DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
/*surface是mediaRecorder的,以mediaprojection为源输出到surface,捕获*/
mMediaRecorder.getSurface(), null /*Callbacks*/, null
/*Handler*/);
}

弄完之后我们跳到另一个Activity,显示录制完的视频的缩略图,并添加分享播放和重新录制功能。

显示视频缩略图:

public Bitmap getVideoThumbnail(String filePath) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(filePath);
bitmap = retriever.getFrameAtTime();
}
catch(IllegalArgumentException e) {
e.printStackTrace();
}
catch (RuntimeException e) {
e.printStackTrace();
}
finally {
try {
retriever.release();
}
catch (RuntimeException e) {
e.printStackTrace();
}
}
return bitmap;
}

播放:

                Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);//主要是这里指定了ACTION File vedioFile = new File(Environment
.getExternalStoragePublicDirectory(Environment
.DIRECTORY_DOWNLOADS), "/video.mp4");
Uri uri = Uri.parse(vedioFile.getAbsolutePath());
intent.setDataAndType(uri,"video/*");
startActivity(intent);

分享:

               Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND); shareIntent.setType("audio/*"); File vedioFile = new File(Environment
.getExternalStoragePublicDirectory(Environment
.DIRECTORY_DOWNLOADS), "/video.mp4"); shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(vedioFile)); //设置分享列表的标题,并且每次都显示分享列表
startActivity(Intent.createChooser(shareIntent, "分享到"));

最新文章

  1. JTabbedPane 和 JScrollBar 联合使用
  2. 关于shell脚本时遇value too great for base (error token is "08")
  3. SpringHttpInvoker解析2-服务端实现
  4. linux之"server" directive is not allowed here in
  5. java基础九[网络与线程](阅读Head First Java记录)
  6. C语言实现冒泡排序-整数排序
  7. javascript去掉字符串前后空格
  8. 【C++面试】常考题复习:排序算法
  9. python 二分法查找
  10. Linux cat命令详解
  11. Maven构建SSM架构,并分离层次,使用Maven 组织多项目
  12. Android中弹出对话框,AlertDialog关键代码
  13. C/S通信模型和相关技术要点
  14. 网页弹出窗口工具推荐之jqmodal
  15. Angular企业级开发(8)-控制器的作用域
  16. Python:strip 函数踩坑
  17. 想了解SAW,BAW,FBAR滤波器的原理?看这篇就够了!
  18. activemq stomp类
  19. Linux 中如何避免 rm -rf /*
  20. bzoj 3631 松鼠的新家 (树链剖分)

热门文章

  1. django' 前端 self.status.split(' ',1)[0], self.bytes_sent AttributeError: 'NoneType' object has no attribute 'split'
  2. C++_新特性1-类型转换运算符
  3. rest-assured之静态导入及简单使用实例
  4. 【算法笔记】B1008 数组元素循环右移问题
  5. vuex的小疑问记录
  6. 微信小程序 template模板使用
  7. [转] Android:用GSON 五招之内搞定任何JSON数组
  8. [转] Mysql命令基础
  9. 正确优雅地解决用户退出——JSP及Struts解决方案
  10. if __name__ == '__main__' 详解