|
| 1 | +# MediaUtils |
| 2 | + |
| 3 | +A demo of record audio and video about Android |
| 4 | + |
| 5 | +一个在 Android 上实现录像和录音功能的小例子。 |
| 6 | + |
| 7 | +GitHub 地址:[https://github.com/Werb/MediaUtils](https://github.com/Werb/MediaUtils) |
| 8 | + |
| 9 | +[](https://fir.im/cbas) 也可直接点击下载体验 |
| 10 | + |
| 11 | +* Android 的 MediaRecorder 相信用过的同学一定踩过很多坑 |
| 12 | +* 之前写的代码很乱,现在重构了一下,可以直接放到自己的项目中用 |
| 13 | +* 本例子将 MediaRecorder 进行了重构,通过 MediaUtils 对外暴露几个必需的方法来实现录像和录音功能 |
| 14 | +* 录制视频界面参考新版微信小视频,还原了微信的动画效果 |
| 15 | +* 支持 Android 7.0 |
| 16 | +* 通过线程及 Exception 等手段避免了常见的 start failed , stop failed 等问题 |
| 17 | +* 重绘了录制视频和录音时的两个自定义view,可在原本基础上进行二次开发 |
| 18 | +* 提供了视频截图方法,支持双击放大,支持自动对焦 |
| 19 | +* 视频录制暂时使用 SurfaceView + Camera , 后续会升级为 TextureView + Camera2 |
| 20 | + |
| 21 | +### 效果图 |
| 22 | + |
| 23 | +<!-- <img src="/screenshots/video.gif" alt="screenshot" title="home" width="360" height="640" /> |
| 24 | +<img src="/screenshots/audio.gif" alt="screenshot" title="home" width="360" height="640" /> --> |
| 25 | + |
| 26 | +### 核心类 |
| 27 | +#### MediaUtils |
| 28 | + |
| 29 | +* 重构后对外暴露只有8行代码,可结合实际情况使用 |
| 30 | +``` |
| 31 | + // 初始化 |
| 32 | + MediaUtils mediaUtils = new MediaUtils(this); |
| 33 | + mediaUtils.setRecorderType(MediaUtils.MEDIA_VIDEO); |
| 34 | + mediaUtils.setTargetDir(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)); |
| 35 | + mediaUtils.setTargetName(UUID.randomUUID() + ".mp4"); |
| 36 | + mediaUtils.setSurfaceView(surfaceView); |
| 37 | + // 开始录制 |
| 38 | + mediaUtils.record() |
| 39 | + // 结束录制 save or unSave |
| 40 | + mediaUtils.stopRecordUnSave(); |
| 41 | + mediaUtils.stopRecordSave(); |
| 42 | +``` |
| 43 | + |
| 44 | +#### CameraHelper |
| 45 | +* 在 Android 中录制视频时显示的 Size 和实际拍照的 Size 是由 Camera 所决定的,最好的方法是计算出可支持的 PreviewSize 和 VideoSize 计算出一个合适的size,同时根据自己视频的用途,选择合理的 Size |
| 46 | +* CameraHelper 参考自 GoogleCameraSample 帮助你计算出合适的 Size |
| 47 | +``` |
| 48 | + public static Camera.Size getOptimalVideoSize(List<Camera.Size> supportedVideoSizes, |
| 49 | + List<Camera.Size> previewSizes, int w, int h) { |
| 50 | + final double ASPECT_TOLERANCE = 0.1; |
| 51 | + double targetRatio = (double) w / h; |
| 52 | + // sizes |
| 53 | + List<Camera.Size> videoSizes; |
| 54 | + if (supportedVideoSizes != null) { |
| 55 | + videoSizes = supportedVideoSizes; |
| 56 | + } else { |
| 57 | + videoSizes = previewSizes; |
| 58 | + } |
| 59 | + Camera.Size optimalSize = null; |
| 60 | + // Start with max value and refine as we iterate over available video sizes. This is the |
| 61 | + // minimum difference between view and camera height. |
| 62 | + double minDiff = Double.MAX_VALUE; |
| 63 | + // Target view height |
| 64 | + int targetHeight = h; |
| 65 | + // Try to find a video size that matches aspect ratio and the target view size. |
| 66 | + // Iterate over all available sizes and pick the largest size that can fit in the view and |
| 67 | + // still maintain the aspect ratio. |
| 68 | + for (Camera.Size size : videoSizes) { |
| 69 | + double ratio = (double) size.width / size.height; |
| 70 | + if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) |
| 71 | + continue; |
| 72 | + if (Math.abs(size.height - targetHeight) < minDiff && previewSizes.contains(size)) { |
| 73 | + optimalSize = size; |
| 74 | + minDiff = Math.abs(size.height - targetHeight); |
| 75 | + } |
| 76 | + } |
| 77 | + // Cannot find video size that matches the aspect ratio, ignore the requirement |
| 78 | + if (optimalSize == null) { |
| 79 | + minDiff = Double.MAX_VALUE; |
| 80 | + for (Camera.Size size : videoSizes) { |
| 81 | + if (Math.abs(size.height - targetHeight) < minDiff && previewSizes.contains(size)) { |
| 82 | + optimalSize = size; |
| 83 | + minDiff = Math.abs(size.height - targetHeight); |
| 84 | + } |
| 85 | + } |
| 86 | + } |
| 87 | + return optimalSize; |
| 88 | + } |
| 89 | +``` |
| 90 | + |
| 91 | +#### 自定义View |
| 92 | +* 仿造新版微信拍摄视频的界面,通过 Paint,RectF,Canvas 绘制 |
| 93 | +* 突然喜欢上了在 Android 画动效,开启 dribbble 抄动效模式 |
| 94 | + |
| 95 | +好了,知识虽小但五脏俱全 |
| 96 | + |
| 97 | +欢迎使用我自己开源的一个 Android 图片选择器 |
| 98 | +* 【PickPhotoView】 Github 地址:[https://github.com/Werb/PickPhotoSample](https://github.com/Werb/PickPhotoSample) |
| 99 | + |
| 100 | +项目中关于 Android M的权限检查用到了,我的另外一个库 |
| 101 | +* 【PermissionsChecker】Github 地址 :[https://github.com/Werb/PermissionsCheckerSample](https://github.com/Werb/PermissionsCheckerSample) |
| 102 | + |
| 103 | + |
| 104 | + |
| 105 | +### 很高兴你看到这里 |
| 106 | + |
| 107 | +> 有时候啊 你总是在追赶前面的人 |
| 108 | +
|
| 109 | +> 总是抱怨自己为什么不能再努力一点 |
| 110 | +
|
| 111 | +>累了你可以停下来 看看原来的自己 |
| 112 | +
|
| 113 | +>其实你已经很了不起了。 |
| 114 | +
|
| 115 | +我是 wanbo 。 |
0 commit comments