2017-10-18 88 views
0

我目前正在使用camera2 api在服务中录制视频。摄像机服务记录

我不能找到一种方法,当预览面被破坏更新camerasession的输出列表。换句话说:当一个表面被销毁时(例如当活动在后台进行时)如何进行以保持记录并避免由于空表面造成的崩溃。

这是我如何开始视频录制。

private void startRecordingVideo() { 
    if (null == mCameraDevice || null == mPreviewSize) { 
     return; 
    } 
    try { 
     closePreviewSession(); 
     setUpMediaRecorder(); 

     mPreviewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); 
     List<Surface> surfaces = new ArrayList<>(); 
     if(mTextureView !=null) { 
      SurfaceTexture texture = mTextureView.getSurfaceTexture(); 
      assert texture != null; 
      texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());   // Set up Surface for the camera preview 
      previewSurface = new Surface(texture); 
      surfaces.add(previewSurface); 
      mPreviewBuilder.addTarget(previewSurface); 
     } 

     // Set up Surface for the MediaRecorder 
     Surface recorderSurface = mMediaRecorder.getSurface(); 
     surfaces.add(recorderSurface); 
     mPreviewBuilder.addTarget(recorderSurface); 

     // Start a capture session 
     // Once the session starts, we can update the UI and start recording 
     mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { 
      @Override 
      public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) { 
       mPreviewSession = cameraCaptureSession; 
       updatePreview(); 
       mMediaRecorder.start(); 
      } 

      @Override 
      public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { 
       Timber.e("Error when creating captureSession"); 
      } 
     }, mBackgroundHandler); 
    } catch (CameraAccessException | IOException e) { 
     e.printStackTrace(); 
    } 

} 

当我将活动发送到后台时:预览表面被破坏,这是我奋斗的地方。我应该如何更新我的capturesession,以便从会话输出中删除预览表面而不停止捕获进程?

回答

1

如果您不希望有再次预览工作,你可以简单地创建一个新的预览请求,而不是添加的previewSurface进去,一旦TextureView不见了。

如果你想稍后连接起来预览没有中断,这是更为复杂。一种选择是从你自己的SurfaceTexture开始,并使用它的attachToGlContext/detachFromGlContext调用以及GLSurfaceView或类似的。

然后你可以用表面纹理配置会话,每当你要显示预览,将其附加到GLSurfaceView的GL上下文和表面添加到您的预览请求的目标。然后,当您想要停止显示预览时,从预览目标中移除Surface并将其从GLSurfaceView中分离。这需要有你自己的GL绘图代码(基本上是你自己的迷你TextureView自定义行为),所以它是很多样板,但它是简单的EGL(只需要绘制一个具有预览纹理的四边形)。