问题现象
修改后的代码在机器正常
int recordTime = 10 * 60 * 1000 ;
try {
File vedioTempPath = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/video/temp/");
if (!vedioTempPath.exists()) {
vedioTempPath.mkdirs();
}
vedioTempPath = new File(storageDirectory + "/video/Camera2_INT_STR8/");
if (!vedioTempPath.exists()) {
vedioTempPath.mkdirs();
}
openCamera(cameraId);
SystemClock.sleep(2000);
//startPreview();
startPreview_qcom();
startRecordingVideo();
SystemClock.sleep(recordTime);
stopRecordingVideo();
SystemClock.sleep(2000);
stopPreview();
releaseCamera();
SystemClock.sleep(5000);
} catch (Exception e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true));
String str = sw.toString();
Display.appendInfo(str);
e.printStackTrace();
fail(str);
}
/**
* 开始录像
*/
private void startRecordingVideo() {
// mMediaRecorder = new MediaRecorder();
if (null == mCameraDevice ) {
return;
}
try {
closePreviewSession();
setUpMediaRecorder();
Display.appendInfo("start recording Video\n");
mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
List<Surface> surfaces = new ArrayList<>();
Surface previewSurface = msurfaceHolder.getSurface();
surfaces.add(previewSurface);
mPreviewBuilder.addTarget(previewSurface);
// Set up Surface for the MediaRecorder设置MediaRecorder的表面
Surface recorderSurface = mMediaRecorder.getSurface();
Log.d(TAG,recorderSurface.toString());
surfaces.add(recorderSurface);
Log.d(TAG,surfaces.toString());
mPreviewBuilder.addTarget(recorderSurface);
mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
mSession = cameraCaptureSession;
updatePreview();
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
mIsRecordingVideo = true;
mMediaRecorder.start();
Display.appendInfo("start record\n");
}
});
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
Toast.makeText(activity, "配置失败", Toast.LENGTH_SHORT).show();
mSession = null;
}
}, mBackgroundHandler);
} catch (CameraAccessException | IOException e) {
e.printStackTrace();
}
}
/**
* 设置录像参数
* @throws IOException
*/
private void setUpMediaRecorder() throws IOException {
if (mMediaRecorder == null) {
mMediaRecorder = new MediaRecorder();
}
CamcorderProfile profile = CamcorderProfile
.get(CamcorderProfile.QUALITY_480P);
Log.d(TAG,"setUpMediaRecorder--setUpMediaRecorder");
// mMediaRecorder.reset();
// mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);//设置音频源
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);//设置视频源: DEFAULT,Surface,Camera
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//设置视频输出格式: amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gpp
mMediaRecorder.setOutputFile(storageDirectory+"/VID_"+cameraId+".mp4");
// mMediaRecorder.setVideoEncodingBitRate(10000000);
mMediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);
mMediaRecorder.setVideoFrameRate(30);
// mMediaRecorder.setVideoSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mMediaRecorder.setVideoSize(profile.videoFrameWidth,
profile.videoFrameHeight);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setPreviewDisplay(msurfaceHolder.getSurface());
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
switch (cOrientation) {
case SENSOR_ORIENTATION_DEFAULT_DEGREES:
mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation));
break;
case SENSOR_ORIENTATION_INVERSE_DEGREES:
mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation));
break;
}
mMediaRecorder.prepare();
Log.d(TAG,"setUpMediaRecorder--prepare");
}
补充mediaRecoder API
主要根据各个状态和触发的条件进行状态转换,图上是一个状态机的实现的说明已经足够了,不过值得注意的是还有两个状态函数是pause()【暂停】和resume()【恢复】录制功能,图上没有的
1、创建:new MediaRecorder();
2、设置Camera:mRecorder.setCamera();
3、设置音频源(采集方式):mRecorder.setAudioSource();
4、设置视频源(采集方式):mRecorder.setVideoSource();
5、设置文件的输出格式:mRecorder.setOutputFormat();
6、设置Audio的编码格式(生成对应的编码器):mRecorder.setAudioEncoder();
7、设置Video的编码格式(生成对应的编码器):mRecorder.setVideoEncoder();
8、设置录制的视频编码比特率(每秒编码多少位bit):mRecorder.setVideoEncodingBitRate();
9、设置录制的视频帧率:mRecorder.setVideoFrameRate();
10、设置要捕获的视频的宽度和高度:mRecorder.setVideoSize();
11、设置记录会话的最大持续时间(毫秒):mRecorder.setMaxDuration();
12、设置一个Surface进行预览显示:mRecorder.setPreviewDisplay();
13、设置输出文件路径:mRecorder.setOutputFile();
14、准备录制:mRecorder.prepare();
15、开始录制:mRecorder.start();
16、暂停或恢复录制:mRecorder.pause()/resume();
17、停止录制:mRecorder.stop();
18、重置Recorder:mRecorder.reset();
19、释放Recorder资源:mRecorder.release();
另一个camera2 stopRecordingVideo问题java.lang.IllegalStateException
private void stopRecordingVideo() {
mIsRecordingVideo = false;
/**
* 添加这两句 可以解决stop时闪退问题
*/
Display.appendInfo("stop record\n");
try {
if(mSession!=null) {
mSession.stopRepeating();
mSession.abortCaptures();
}
} catch (CameraAccessException e) {
e.printStackTrace();
}
// Stop recording
try {
mMediaRecorder.stop();
} catch (IllegalStateException e) {
// TODO 如果当前java状态和jni里面的状态不一致,
mMediaRecorder = null;
mMediaRecorder = new MediaRecorder();
}
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
startPreview();
}
public void stopPreview() {
if (mSession == null || mPreviewBuilder == null) {
return;
}
if (mSession != null){
try {
mSession.stopRepeating();
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
}