1) Set up storage location. Make sure the file names dont clash
// set up storage location
private File mVideoFolder;
private File mVideoFile;
private String mVideofileName;
// to be called under onCreate
private void createVideoFolder(){
// get the storage dir for movies
File moviewFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
// create a new directory for your app under this directory
mVideoFolder = new File(moviewFile, "camera2videoImage");
if(!mVideoFolder.exists())
mVideoFolder.mkdirs();
}
// to be called when recording has been started
private void createVideoFileName(){
//create unique name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String prepend = "VIDEO_" + timeStamp + "_";
File videoFile = null;
try {
videoFile = File.createTempFile(prepend, ".mp4", mVideoFolder);
} catch (IOException e) {
e.printStackTrace();
}
mVideofileName = videoFile.getAbsolutePath();
mVideoFile = videoFile;
}
2) Set up media recorder. First get the video size for media recorder in setUpCamera
In setUpCamera
mTotalRotation = calcSize.totalRotation; mVideoSize = calcSize.chooseOptimalSize(map.getOutputSizes(MediaRecorder.class));MediaRecorder setup
private MediaRecorder mMediaRecorder;
// to be called when recording have to be saved
private void setUpMediaRecorder(){
// the order is important
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setOutputFile(mVideofileName);
mMediaRecorder.setVideoEncodingBitRate(1000000);
mMediaRecorder.setVideoFrameRate(24);
mMediaRecorder.setVideoSize(mVideoSize.getWidth(), mVideoSize.getHeight());
//mMediaRecorder.setVideoSize(640, 480);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mMediaRecorder.setOrientationHint(mTotalRotation);
try {
mMediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}
3) Create Capture Request for recording. (This should replace the CaptureRequestBuilder from preview)
private void startRecord(){
if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
Toast.makeText(this,"No permission to access storage", Toast.LENGTH_SHORT).show();
return;
}
createVideoFileName();
setUpMediaRecorder();
// record surface
Surface recordSurface = mMediaRecorder.getSurface();
//surface to preview recording
SurfaceTexture surfaceTexture = mTextureView.getSurfaceTexture();
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
Surface previewSurface = new Surface(surfaceTexture);
try {
mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
mCaptureRequestBuilder.addTarget(previewSurface);
mCaptureRequestBuilder.addTarget(recordSurface);
mCameraDevice.createCaptureSession(Arrays.asList(previewSurface, recordSurface),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
session.setRepeatingRequest(mCaptureRequestBuilder.build(),null,mBAckgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
mMediaRecorder.start();
}
});
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {
}
}, null);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
4) When recoding is stopped, reset MediaRecorder and start the preview
private void stopRecord(){
if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
mMediaRecorder.stop();
mMediaRecorder.reset();
// open an alert dialog. delete file if save is not intended
saveVideo();
//revert back to preview mode
startPreview();
}
}
5) Recording request should be started when record button is clicked.
Under onCreate
mRecordButton = (ImageButton) findViewById(R.id.imageButton2);
mRecordButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(mIsRecording){
mIsRecording = false;
mRecordButton.setImageResource(android.R.drawable.presence_video_online);
stopRecord();
}else{
mIsRecording = true;
mRecordButton.setImageResource(android.R.drawable.presence_video_busy);
startRecord();
}
}
});