前言
在前几篇博客中我分别介绍了一下SurfaceView以及Camera的水印预览和拍照,专题地址请看:传送门,下面我就来介绍下如何使用Camera进行录像功能。
流程
1、首先初始化一个Camera并且开启预览,方法可以查看前几篇博客。
2、使用Camera的unlock()方法解锁Camera,因为系统在同一时刻只允许一个进程访问摄像头,所以需要调用这个方法让其"解锁"。
3、通过MediaRecorder的 setCamera(Camera)将Camera数据设置给MediaRecorder,然后给MediaRecorder设置好属性即可开始录制。
4、当完成录制以后需要通过Camera的 reconnect()方法去重新"锁住"相机。
5、如果不需要使用像极了,那么回收相机资源
实现
视频录像主要使用的是MediaRecorder。根据官方文档,基本用法为如下:
MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(PATH_NAME); recorder.prepare(); recorder.start(); // Recording is now started ... recorder.stop(); recorder.reset(); // You can reuse the object by going back to setAudioSource() step recorder.release(); // Now the object cannot be reused
如上仅仅实现了录音功能,如果我们想加入录像功能也仅仅只需要一并设置视频来源而已,代码如下。
public void startRecorder() {
File outputPath = new File(Environment.getExternalStorageDirectory(), "recoder.mp4");
if (mMediaRecorder == null) {
// Initial 状态
mMediaRecorder = new MediaRecorder();
}
if (mCamera != null) {
mCamera.unlock();
}
mMediaRecorder.setCamera(mCamera);
// 前置摄像头需要旋转90度,原因见前几篇博客
mMediaRecorder.setOrientationHint(90);
// 进入Initialized状态
// 设置音频来源为麦克风
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 设置视频来源为摄像头
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 进入DataSourceConfigured状态
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
// 设置文件保存路径
mMediaRecorder.setOutputFile(outputPath.getAbsolutePath());
mMediaRecorder.setVideoSize(1280, 720);
// 设置帧数率 30fps
mMediaRecorder.setVideoFrameRate(30);
// 设置bit率
mMediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
try {
// 进入prepare状态
mMediaRecorder.prepare();
// 进入Recording状态
mMediaRecorder.start();
Toast.makeText(getContext(), "开始录像", Toast.LENGTH_SHORT).show();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
上面的代码注释已经写得很清楚了。首先使用mCamera.unlock();解锁,然后设置好属性就可以录制啦,请注意上面的方法调用顺序!!!请注意上面的方法调用顺序!!!请注意上面的方法调用顺序!!!在不同的状态下不能调用其他状态的方法,不然会抛出非法状态异常。关于各个状态的转变以及每个状态可以调用的方法,贴出一张官文文档里面的图片。

停止录像需要进行资源回收工作。类似于Camera的回收。
public void stopRecorder() {
if (mMediaRecorder != null) {
mMediaRecorder.stop();
mMediaRecorder.release();
mMediaRecorder = null;
Toast.makeText(getContext(), "停止录像", Toast.LENGTH_SHORT).show();
if (mCamera != null) {
try {
mCamera.reconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
一些暗坑
1、注意方法调用顺序!!!注意方法调用顺序!!!注意方法调用顺序!!!
2、注意资源回收的时机,当SurfaceView被销毁的时候以及Activity进入onPause()的时候,需要停止录像与相机预览并回收资源。
3、如果录制的视频方向不对,请查看前几篇博客的说明,后置90°,前置270°!!!
Demo下载地址:https://github.com/CB2Git/BlogDemoRepository/tree/master/TestCameraRecorder