相机服务录制

时间:2017-10-18 22:35:52

标签: android android-service android-camera2

我目前正在使用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 个答案:

答案 0 :(得分:1)

如果你再也不想让预览工作了,你可以简单地创建一个新的预览请求,而不是在TextureView消失后将previewSurface添加到其中。

如果您希望以后不间断地连接预览,那就更复杂了。一种选择是从您自己的SurfaceTexture开始,并使用其attachToGlContext / detachFromGlContext调用以及GLSurfaceView或类似的。

然后,您可以使用SurfaceTexture配置会话,并且每当您想要显示预览时,将其附加到GLSurfaceView的GL上下文并将Surface添加到预览请求目标。然后,当您想要停止显示预览时,从预览目标中移除Surface,并将其从GLSurfaceView中分离。

这需要你自己的GL绘图代码(基本上你自己的迷你TextureView具有自定义行为),所以它是很多样板,但它是简单的EGL(只需要在其上绘制带有预览纹理的四边形)。