MediaRecorder start () error when calling too fast

I am trying to create a basic video camera that allows the user to quickly shoot video by touching the screen, it seemed straightforward, however, the main problem I encountered was that Android MediaRecorder does not allow to quickly start and restart without crashing if the user shoots, and then stops, and then quickly resumes shooting, it always fails. Im not sure if there is a way to fix this directly, so I also developed another method to achieve this, trying to record one video, but trying to get some control when mediaRecorder actually writes to a file. however, I could not completely run this file using FileDescriptor, below I will insert my original code and my method, which I used in the second attempt to control the recording, is there any way to configure any code to achieve this pause function after? any help goes a long way thanks

My first attempt to use the general way to set a file in setOutPutFile ():

public class MainActivity extends Activity implements SurfaceHolder.Callback { public static final String LOGTAG = "VIDEOCAPTURE"; private MediaRecorder recorder; private SurfaceHolder holder; private CamcorderProfile camcorderProfile; private Camera camera; boolean recording = false; boolean usecamera = true; boolean previewRunning = false; double timer = 0; ProgressBar pb; boolean neverEnd; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_LOW); setContentView(R.layout.activity_main); pb = (ProgressBar) findViewById(R.id.progressBar1); pb.setProgress(0); SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView); holder = cameraView.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); cameraView.setClickable(true); cameraView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { recording = true; new recordVideo().execute(); Log.v(LOGTAG, "Recording Started"); return true; } else if (event.getAction() == MotionEvent.ACTION_UP) { recording = false; return true; } return false; } }); } private void prepareRecorder() { recorder = new MediaRecorder(); recorder.setPreviewDisplay(holder.getSurface()); if (usecamera) { camera.unlock(); recorder.setCamera(camera); } recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); recorder.setProfile(camcorderProfile); Calendar calendarTime = Calendar.getInstance(); //initial attempt using a file path with setoutputfile File file = new File(Environment.getExternalStorageDirectory(), String.valueOf(calendarTime.getTimeInMillis()) + ".mp4"); if (camcorderProfile.fileFormat == MediaRecorder.OutputFormat.THREE_GPP) { recorder.setOutputFile(file.getAbsolutePath()); } else if (camcorderProfile.fileFormat == MediaRecorder.OutputFormat.MPEG_4) { recorder.setOutputFile(file.getAbsolutePath()); } else { recorder.setOutputFile(file.getAbsolutePath()); } // recorder.setMaxDuration(50000); // 50 seconds // recorder.setMaxFileSize(5000000); // Approximately 5 megabytes boolean initialized = false; while (!initialized) { try { recorder.prepare(); initialized = true; } catch (IllegalStateException e) { e.printStackTrace(); // finish(); initialized = false; } catch (IOException e) { e.printStackTrace(); // finish(); initialized = false; } } } public void surfaceCreated(SurfaceHolder holder) { Log.v(LOGTAG, "surfaceCreated"); if (usecamera) { camera = Camera.open(); try { camera.setPreviewDisplay(holder); camera.startPreview(); previewRunning = true; } catch (IOException e) { Log.e(LOGTAG, e.getMessage()); e.printStackTrace(); } } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.v(LOGTAG, "surfaceChanged"); if (!recording && usecamera) { if (previewRunning) { camera.stopPreview(); } try { Camera.Parameters p = camera.getParameters(); p.setPreviewSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight); p.setPreviewFrameRate(camcorderProfile.videoFrameRate); camera.setParameters(p); camera.setPreviewDisplay(holder); camera.startPreview(); previewRunning = true; } catch (IOException e) { Log.e(LOGTAG, e.getMessage()); e.printStackTrace(); } prepareRecorder(); } } public void surfaceDestroyed(SurfaceHolder holder) { Log.v(LOGTAG, "surfaceDestroyed"); if (recording) { recorder.stop(); recording = false; } recorder.release(); if (usecamera) { previewRunning = false; // camera.lock(); camera.release(); } finish(); } private class recordVideo extends AsyncTask<Void, Integer, Void> { @Override protected Void doInBackground(Void... params) { // TODO Auto-generated method stub try { recorder.start(); while (recording) { Thread.sleep(100); publishProgress(); } recorder.stop(); recorder.release(); recorder = null; // recorder.release(); Log.v(LOGTAG, "Recording Stopped"); // Let prepareRecorder so we can record again prepareRecorder(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override protected void onProgressUpdate(Integer... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); if (recording) { timer += 0.1; pb.setProgress((int) (timer * 10)); } } } } 

Here is my method using FileDescriptor, it did not work, only created the file, but did not write it:

 //Pass it into setOutputFile() like this recorder.setOutputFile(getStreamFd()); private FileDescriptor getStreamFd() { ParcelFileDescriptor pipe = null; try { Calendar calendarTime = Calendar.getInstance(); File file = new File(Environment.getExternalStorageDirectory(), String.valueOf(calendarTime.getTimeInMillis()) + ".mp4"); pipe = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_APPEND | ParcelFileDescriptor.MODE_WORLD_WRITEABLE); byte[] buf = new byte[1024]; int len; FileOutputStream out = new FileOutputStream(FileDescriptor.out); InputStream is = new FileInputStream(FileDescriptor.in); while (usecamera) { if(recordng){ out.write(buf, 0, len); } } is.close(); out.close(); } catch (IOException e) { Log.e(getClass().getSimpleName(), "Exception opening pipe", e); } return pipe.getFileDescriptor(); } 
+6
source share
1 answer

Call cameraView.setClickable (true) after receiving Recorder () and call cameraView.setClickable (false) before calling prepareRecorder () in AsynkTask

0
source

Source: https://habr.com/ru/post/946962/


All Articles