title: Record video from an already-running preview
body: <p>Greetings fellow Androiders. I'm developing an app that uses the camera to display a continuous preview, and when the user would like to, record video from that feed and save it.</p>
  
  <p>The first part I have set up, but I am having issues getting the recording to work. I've followed various guides and answers to the problems I'm hitting, but I always seem to run into an "invalid state" problem (currently setCamera called in an invalid state(4)).</p>
  
  <p>This is my complete code. Thank you for taking a look!</p>
  
  <pre><code>Camera camera;
  SurfaceView preview;
  SurfaceHolder previewHolder;
  MediaRecorder recorder;
  boolean recording = false;
  boolean cameraConfigured = false;
  private Button camera_button;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) 
  {
      super.onCreate(savedInstanceState);
  
      //Remove title bar
      this.requestWindowFeature(Window.FEATURE_NO_TITLE);
  
      //Remove notification bar
      this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  
      //Keep screen awake
      this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  
      setContentView(R.layout.activity_fullscreen);
  
      preview = (SurfaceView)findViewById(R.id.camerapreview);        
      previewHolder = preview.getHolder();
      previewHolder.addCallback(surfaceCallback);
      previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  
      camera_button = (Button) findViewById(R.id.camera_button);
  
      camera_button.setOnClickListener(new OnClickListener()
      {
          @Override
          public void onClick(View view)
          {
              if (recording) 
              {
                  recorder.stop();
                  recording = false;
  
                  initRecorder();
                  prepareRecorder();
  
                  camera_button.setText("Record");
              } 
              else 
              {
                  recording = true;
                  recorder.start();
  
                  camera_button.setText("Stop");
              }
          }
      });
  
      // Wake screen
      WakeLock screenLock = ((PowerManager)getSystemService(POWER_SERVICE)).newWakeLock(
               PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "TAG");
      screenLock.acquire();
      screenLock.release();
  }
  
  @Override
  public void onResume() 
  {     
      super.onResume();
  
      if (camera == null) 
      {
          camera = Camera.open();         
      }
  
      preview.setVisibility(View.VISIBLE);
      startPreview();
  }
  
  @Override
  public void onPause() 
  {       
      if(camera != null)
      {           
          camera.stopPreview();
          camera.release();
          camera = null;
          cameraConfigured = false;           
      }
  
      preview.setVisibility(View.INVISIBLE);
  
      super.onPause();
  }
  
  SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() 
  {
      public void surfaceCreated(SurfaceHolder holder) 
      {
          initRecorder();
          prepareRecorder();          
      }
  
      public void surfaceChanged(SurfaceHolder holder, int format,
                                 int width, int height)
      {
          initPreview(width, height);
          startPreview();
      }
  
      public void surfaceDestroyed(SurfaceHolder holder) 
      {
          if (recording) 
          {
              recorder.stop();
              recording = false;
          }
          recorder.release();
      }
  };
  
  
  private void initRecorder() 
  {
      recorder = new MediaRecorder();     
  
      recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
      recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
  
      CamcorderProfile cpHigh = CamcorderProfile
              .get(CamcorderProfile.QUALITY_HIGH);
      recorder.setProfile(cpHigh);
  
      String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
      recorder.setOutputFile("/sdcard" + File.separator + "testVideo_" + timeStamp + ".mp4");  
  
      camera.unlock();
      recorder.setCamera(camera);
  }
  
  private void prepareRecorder() 
  {
      recorder.setPreviewDisplay(previewHolder.getSurface());
  
      try 
      {
          recorder.prepare();
      } 
      catch (IllegalStateException e) 
      {
          e.printStackTrace();
  
      } 
      catch (IOException e) 
      {
          e.printStackTrace();
  
      }
  }
  
  private void initPreview(int width, int height) 
  {
      if (camera != null &amp;&amp; previewHolder.getSurface() != null) 
      {
          try 
          {
              camera.setPreviewDisplay(previewHolder);
          }
          catch (Throwable t) 
          {
              Log.e("CameraTest","");
          }
  
          if (!cameraConfigured)
          {
              Camera.Parameters parameters=camera.getParameters();
              Camera.Size size = getBestPreviewSize(width, height, parameters);
              Camera.Size pictureSize = getSmallestPictureSize(parameters);
  
              if (size != null &amp;&amp; pictureSize != null) 
              {
                  parameters.setPreviewSize(size.width, size.height);
                  parameters.setPictureSize(pictureSize.width,
                                              pictureSize.height);
  
                  parameters.set("cam_mode", 1 );
                  parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
                  parameters.setPictureFormat(ImageFormat.JPEG);
                  camera.setParameters(parameters);
                  cameraConfigured=true;
              }
          }
      }           
  }
  
  private void startPreview() 
  {
      if (cameraConfigured &amp;&amp; camera != null) 
      {
          camera.startPreview();
      }
  }
  
  public Camera.Size getBestPreviewSize(int width, int height,
          Camera.Parameters parameters) 
  {       
      Camera.Size result=null;
  
      for (Camera.Size size : parameters.getSupportedPreviewSizes()) 
      {
          if ((size.width &lt;= width &amp;&amp; size.height &lt;= height) || (size.height &lt;= width &amp;&amp; size.width &lt;= height)) 
          {
              if (result == null) 
              {
                  result=size;
              }
              else 
              {
                  int resultArea=result.width * result.height;
                  int newArea=size.width * size.height;
  
                      if (newArea &gt; resultArea) 
                      {
                          result=size;
                      }
              }
          }
      }
  
      return(result);
  
  
  }
  
  public Camera.Size getSmallestPictureSize(Camera.Parameters parameters) 
  {
      Camera.Size result=null;
  
      for (Camera.Size size : parameters.getSupportedPictureSizes()) 
      {
          if (result == null) 
          {
              result=size;
          }
          else 
          {
              int resultArea=result.width * result.height;
              int newArea=size.width * size.height;
  
              if (newArea &lt; resultArea) 
              {
                  result=size;
              }
          }
      }
      return(result);
  }
  </code></pre>