前言
在前几篇博客中我分别介绍了一下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