最近公司产品要添加一个拍摄小视频的功能,在开发Camera的时候发现有好多坑,而网上的找的内容又不能完全解决问题,所以还是得靠自己来解决。
首先要来分析一下需求
- 可以切换前后摄像头
- 可以开启和关闭闪光灯
- 尽可能的减少拍摄视频的体积
先来看一下要实现的接口
public interface RecordInterface {
void initView();
void openCamera();
void startPreview();
void startRecorder();
void stopRecorder();
void stopPreview();
void releaseCamera();
void deleteFile();
void changeCamera();
void changeLight();
}
@Override
public void openCamera() {
try {
mCamera = Camera.open(isBack ? Camera.CameraInfo.CAMERA_FACING_BACK : Camera.CameraInfo.CAMERA_FACING_FRONT);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(App.getInstance().getContext(), R.string.open_camera_fail, Toast.LENGTH_SHORT).show();
}
}
@Override
public void startPreview() {
if (mCamera != null) {
try {
Parameters params = mCamera.getParameters();
List<String> flashModeList = params.getSupportedFlashModes();
if (flashModeList != null && !flashModeList.isEmpty()) {
boolean supportTorch = false;
for (String flashMode : flashModeList) {
if (TextUtils.equals(flashMode, Parameters.FLASH_MODE_TORCH)) {
supportTorch = true;
}
}
params.setFlashMode(isLight && supportTorch ? Parameters.FLASH_MODE_TORCH : Parameters.FLASH_MODE_OFF);
}
List<Camera.Size> sizeList = params.getSupportedPreviewSizes();
if (sizeList != null && !sizeList.isEmpty()) {
for (Camera.Size size : sizeList) {
if (size.width == width && size.height == height) {
width = size.width;
height = size.height;
break;
} else {
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);
width = profile.videoFrameWidth;
height = profile.videoFrameHeight;
}
}
}
params.setPreviewSize(width, height);
mCamera.setParameters(params);
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void startRecorder() {
if (mCamera != null) {
try {
mMediaRecorder = new MediaRecorder();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(VideoSource.CAMERA);
mMediaRecorder.setAudioSource(AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setCaptureRate(10);
mMediaRecorder.setVideoFrameRate(10);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setVideoEncodingBitRate(900 * 1024);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setAudioEncodingBitRate(161 * 1024);
mMediaRecorder.setVideoSize(width, height);
mMediaRecorder.setOrientationHint(type == 0 ? ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL);
mMediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
mMediaRecorder.setOutputFile(mVecordFile.getAbsolutePath());
mMediaRecorder.setOnErrorListener(this);
mMediaRecorder.prepare();
mMediaRecorder.start();
seconds = 0;
App.getInstance().getHandler().postDelayed(runnable, 1000);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
@Override
public void stopRecorder() {
if (mMediaRecorder != null) {
mMediaRecorder.setOnErrorListener(null);
mMediaRecorder.setPreviewDisplay(null);
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
}
mOnRecordListener.onFinish(mVecordFile, seconds);
App.getInstance().getHandler().removeCallbacks(runnable);
}
@Override
public void stopPreview() {
if (mCamera != null) {
mCamera.stopPreview();
}
}
@Override
public void releaseCamera() {
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
@Override
public void deleteFile() {
mVecordFile.delete();
}
@Override
public void changeCamera() {
isBack = !isBack;
stopPreview();
releaseCamera();
openCamera();
startPreview();
}
@Override
public void changeLight() {
isLight = !isLight;
startPreview();
}