因为在项目中经常需要使用音视频录制,所以写了一个公共库RecorderManager,欢迎大家使用。

最新0.4.0-beta.5版本:
1.升级依赖
2.移除EasyPermissions和废弃方法,使用新API registerForActivityResult,请采用Java1.8以上版本
3.重构框架,优化代码
4.库调用做部分调整,详见下方文档说明
5.欢迎大家测试反馈完善功能

0.3.2版本:1.移除strings.xml中app_name
2.升级kotlin

0.3.1版本更新:详情见文档
1.新增最小录制时间设置RecordVideoOption.setMinDuration(//最小录制时长(秒数,最小是1,会自动调整不大于最大录制时长))
2.优化代码

0.3-beta.2版本更新:
1.重构项目代码,kotlin改写部分功能
2.移除rxjava库,减少依赖
3.升级最新SDK
4.新增闪光灯功能,增加计时前提示文本设置
5.增加国际化支持,英文和中文
6.修复已知问题,优化代码
7.对外用户调用API改动较少,主要为内部调整,见下方文档,欢迎大家测试反馈完善功能

0.2.29版本更新:
1.新增圆形进度按钮配置功能
2.新增指定前后置摄像头功能
3.优化代码,调整启动视频录制配置项

0.2.28版本更新:
1.优化视频录制结果获取方式
2.优化代码

0.2.27版本更新:
1.视频录制界面RecordVideoRequestOption新增RecorderOption和hideFlipCameraButton配置
2.优化代码

0.2.26版本更新:
1.项目迁移至AndroidX, 引入Kotlin

0.2.25版本更新:
1.优化权限自动申请,可自动调起视频录制界面
2.规范图片资源命名

一.效果展示

仿微信界面视频录制


2.音频录制界面比较简单,就不放图了

二.引用

1.Add it in your root build.gradle at the end of repositories

allprojects {repositories {...maven { url 'https://jitpack.io' }}}

2.Add the dependency

dependencies {implementation 'com.github.MingYueChunQiu:RecorderManager:0.3.2'}

三.使用

1.音频录制

采用默认配置录制

mRecorderManager.recordAudio(mFilePath);

自定义配置参数录制

mRecorderManager.recordAudio(new RecorderOption.Builder().setAudioSource(MediaRecorder.AudioSource.MIC).setOutputFormat(MediaRecorder.OutputFormat.MPEG_4).setAudioEncoder(MediaRecorder.AudioEncoder.AAC).setAudioSamplingRate(44100).setBitRate(96000).setFilePath(path).build());

2.视频录制

(1).可以直接使用RecordVideoActivity,实现了仿微信风格的录制界面

从0.2.18开始改为类似

RecorderManagerFactory.getRecordVideoRequest().startRecordVideo(MainActivity.this, 0);

从0.4.0-beta版本开始,因为采用registerForActivityResult,所以直接传入结果回调

      RecorderManagerProvider.getRecordVideoRequester().startRecordVideo(MainActivity.this, new RMRecordVideoResultCallback() {@Overridepublic void onResponseRecordVideoResult(@NonNull RecordVideoResultInfo info) {Log.e("MainActivity", "onActivityResult: " + info.getDuration() + " " + info.getFilePath());Toast.makeText(MainActivity.this, info.getDuration() + " " + info.getFilePath(), Toast.LENGTH_SHORT).show();}@Overridepublic void onFailure(@NonNull RecorderManagerException e) {Log.e("MainActivity", "onActivityResult: " + e.getErrorCode() + " " + e.getMessage());}});

从0.4.0-beta版本开始:RecorderManagerFactory重命名为RecorderManagerProvider
RecorderManagerFactory中可以拿到IRecordVideoPageRequester,在IRecordVideoPageRequester接口中

/*** 以默认配置打开录制视频界面** @param activity    Activity* @param requestCode 请求码*/void startRecordVideo(@NonNull FragmentActivity activity, int requestCode);/*** 以默认配置打开录制视频界面** @param fragment    Fragment* @param requestCode 请求码*/void startRecordVideo(@NonNull Fragment fragment, int requestCode);/*** 打开录制视频界面** @param activity    Activity* @param requestCode 请求码* @param option      视频录制请求配置信息类*/void startRecordVideo(@NonNull FragmentActivity activity, int requestCode, @Nullable RecordVideoRequestOption option);/*** 打开录制视频界面** @param fragment    Fragment* @param requestCode 请求码* @param option      视频录制请求配置信息类*/void startRecordVideo(@NonNull Fragment fragment, int requestCode, @Nullable RecordVideoRequestOption option);

从0.4.0-beta版本开始:

public interface IRecordVideoPageRequester extends IRMRequester {/*** 以默认配置打开录制视频界面** @param activity Activity* @param callback 视频录制结果回调*/void startRecordVideo(@NonNull FragmentActivity activity, @NonNull RMRecordVideoResultCallback callback);/*** 以默认配置打开录制视频界面** @param fragment Fragment* @param callback 视频录制结果回调*/void startRecordVideo(@NonNull Fragment fragment, @NonNull RMRecordVideoResultCallback callback);/*** 打开录制视频界面** @param activity Activity* @param option   视频录制请求配置信息类* @param callback 视频录制结果回调*/void startRecordVideo(@NonNull FragmentActivity activity, @Nullable RecordVideoRequestOption option, @NonNull RMRecordVideoResultCallback callback);/*** 打开录制视频界面** @param fragment Fragment* @param option   视频录制请求配置信息类* @param callback 视频录制结果回调*/void startRecordVideo(@NonNull Fragment fragment, @Nullable RecordVideoRequestOption option, @NonNull RMRecordVideoResultCallback callback);
}

RecordVideoRequestOption可配置最大时长(秒)和文件保存路径

public class RecordVideoRequestOption implements Parcelable {private String filePath;//文件保存路径private int maxDuration;//最大录制时间(秒数)private RecordVideoOption recordVideoOption;//录制视频配置信息类(里面配置的filePath和maxDuration会覆盖外面的)
}

RecordVideoActivity里已经配置好了默认参数,可以直接使用,然后在onActivityResult里拿到视频路径的返回值
返回值为RecordVideoResultInfo

@Overrideprotected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == Activity.RESULT_OK && requestCode == 0) {RecordVideoResultInfo info = data.getParcelableExtra(EXTRA_RECORD_VIDEO_RESULT_INFO);//从0.2.28版本开始可以使用下面这种方式,更安全更灵活,兼容性强RecordVideoResultInfo info = RecorderManagerFactory.getRecordVideoResult(data);//从0.3版本开始RecordVideoResultInfo info = RecorderManagerFactory.getRecordVideoResultParser().parseRecordVideoResult(data);if (info != null) {Log.e("MainActivity", "onActivityResult: " + " "+ info.getDuration() + " " + info.getFilePath());}}}

从0.4.0-beta.1版本开始:
由于采用Android新API registerForActivityResult,所以startActivityForResult等相关方法皆已废弃,相关回调将直接通过RMRecordVideoResultCallback传递

interface RMRecordVideoResultCallback {fun onResponseRecordVideoResult(info: RecordVideoResultInfo)fun onFailure(e: RecorderManagerException)
}通过下列IRecordVideoPageRequester相关方法,调用时同时传入响应结果回调void startRecordVideo(@NonNull FragmentActivity activity, @NonNull RMRecordVideoResultCallback callback);

(2).如果想要界面一些控件的样式,可以继承RecordVideoActivity,里面提供了几个protected方法,可以拿到界面的一些控件

/*** 获取计时控件** @return 返回计时AppCompatTextView*/protected AppCompatTextView getTimingView() {return mRecordVideoFg == null ? null : mRecordVideoFg.getTimingView();}/*** 获取圆形进度按钮** @return 返回进度CircleProgressButton*/protected CircleProgressButton getCircleProgressButton() {return mRecordVideoFg == null ? null : mRecordVideoFg.getCircleProgressButton();}/*** 获取翻转摄像头控件** @return 返回翻转摄像头AppCompatImageView*/public AppCompatImageView getFlipCameraView() {return mRecordVideoFg == null ? null : mRecordVideoFg.getFlipCameraView();}/*** 获取播放控件** @return 返回播放AppCompatImageView*/protected AppCompatImageView getPlayView() {return mRecordVideoFg == null ? null : mRecordVideoFg.getPlayView();}/*** 获取取消控件** @return 返回取消AppCompatImageView*/protected AppCompatImageView getCancelView() {return mRecordVideoFg == null ? null : mRecordVideoFg.getCancelView();}/*** 获取确认控件** @return 返回确认AppCompatImageView*/protected AppCompatImageView getConfirmView() {return mRecordVideoFg == null ? null : mRecordVideoFg.getConfirmView();}/*** 获取返回控件** @return 返回返回AppCompatImageView*/protected AppCompatImageView getBackView() {return mRecordVideoFg == null ? null : mRecordVideoFg.getBackView();}

想要替换图标资源的话,提供下列名称图片

rm_record_video_flip_camera.png
rm_record_video_cancel.png
rm_record_video_confirm.png
rm_record_video_play.png
rm_record_video_pull_down.png
rm_record_video_flashlight_turn_off.png
rm_record_video_flashlight_turn_on.png

(3).同时提供了对应的RecordVideoFragment,实现与RecordVideoActivity同样的功能,实际RecordVideoActivity就是包裹了一个RecordVideoFragment

1.创建RecordVideoFragment

/*** 获取录制视频Fragment实例(使用默认配置项)** @param filePath 存储文件路径* @return 返回RecordVideoFragment*/public static RecordVideoFragment newInstance(@Nullable String filePath) {return newInstance(filePath, 30);}/*** 获取录制视频Fragment实例(使用默认配置项)** @param filePath    存储文件路径* @param maxDuration 最大时长(秒数)* @return 返回RecordVideoFragment*/public static RecordVideoFragment newInstance(@Nullable String filePath, int maxDuration) {return newInstance(new RecordVideoOption.Builder().setRecorderOption(new RecorderOption.Builder().buildDefaultVideoBean(filePath)).setMaxDuration(maxDuration).build());}/*** 获取录制视频Fragment实例** @param option 录制配置信息对象* @return 返回RecordVideoFragment*/public static RecordVideoFragment newInstance(@Nullable RecordVideoOption option) {RecordVideoFragment fragment = new RecordVideoFragment();Bundle args = new Bundle();args.putParcelable(BUNDLE_EXTRA_RECORD_VIDEO_OPTION, option == null ? new RecordVideoOption() : option);fragment.setArguments(args);return fragment;}

2.然后添加RecordVideoFragment到自己想要的地方就可以了
3.可以设置OnRecordVideoListener,拿到各个事件的回调

public class RecordVideoOption:private RecorderOption recorderOption;//录制配置信息private RecordVideoButtonOption recordVideoButtonOption;//录制视频按钮配置信息类private int minDuration;//最小录制时长(秒数,最小是1,会自动调整不大于最大录制时长),可以和timingHint配合使用private int maxDuration;//最大录制时间(秒数)private RecorderManagerConstants.CameraType cameraType;//摄像头类型private boolean hideFlipCameraButton;//隐藏返回翻转摄像头按钮private boolean hideFlashlightButton;//隐藏闪光灯按钮private String timingHint;//录制按钮上方提示语句(默认:0:%s),会在计时前显示private String errorToastMsg;//录制发生错误Toast(默认:录制时间小于1秒,请重试)

原OnRecordVideoListener现已改为RMOnRecordVideoListener,并从RecordVideoOption中移除,主要用于用户自己activity或fragment实现此接口,用于承载RecordVideoFragment,获取相关步骤回调

interface RMOnRecordVideoListener {/*** 当完成一次录制时回调** @param filePath      视频文件路径* @param videoDuration 视频时长(毫秒)*/fun onCompleteRecordVideo(filePath: String?, videoDuration: Int)/*** 当点击确认录制结果按钮时回调** @param filePath      视频文件路径* @param videoDuration 视频时长(毫秒)*/fun onClickConfirm(filePath: String?, videoDuration: Int)/*** 当点击取消按钮时回调** @param filePath      视频文件路径* @param videoDuration 视频时长(毫秒)*/fun onClickCancel(filePath: String?, videoDuration: Int)/*** 当点击返回按钮时回调*/fun onClickBack()
}

4.RecordVideoButtonOption是圆形进度按钮配置类

 private @ColorIntint idleCircleColor;//空闲状态内部圆形颜色private @ColorIntint pressedCircleColor;//按下状态内部圆形颜色private @ColorIntint releasedCircleColor;//释放状态内部圆形颜色private @ColorIntint idleRingColor;//空闲状态外部圆环颜色private @ColorIntint pressedRingColor;//按下状态外部圆环颜色private @ColorIntint releasedRingColor;//释放状态外部圆环颜色private int idleRingWidth;//空闲状态外部圆环宽度private int pressedRingWidth;//按下状态外部圆环宽度private int releasedRingWidth;//释放状态外部圆环宽度private int idleInnerPadding;//空闲状态外部圆环与内部圆形之间边距private int pressedInnerPadding;//按下状态外部圆环与内部圆形之间边距private int releasedInnerPadding;//释放状态外部圆环与内部圆形之间边距private boolean idleRingVisible;//空闲状态下外部圆环是否可见private boolean pressedRingVisible;//按下状态下外部圆环是否可见private boolean releasedRingVisible;//释放状态下外部圆环是否可见

5.RecorderOption是具体的录制参数配置类

 private int audioSource;//音频源private int videoSource;//视频源private int outputFormat;//输出格式private int audioEncoder;//音频编码格式private int videoEncoder;//视频编码格式private int audioSamplingRate;//音频采样频率(一般44100)private int bitRate;//视频编码比特率private int frameRate;//视频帧率private int videoWidth, videoHeight;//视频宽高private int maxDuration;//最大时长private long maxFileSize;//文件最大大小private String filePath;//文件存储路径private int orientationHint;//视频录制角度方向

(4).如果想自定义自己的界面,可以直接使用RecorderManagerable类

1.通过RecorderManagerFactory获取IRecorderManager
从0.4.0-beta版本开始:RecorderManagerFactory重命名为RecorderManagerProvider

public final class RecorderManagerProvider {private RecorderManagerProvider() {}/*** 创建录制管理类实例(使用默认录制类)** @return 返回录制管理类实例*/@NonNullpublic static IRecorderManager newInstance() {return newInstance(new RecorderHelper());}/*** 创建录制管理类实例(使用默认录制类)** @param intercept 录制管理器拦截器* @return 返回录制管理类实例*/@NonNullpublic static IRecorderManager newInstance(@NonNull IRecorderManagerInterceptor intercept) {return newInstance(new RecorderHelper(), intercept);}/*** 创建录制管理类实例** @param helper 实际录制类* @return 返回录制管理类实例*/@NonNullpublic static IRecorderManager newInstance(@NonNull IRecorderHelper helper) {return newInstance(helper, null);}/*** 创建录制管理类实例** @param helper    实际录制类* @param intercept 录制管理器拦截器* @return 返回录制管理类实例*/@NonNullpublic static IRecorderManager newInstance(@NonNull IRecorderHelper helper, @Nullable IRecorderManagerInterceptor intercept) {return new RecorderManager(helper, intercept);}@NonNullpublic static IRecordVideoPageRequester getRecordVideoRequester() {return new RecordVideoPageRequester();}@NonNullpublic static IRecordVideoResultParser getRecordVideoResultParser() {return new RecordVideoResultParser();}
}

它们返回的都是IRecorderManager 接口类型,RecorderManager 是默认的实现类,RecorderManager 内持有一个真正进行操作的RecorderHelper。

public interface IRecorderManager extends IRecorderHelper {/*** 设置录制对象** @param helper 录制对象实例*/void setRecorderHelper(@NonNull IRecorderHelper helper);/*** 获取录制对象** @return 返回录制对象实例*/@NonNullIRecorderHelper getRecorderHelper();/*** 初始化相机对象** @param holder Surface持有者* @return 返回初始化好的相机对象*/@NullableCamera initCamera(@NonNull SurfaceHolder holder);/*** 初始化相机对象** @param cameraType 指定的摄像头类型* @param holder     Surface持有者* @return 返回初始化好的相机对象*/@NullableCamera initCamera(@NonNull RecorderManagerConstants.CameraType cameraType, @NonNull SurfaceHolder holder);/*** 打开或关闭闪光灯** @param turnOn true表示打开,false关闭*/boolean switchFlashlight(boolean turnOn);/*** 翻转摄像头** @param holder Surface持有者* @return 返回翻转并初始化好的相机对象*/@NullableCamera flipCamera(@NonNull SurfaceHolder holder);/*** 翻转到指定类型摄像头** @param cameraType 摄像头类型* @param holder     Surface持有者* @return 返回翻转并初始化好的相机对象*/@NullableCamera flipCamera(@NonNull RecorderManagerConstants.CameraType cameraType, @NonNull SurfaceHolder holder);/*** 获取当前摄像头类型** @return 返回摄像头类型*/@NonNullRecorderManagerConstants.CameraType getCameraType();/*** 释放相机资源*/void releaseCamera();}

RecorderManagerIntercept实现IRecorderManagerInterceptor接口,用户可以直接继承RecorderManagerIntercept,它里面所有方法都是空实现,可以自己改写需要的方法

public interface IRecorderManagerInterceptor extends ICameraInterceptor {
}

IRecorderHelper是一个接口类型,由实现IRecorderHelper的子类来进行录制操作,默认提供的是RecorderHelper,RecorderHelper实现了IRecorderHelper。

public interface IRecorderHelper {/*** 录制音频** @param path 文件存储路径* @return 返回是否成功开启录制,成功返回true,否则返回false*/boolean recordAudio(@NonNull String path);/*** 录制音频** @param option 存储录制信息的对象* @return 返回是否成功开启录制,成功返回true,否则返回false*/boolean recordAudio(@NonNull RecorderOption option);/*** 录制视频** @param camera  相机* @param surface 表面视图* @param path    文件存储路径* @return 返回是否成功开启录制,成功返回true,否则返回false*/boolean recordVideo(@Nullable Camera camera, @Nullable Surface surface, @Nullable String path);/*** 录制视频** @param camera  相机* @param surface 表面视图* @param option  存储录制信息的对象* @return 返回是否成功开启视频录制,成功返回true,否则返回false*/boolean recordVideo(@Nullable Camera camera, @Nullable Surface surface, @Nullable RecorderOption option);/*** 释放资源*/void release();/*** 获取录制器** @return 返回实例对象*/@NonNullMediaRecorder getMediaRecorder();/*** 获取配置信息对象** @return 返回实例对象*/@NullableRecorderOption getRecorderOption();
}

2.拿到后创建相机对象

     if (mCamera == null) {mCamera = mManager.initCamera(mCameraType, svVideoRef.get().getHolder());mCameraType = mManager.getCameraType();}

3.录制

isRecording = mManager.recordVideo(mCamera, svVideoRef.get().getHolder().getSurface(), mOption.getRecorderOption());

4.释放

     mManager.release();mManager = null;mCamera = null;

四.总结

目前来说,大体流程就是这样,更详细的信息请到Github上查看, 后期将添加闪光灯等更多功能,敬请关注,github地址为 https://github.com/MingYueChunQiu/RecorderManager ,码云地址为 https://gitee.com/MingYueChunQiu/RecorderManager ,如果它能对你有所帮助,请帮忙点个star,有什么建议或意见欢迎反馈。

RecorderManager安卓仿微信自定义音视频录制第三方库相关推荐

  1. Android (系统+自定义)短视频录制(含暂停继续录制功能) 总结

    前言 在Android开发中自然少不了对视频录制的需求,然而视频录制虽然有系统提供给我们能够直接使用的API,但是我们往往在完成需求的过程中需要自定义实现短视频录制.网上虽然也有不少资料,但是总是零零 ...

  2. 【愚公系列】2022年04月 微信小程序-实时音视频录制

    文章目录 前言 一.实时音视频录制 1.js代码 2.wxml代码 3.效果 前言 小程序的实时音视频播放需要先去微信开发者平台开通权限,「开发」-「接口设置」中自助开通该组件权限. 类目属性如下: ...

  3. android放微信@功能,Android仿微信语音消息的录制和播放功能

    一.简述 效果: 实现功能: 长按Button时改变Button显示文字,弹出Dialog(动态更新音量),动态生成录音文件,开始录音: 监听手指动作,规定区域.录音状态下手指划出规定区域取消录音,删 ...

  4. 仿微信语音消息的录制和播放

    仿微信语音消息的录制和播放 一.简述 效果: 实现功能: 长按Button时改变Button显示文字,弹出Dialog(动态更新音量),动态生成录音文件,开始录音: 监听手指动作,规定区域.录音状态下 ...

  5. 《android多媒体api》之MediaRecorder音视频录制api

    <android多媒体api>系列是整合梳理android开发中经常用到的媒体相关api:多媒体开发主要内容有音频.视频录制播放.摄像头操作.录制操作.流媒体.直播.推流.拉流等方面:最近 ...

  6. Java集成腾讯云音视频录制功能

    Java集成腾讯云音视频录制功能 为什么要实现音视频录制功能 因为我们做的是一个医院的项目,医生和患者可能进行视频通话和语音通话,为了保证通话的质量以及后续的问题, 我们就需要进行音视频录制,以便后续 ...

  7. javacv+远程视频直播+音视频录制+视频抓取

    远程视频直播+音视频录制+视频抓取 请首先阅读注意事项文末有github地址 远程直播展示 音视频录制 运行会有延迟,视频为mp4格式存储在D盘. 视频抓取 注意事项 远程直播需要下载一个软件:VLC ...

  8. webrtc 入门第二章 音视频录制

    webrtc 入门第二章 音视频录制 一.介绍 1.媒体录制原理 ​ 在很多场景中回放音视频资源的需求是非常重要的例如会议,直播授课等.任何媒体形式的表情都可进行录制,如 ,,等.其中内容更加自由用户 ...

  9. 开发ASP.NET MVC 在线录音录像(音视频录制并上传)

    开发ASP.NET MVC 在线录音录像(音视频录制并上传) 最近有个在线招聘录音的开发需求,需要在招聘网站上让招聘者上传录音和视频. 找到两个不错的javascript开源,可以在除了IE以外的浏览 ...

  10. Android OpenGL添加水印并录制视频--抖音视频录制原理

    Android OpenGL添加水印并录制视频–抖音视频录制原理 简单的视频录制,我们可以使用MediaRecorder,具体示例可以参考Gitee: Camera2VideoJava 本文将介绍采集 ...

最新文章

  1. python简单计算器异常处理_Python实现的简单计算器
  2. 计算机中丢失qt5svg,无法找到“Qt5Svg”提供了一个程序包配置文件
  3. 结对-贪吃蛇-项目进度
  4. Spring系列(九):Spring属性赋值注解@Value 用法介绍
  5. 在Teams Hackathon上介绍LuckyDraw
  6. ac算法 有什么用 Java_AC算法使用例子
  7. C#递归搜索指定目录下的文件或目录
  8. ci phpexcel mysql_PHPExcel导入数据到mysql数据库
  9. 51单片机怎么显示当前时间_51单片机玩转物联网基础篇06-LCD1602液晶显示器
  10. 《零基础》MySQL 超级入门教程
  11. 飞鸽传书开发者的圈子里面 有很多对飞鸽公司
  12. 从竞品数据搜集切入,NiucoData要做商业情报追踪分析工具
  13. web报表工具FineReport最经常用到部分函数详解
  14. listview拖动优化问题
  15. C++基础::字符串流(stringstream)
  16. aloha app android,Aloha软件最新版下载-Aloha安卓版下载 v5.2.0-都去下载
  17. 人工智能谓词逻辑——猴子摘香蕉问题
  18. 你想学Python爬虫?看看这篇关于开发者工具神器的博客吧
  19. 面试官问我知道的分布式事务,我一口气说了六种
  20. 考题篇(6.2) 02 ❀ FortiGate ❀ Fortinet 网络安全专家 NSE 4

热门文章

  1. nova5 pro Android id,华为nova5pro支持NFC功能吗?
  2. Android 8.0中各种通知写法汇总
  3. Laraval-admin 自定义form组件
  4. springboot + vue + FastDFS实现文件上传(支持预览)
  5. mysql表必须有主键吗_SQL中的每一张表都必须设有主键吗
  6. 公众号引流好困难,这个病该怎么治?
  7. 资源下载类网站源码 第二版本分享
  8. 数据结构与算法01:绪论【LEARN FROM 李春葆《数据结构教程》】
  9. python实现ks算法_Python计算KS值并绘制KS曲线
  10. 解封反垃圾邮件组织屏蔽方法