title: Camera2 recording video, Screen freeze after pressing the record button (only when using front camera and on certain devices)
body: <p>I have surfed all the internet and didn't find any solution, I am using Camera2 api to record a video from my front camera, I have tested on multiple devices and its working fine, but when I tried on my Samsung Galaxy 3, after I press the record button sometimes the recording work, and sometimes the camera preview freeze, you can find below the code I have implemented</p>
  <ol>
  <li>Create Preview and Record request by lazy loading</li>
  </ol>
  <pre><code>private val previewRequest: CaptureRequest? by lazy {
          mCaptureSession.device.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW).apply {
              addTarget(viewFinder.holder.surface)
          }.build()
      }
  
  
      private val recordRequest: CaptureRequest by lazy {
          mCaptureSession.device.createCaptureRequest(CameraDevice.TEMPLATE_RECORD).apply {
              addTarget(viewFinder.holder.surface)
              addTarget(mMediaRecorder.surface)
          }.build()
      }
  </code></pre>
  <ol start="2">
  <li>I am using AutoFitSurfaceView, onSurfaceCreated I'm doing the following:</li>
  </ol>
  <pre><code>when (cameraDirection) { // I am getting this variable to see what camera I should open
                      CameraDirection.BACK -&gt; { //getCameraPosition gets the cameraId for the given //LENS_FACING direction
                          mCameraId = getCameraPosition(CameraCharacteristics.LENS_FACING_BACK)
                      }
                      CameraDirection.FRONT -&gt; {
                          mCameraId = getCameraPosition(CameraCharacteristics.LENS_FACING_FRONT)
                      }
                      else -&gt; {
                          mCameraId = getCameraPosition(CameraCharacteristics.LENS_FACING_BACK)
                      }
                  }
                  characteristics = cameraManager.getCameraCharacteristics(mCameraId!!)
  
                  // Selects appropriate preview size and configures view finder
                  mPreviewSize = getPreviewOutputSize(
                      viewFinder.display, characteristics, SurfaceHolder::class.java
                  )
                  // Selects appropriate video size
                  mVideoSize = getPreviewOutputSize(
                      viewFinder.display, characteristics, MediaRecorder::class.java
                  )
                  viewFinder.setAspectRatio(mPreviewSize.width, mPreviewSize.height)
  
                  // To ensure that size is set, initialize camera in the view's thread
                  viewFinder.post {
                      initializeCamera()
                  }
  </code></pre>
  <ol start="3">
  <li>initializeCamera() function look like this</li>
  </ol>
  <pre><code>private fun initializeCamera() = lifecycleScope.launch(Dispatchers.Main) {
          //viewFinder is the AutoFitSurfaceView
          camera = openCamera(cameraManager, mCameraId!!, cameraHandler)
          setupMediaRecorder()
  
          val targets = listOf(viewFinder.holder.surface)
          camera.createCaptureSession(targets, object : CameraCaptureSession.StateCallback() {
              override fun onConfigured(session: CameraCaptureSession) {
                  mCaptureSession = session
                  session.setRepeatingRequest(previewRequest!!, null, cameraHandler)
              }
  
              override fun onConfigureFailed(session: CameraCaptureSession) {
  
              }
  
          }, cameraHandler)
      }
  </code></pre>
  <ol start="4">
  <li>openCamera() looks like the following</li>
  </ol>
  <pre><code>private suspend fun openCamera(
          manager: CameraManager,
          cameraId: String,
          handler: Handler? = null
      ): CameraDevice = suspendCancellableCoroutine { cont -&gt;
          manager.openCamera(cameraId, object : CameraDevice.StateCallback() {
              override fun onOpened(device: CameraDevice) = cont.resume(device)
  
              override fun onDisconnected(device: CameraDevice) {
                  finish()
              }
  
              override fun onError(device: CameraDevice, error: Int) {
                  val msg = when (error) {
                      ERROR_CAMERA_DEVICE -&gt; &quot;Fatal (device)&quot;
                      ERROR_CAMERA_DISABLED -&gt; &quot;Device policy&quot;
                      ERROR_CAMERA_IN_USE -&gt; &quot;Camera in use&quot;
                      ERROR_CAMERA_SERVICE -&gt; &quot;Fatal (service)&quot;
                      ERROR_MAX_CAMERAS_IN_USE -&gt; &quot;Maximum cameras in use&quot;
                      else -&gt; &quot;Unknown&quot;
                  }
                  val exc = RuntimeException(&quot;Camera $cameraId error: ($error) $msg&quot;)
                  if (cont.isActive) cont.resumeWithException(exc)
              }
          }, handler)
      }
  </code></pre>
  <ol start="5">
  <li>setupMediaRecorder() looks like this</li>
  </ol>
  <pre><code>private fun setupMediaRecorder() {
          mMediaRecorder = MediaRecorder()
          mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE)
          mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
          mMediaRecorder.setOutputFile(outputFile.absolutePath)
          Log.i(&quot;CAMERA_INFO&quot;, mCameraId!!)
          val profile = CamcorderProfile.get(mCameraId!!.toInt(), CamcorderProfile.QUALITY_LOW)
          Log.i(&quot;CAMERA_INFO&quot;, &quot;Frame Rate: &quot; + profile.videoFrameRate)
          mMediaRecorder.setVideoEncodingBitRate(profile.videoBitRate)
          mMediaRecorder.setVideoFrameRate(profile.videoFrameRate)
          mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height)
          mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264)
          when (mCameraDirection) {
              CameraDirection.BACK -&gt; {
                  mMediaRecorder.setOrientationHint(90)
              }
              CameraDirection.FRONT -&gt; {
                  mMediaRecorder.setOrientationHint(270)
              }
              else -&gt; {
  
              }
          }
          mMediaRecorder.prepare()
      }
  </code></pre>
  <p>Explanation:
  first initializeCamera() is called and in this function I am setting the Camera and the previewSession and preparing the MediaRecorder to start recording when the user press the record button</p>
  <p>After the user press on record button I am doing the following:</p>
  <ul>
  <li>Closing the previewSession</li>
  <li>Create the recordSession</li>
  <li>after the session is successfully configured, I am setting the recordRequest that I am initializing by lazy loading</li>
  </ul>
  <p>here is the following code:</p>
  <pre><code>button_record_video.setOnClickListener {
              mCaptureSession.close() //Closing the previewSession
              try {
  
                  camera.createCaptureSession( //Creating the record session passing the viewFinder surface //and the MediaRecorder session
                      listOf(
                          viewFinder.holder.surface,
                          mMediaRecorder.surface
                      ), object : CameraCaptureSession.StateCallback() {
                          override fun onConfigured(session: CameraCaptureSession) {
                              mCaptureSession = session
                              session.setRepeatingRequest(recordRequest, null, cameraHandler)
                              mMediaRecorder.start()
                          }
  
                          override fun onConfigureFailed(p0: CameraCaptureSession) {
  
                          }
  
                      }, cameraHandler
                  )
              } catch (e: Exception) {
  
              }
  
          }
  </code></pre>
  <p>PS: This code is working when capturing from the back camera as for the front camera its working on some devices and failing OCCASIONALLY on others (device tested that this code fail OCCASIONALLY Samsung Galaxy S3).</p>
  <p>Any more information needed, I can gladly provide
  Thanks in Advance</p>