因為在專案中經常需要使用音視訊錄製,所以寫了一個公共庫RecorderManager,歡迎大家使用。
最新0.2.16版本更新: 1.優化相機呼叫
一.效果展示
仿微信介面視訊錄製
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.2.16'
}
複製程式碼
三.使用
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,實現了仿微信風格的錄製介面
startActivityForResult(new Intent(MainActivity.this, RecordVideoActivity.class),0);
複製程式碼
通過在Intent中傳入下列引數來設定路徑和最長時間
//設定儲存視訊錄製的檔案路徑
intent.putExtra(EXTRA_RECORD_VIDEO_FILE_PATH, "路徑名");
//設定視訊錄製的最大時長(預設30秒)
intent.putExtra(EXTRA_RECORD_VIDEO_MAX_DURATION, 10);
複製程式碼
RecordVideoActivity裡已經配置好了預設引數,可以直接使用,然後在onActivityResult裡拿到視訊路徑的返回值
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == 0) {
Log.e("onActivityResult", "onActivityResult: " + " " + data.getStringExtra(EXTRA_RECORD_VIDEO_FILE_PATH) + " " +
data.getIntExtra(EXTRA_RECORD_VIDEO_DURATION, -1));
}
}
複製程式碼
(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();
}
複製程式碼
想要替換圖示資源的話,提供下列名稱圖片
record_video_flip_camera.png
record_video_cancel.png
record_video_confirm.png
record_video_play.png
record_video_pull_down.png
複製程式碼
(3).同時提供了對應的RecordVideoFragment,實現與RecordVideoActivity同樣的功能,實際RecordVideoActivity就是包裹了一個RecordVideoFragment
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() + ".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);
/**
* 當點選返回按鈕時回撥
*/
void onClickBack();
}
複製程式碼
(4).如果想自定義自己的介面,可以直接使用RecorderManagerable類
1.通過RecorderManagerFactory獲取RecorderManagerable
public class RecorderManagerFactory {
/**
* 建立錄製管理類例項(使用預設錄製類)
*
* @return 返回錄製管理類例項
*/
public static RecorderManagerable newInstance() {
return newInstance(new RecorderHelper());
}
/**
* 建立錄製管理類例項(使用預設錄製類)
*
* @param intercept 錄製管理器攔截器
* @return 返回錄製管理類例項
*/
public static RecorderManagerable newInstance(RecorderManagerInterceptable intercept) {
return newInstance(new RecorderHelper(), intercept);
}
/**
* 建立錄製管理類例項
*
* @param recorderable 實際錄製類
* @return 返回錄製管理類例項
*/
public static RecorderManagerable newInstance(Recorderable recorderable) {
return newInstance(recorderable, null);
}
/**
* 建立錄製管理類例項
*
* @param recorderable 實際錄製類
* @param intercept 錄製管理器攔截器
* @return 返回錄製管理類例項
*/
public static RecorderManagerable newInstance(Recorderable recorderable, RecorderManagerInterceptable intercept) {
return new RecorderManager(recorderable, intercept);
}
}
複製程式碼
它們返回的都是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介面
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地址為 github.com/MingYueChun… ,碼雲地址為 gitee.com/MingYueChun… ,如果它能對你有所幫助,請幫忙點個star,有什麼建議或意見歡迎反饋。