- 用于录制音频和视频的一个类:MediaRecorder
-
Initial:初始状态,当使用new()方法创建一个MediaRecorder对象或者调用了reset()方法时,该MediaRecorder对象处于Initial状态。在设定视频源或者音频源之后将转换为Initialized状态。另外,在除Released状态外的其它状态通过调用reset()方法都可以使MediaRecorder进入该状态。
-
Initialized:已初始化状态,可以通过在Initial状态调用setAudioSource()或setVideoSource()方法进入该状态。在这个状态可以通过setOutputFormat()方法设置输出格式,此时MediaRecorder转换为DataSourceConfigured状态,数据源配置状态。
-
DataSourceConfigured:数据源配置状态,这期间可以设定编码方式、输出文件、屏幕旋转、预览显示等等。可以在Initialized状态通过setOutputFormat()方法进入该状态。可以通过reset()方法回到Initial状态,或者通过prepare()方法到达Prepared状态。
-
Prepared:就绪状态,在DataSourceConfigured状态通过prepare()方法进入该状态。在这个状态可以通过start()进入录制状态。
另外,可以通过reset()方法回到Initialized状态。 -
Recording: 录制状态,可以在Prepared状态通过调用start()方法进入该状态。另外,它可以通过stop()方法或reset()方法回到Initial状态
-
Released: 释放状态(空闲状态),可以通过调用release()方法来进入这个状态,这时将会释放所有和MediaRecorder对象绑定的资源。
-
Error:错误状态,当错误发生的时候进入这个状态,它可以通过reset()方法进入Initial状态。
-
动态申请以下权限
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO -
初始化mediaRecord
//初始化MediaRecorder
private void initMediaRecorder() {
try {
//进入Initial状态
if (mediaRecorder == null) {
mediaRecorder = new MediaRecorder();
} else {
//通过reset()方法
mediaRecorder.reset();
}
if (cameraCaptureSession != null) {
cameraCaptureSession.close();
cameraCaptureSession = null;
}
//前后置摄像头的录制角度,前270,后90
if (cameraId.equals(String.valueOf(CameraCharacteristics.LENS_FACING_BACK))) {
mediaRecorder.setOrientationHint(270);
}else {
mediaRecorder.setOrientationHint(90);
}
//配置mediaRecorder
setConfig();
} catch (Exception e) {
e.printStackTrace();
}
}
- //自定义MediaRecorder的录制参数
private void setConfig() {
//采集声音来源,mic是麦克风,进入initialized状态
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置视频源,从Surface里面读取画面去录制
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
//设置封装格式 默认是MP4,进入DataSourceConfigured状态
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
//音频编码,AAC:高级音频编码
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
//图像编码,H263 多用于视频传输,其优点是压缩后体积小,占用带宽少;
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//设置最大录像时间 单位:毫秒
//mediaRecorder.setMaxDuration(60 * 1000);
//设置最大录制的大小60M 单位,字节
mediaRecorder.setMaxFileSize(60 * 1024 * 1024);
//设置帧率(帧/秒),该帧率必须是硬件支持的,可以通过Camera.CameraParameter.getSupportedPreviewFpsRange()方法获取相机支持的帧率
//设置要捕获的视频的帧速率。每秒要捕捉的视频帧数.必须在setVideoSource()后调用。在setOutputFormat()之后,在prepare()之前调用它
mediaRecorder.setVideoFrameRate(30);
//setVideoFrameRate在正常记录情况下使用,在延时情况下添加设置要捕获的视频的帧速率 ,setCaptureRate()。
//相对于VideoRate的值,大于则放慢,小于加快
if (delayflage) {mediaRecorder.setCaptureRate(10);}
//设置视频比特率:指每秒传输速率(比特数(bit)。单位为bps(Bit Per Second),比特率越高,每秒传送数据就越多,画质就越清晰。
//mediaRecorder.setVideoEncodingBitRate(500 * 1024 * 24);
mediaRecorder.setVideoEncodingBitRate(previewSize.getWidth() * previewSize.getHeight() * 24);
//设置视频尺寸,通常搭配码率一起使用,可调整视频清晰度
mediaRecorder.setVideoSize(previewSize.getWidth(), previewSize.getHeight());
//设置文件的输出路径
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera";
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
recordFile = new File(path + "/" + System.currentTimeMillis() + ".MP4");
String savedpath = recordFile.getAbsolutePath();
//设置录制的音频文件的保存位置。
mediaRecorder.setOutputFile(savedpath);
//在DataSourceConfigured状态通过prepare()方法进入就绪状态,在这个状态可以通过start()进入录制状态。
try {
//通过prepare()方法到达Prepared状态
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
imageList.add(savedpath);
}
//配置录像
private void setVideoBuilder() {
try {
//创建录像请求 CaptureRequest.Builder对象
recordRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
// CaptureRequest.Builder添加两个surface1
recordRequestBuilder.addTarget(previewsurface);
//预览输出
//设置MediaRecorder的surface
Surface recorderSurface = mediaRecorder.getSurface();
// CaptureRequest.Builder添加两个surface2
recordRequestBuilder.addTarget(recorderSurface);
//创建录像会话
cameraDevice.createCaptureSession(Arrays.asList(previewsurface, recorderSurface), videoSessionStateCallback, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
//创建videoSession回调
//创建videoSession回调
private CameraCaptureSession.StateCallback videoSessionStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
try {
cameraCaptureSession = session;
cameraCaptureSession.setRepeatingRequest(recordRequestBuilder.build(), null, null);
//通过调用start()方法进入Recording: 录制状态
mediaRecorder.start();//开始录像
startTime();//开始计时
timer.setVisibility(View.VISIBLE);//出现
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
session.close();
cameraCaptureSession = null;
cameraDevice.close();
cameraDevice = null;
}
};
//开始计时
private void startTime() {
timer.setBase(SystemClock.elapsedRealtime());//计时器清零
timer.start();
}
- 停止录像:释放MediaRecorder(stop()->reset->release->null),开启预览
private void stopRecord() {
timer.stop();
releaseMediaRecorder();
broadcastUpdate();
setPhotos_show(imageList.get(imageList.size() - 1));//显示最新的一张图
startPreview();
isRecording = false;
}
//释放MediaRecorder:stop()->reset->release->null
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
if (isRecording) {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
mediaRecorder = null;
isRecording = false;
}
}
}