Good day.
There was a need to create something like DVR, i.e. There are 2 buttons on the screen - start and stop. When you click on the start, the application should produce video recording (without preview) in 2-minute intervals and save them to a folder on the sd-card.
So, I ran into the problem of a smooth transition between the recorded segments. It is necessary that the end of one segment of the video and the beginning of the next should be almost without a break. Now the gap is about 2-3 seconds. Is it possible to somehow reduce it?
Record is in service, here is his code:
public class RecorderService extends Service { private static final String TAG = "RecorderService"; private SurfaceHolder mSurfaceHolder; private static Camera mServiceCamera; private boolean mRecordingStatus; private MediaRecorder mMediaRecorder; private Boolean isDestroy = false; private int VIDEO_DURATION = 0; @Override public void onCreate() { mRecordingStatus = false; //mServiceCamera = CameraRecorder.mCamera; mServiceCamera = Camera.open(); mSurfaceHolder = MainActivity.mSurfaceHolder; SharedPreferences sharedPreferences = getSharedPreferences("detail", MODE_PRIVATE); VIDEO_DURATION = sharedPreferences.getInt("duration", 1); super.onCreate(); if (!mRecordingStatus) { startRecording(); } } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onDestroy() { isDestroy = true; stopRecording(); try { mServiceCamera.reconnect(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } mServiceCamera.release(); mServiceCamera = null; super.onDestroy(); } public boolean startRecording() { try { //mServiceCamera = Camera.open(); Camera.Parameters params = mServiceCamera.getParameters(); mServiceCamera.setParameters(params); Camera.Parameters p = mServiceCamera.getParameters(); final List<Camera.Size> listSize = p.getSupportedPreviewSizes(); Camera.Size mPreviewSize = listSize.get(2); Log.v(TAG, "use: width = " + mPreviewSize.width + " height = " + mPreviewSize.height); p.setPreviewSize(mPreviewSize.width, mPreviewSize.height); p.setPreviewFormat(PixelFormat.YCbCr_420_SP); mServiceCamera.setParameters(p); try { mServiceCamera.setPreviewDisplay(mSurfaceHolder); mServiceCamera.startPreview(); } catch (IOException e) { Log.e(TAG, e.getMessage()); e.printStackTrace(); } mServiceCamera.unlock(); mMediaRecorder = new MediaRecorder(); mMediaRecorder.setCamera(mServiceCamera); mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); mMediaRecorder.setOutputFile(getOutputMediaFile(this).toString()); mMediaRecorder.setVideoFrameRate(30); mMediaRecorder.setVideoSize(640, 480); mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface()); mMediaRecorder.prepare(); mMediaRecorder.start(); Log.d(TAG, "Recording Started"); mRecordingStatus = true; new Handler().postDelayed(new Runnable() { @Override public void run() { if (!isDestroy) { stopRecording(); startRecording(); } } }, VIDEO_DURATION * 60 * 1000); return true; } catch (IllegalStateException e) { Log.d(TAG, e.getMessage()); e.printStackTrace(); return false; } catch (IOException e) { Log.d(TAG, e.getMessage()); e.printStackTrace(); return false; } } public void stopRecording() { if (mRecordingStatus) { mRecordingStatus = false; try { mMediaRecorder.stop(); } catch (RuntimeException e) { e.printStackTrace(); } Log.d(TAG, "Recording Stopped"); mMediaRecorder.reset(); mServiceCamera.stopPreview(); mMediaRecorder.release(); } } }