由於在項目中常常須要使用音視頻錄製,因此寫了一個公共庫RecorderManager,歡迎你們使用。git
最新0.2.25版本更新: 1.優化權限自動申請,可自動調起視頻錄製界面 2.規範圖片資源命名github
仿微信界面視頻錄製 2.音頻錄製界面比較簡單,就不放圖了微信
1.Add it in your root build.gradle at the end of repositoriesmaven
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
2.Add the dependencyide
dependencies { implementation 'com.github.MingYueChunQiu:RecorderManager:0.2.25' }
採用默認配置錄製gradle
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());
從0.2.18開始改成相似ui
RecorderManagerFactory.getRecordVideoRequest().startRecordVideo(MainActivity.this, 0);
RecorderManagerFactory中能夠拿到RequestRecordVideoPageable,在RequestRecordVideoPageable接口中this
/** * 以默認配置打開錄製視頻界面 * * @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, RecordVideoRequestOption option); /** * 打開錄製視頻界面 * * @param fragment Fragment * @param requestCode 請求碼 * @param option 視頻錄製請求配置信息類 */ void startRecordVideo(@NonNull Fragment fragment, int requestCode, RecordVideoRequestOption option);
RecordVideoRequestOption可配置最大時長(秒)和文件保存路徑url
public class RecordVideoRequestOption implements Parcelable { private int maxDuration;//最大錄製時長 private String filePath;//文件保存路徑 }
RecordVideoActivity裏已經配置好了默認參數,能夠直接使用,而後在onActivityResult裏拿到視頻路徑的返回值 返回值爲RecordVideoResultInfo
@Override protected 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); Log.e("MainActivity", "onActivityResult: " + " " + info.getDuration() + " " + info.getFilePath()); } }
/** * 獲取計時控件 * * @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
1.建立RecordVideoFragment
/** * 獲取錄製視頻Fragment實例(使用默認配置項) * * @param filePath 存儲文件路徑 * @return 返回RecordVideoFragment */ public static RecordVideoFragment newInstance(String filePath) { return newInstance(filePath, 30); } /** * 獲取錄製視頻Fragment實例(使用默認配置項) * * @param filePath 存儲文件路徑 * @param maxDuration 最大時長(秒數) * @return 返回RecordVideoFragment */ public static RecordVideoFragment newInstance(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(RecordVideoOption option) { RecordVideoFragment fragment = new RecordVideoFragment(); fragment.mOption = option; if (fragment.mOption == null) { fragment.mOption = new RecordVideoOption(); } if (fragment.mOption.getRecorderOption() == null && fragment.getContext() != null) { File file = fragment.getContext().getExternalFilesDir(Environment.DIRECTORY_MOVIES); if (file != null) { fragment.mOption.setRecorderOption(new RecorderOption.Builder().buildDefaultVideoBean( file.getAbsolutePath() + File.separator + System.currentTimeMillis() + SUFFIX_MP4)); } } return fragment; }
2.而後添加RecordVideoFragment到本身想要的地方就能夠了 3.能夠設置OnRecordVideoListener,拿到各個事件的回調
public class RecordVideoOption: private RecorderOption option;//錄製配置信息 private int maxDuration;//最大錄製時間 private OnRecordVideoListener listener;//錄製視頻監聽器 /** * 錄製視頻監聽器 */ public interface OnRecordVideoListener { /** * 當完成一次錄製時回調 * * @param filePath 視頻文件路徑 * @param videoDuration 視頻時長(毫秒) */ void onCompleteRecordVideo(String filePath, int videoDuration); /** * 當點擊確認錄製結果按鈕時回調 * * @param filePath 視頻文件路徑 * @param videoDuration 視頻時長(毫秒) */ void onClickConfirm(String filePath, int videoDuration); /** * 當點擊取消按鈕時回調 * * @param filePath 視頻文件路徑 * @param videoDuration 視頻時長(毫秒) */ void onClickCancel(String filePath, int videoDuration); /** * 當點擊返回按鈕時回調 */ void onClickBack(); }
1.經過RecorderManagerFactory獲取RecorderManagerable
public class RecorderManagerFactory { /** * 建立錄製管理類實例(使用默認錄製類) * * @return 返回錄製管理類實例 */ @NonNull public static RecorderManagerable newInstance() { return newInstance(new RecorderHelper()); } /** * 建立錄製管理類實例(使用默認錄製類) * * @param intercept 錄製管理器攔截器 * @return 返回錄製管理類實例 */ @NonNull public static RecorderManagerable newInstance(RecorderManagerInterceptable intercept) { return newInstance(new RecorderHelper(), intercept); } /** * 建立錄製管理類實例 * * @param recorderable 實際錄製類 * @return 返回錄製管理類實例 */ @NonNull public static RecorderManagerable newInstance(Recorderable recorderable) { return newInstance(recorderable, null); } /** * 建立錄製管理類實例 * * @param recorderable 實際錄製類 * @param intercept 錄製管理器攔截器 * @return 返回錄製管理類實例 */ @NonNull public static RecorderManagerable newInstance(Recorderable recorderable, RecorderManagerInterceptable intercept) { return new RecorderManager(recorderable, intercept); } @NonNull public static RequestRecordVideoPageable getRecordVideoRequest() { return new RecordVideoPageRequest(); } }
它們返回的都是RecorderManagerable 接口類型,RecorderManager 是默認的實現類,RecorderManager 內持有一個真正進行操做的Recorderable。
public interface RecorderManagerable extends Recorderable { /** * 設置錄製對象 * * @param recorderable 錄製對象實例 */ void setRecorderable(Recorderable recorderable); /** * 獲取錄製對象 * * @return 返回錄製對象實例 */ Recorderable getRecorderable(); /** * 初始化相機對象 * * @param holder Surface持有者 * @return 返回初始化好的相機對象 */ Camera initCamera(SurfaceHolder holder); /** * 初始化相機對象 * * @param cameraType 指定的攝像頭類型 * @param holder Surface持有者 * @return 返回初始化好的相機對象 */ Camera initCamera(Constants.CameraType cameraType, SurfaceHolder holder); /** * 翻轉攝像頭 * * @param holder Surface持有者 * @return 返回翻轉並初始化好的相機對象 */ Camera flipCamera(SurfaceHolder holder); /** * 翻轉到指定類型攝像頭 * * @param cameraType 攝像頭類型 * @param holder Surface持有者 * @return 返回翻轉並初始化好的相機對象 */ Camera flipCamera(Constants.CameraType cameraType, SurfaceHolder holder); /** * 獲取當前攝像頭類型 * * @return 返回攝像頭類型 */ Constants.CameraType getCameraType(); /** * 釋放相機資源 */ void releaseCamera(); }
RecorderManagerIntercept實現RecorderManagerInterceptable接口,用戶能夠直接繼承RecorderManagerIntercept,它裏面全部方法都是空實現,能夠本身改寫須要的方法
public interface RecorderManagerInterceptable extends RecorderManagerable, CameraInterceptable { }
Recorderable是一個接口類型,由實現Recorderable的子類來進行錄製操做,默認提供的是RecorderHelper,RecorderHelper實現了Recorderable。
public interface Recorderable { /** * 錄製音頻 * * @param path 文件存儲路徑 * @return 返回是否成功開啓錄製,成功返回true,不然返回false */ boolean recordAudio(String path); /** * 錄製音頻 * * @param option 存儲錄製信息的對象 * @return 返回是否成功開啓錄製,成功返回true,不然返回false */ boolean recordAudio(RecorderOption option); /** * 錄製視頻 * * @param camera 相機 * @param surface 表面視圖 * @param path 文件存儲路徑 * @return 返回是否成功開啓錄製,成功返回true,不然返回false */ boolean recordVideo(Camera camera, Surface surface, String path); /** * 錄製視頻 * * @param camera 相機 * @param surface 表面視圖 * @param option 存儲錄製信息的對象 * @return 返回是否成功開啓視頻錄製,成功返回true,不然返回false */ boolean recordVideo(Camera camera, Surface surface, RecorderOption option); /** * 釋放資源 */ void release(); /** * 獲取錄製器 * * @return 返回實例對象 */ MediaRecorder getMediaRecorder(); /** * 獲取配置信息對象 * * @return 返回實例對象 */ RecorderOption 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,有什麼建議或意見歡迎反饋。