Camera2实现录像过程拍照

本文详细介绍了在Android Camera2 API中如何在录像过程中实现拍照功能,重点讲解了Capture的单次模式、多次模式和重复模式,特别是重复模式在录像过程中的应用。通过暂停录像的重复模式,插入单次拍照请求,然后自动恢复录像,解决了录像拍照后导致的卡帧问题。代码示例展示了如何在录像session中无缝插入拍照操作。
摘要由CSDN通过智能技术生成

前言

  在开始这个功能之前,我们需要一些知识需要知道——对Captrue各个模式的一个理解。

Capture

  相机的所有操作和参数配置最终服务于捕获,在Camera2里面所有的相机操作和参数配置都被抽象成Captrue(捕获),切勿理解为拍照,因为使用Captrue也可能是开发者仅仅想对预览进行一个对焦。

  Captrue分为三种模式,分别是单次模式,多次模式,重复模式。这几个模式也很好理解,如果要举例来说的话单次模式最经典的运用就是拍照操作,而多次模式最经典的例子就是连拍操作,而对于重复模式,预览操作就能显示出其重复的特征,不断地去捕获画面。

  而在这里着重说一下重复模式,这也是本次实现录像过程拍照的关键知识点。重复模式指的是不断重复执行指定的Captrue操作,当有其他模式的Captrue提交时会暂停该模式,转而执行其他模式的captrue,当其他模式的Captrue执行完之后,会自动启动刚刚暂停的重复模式的Captrue,该模式的Captrue是全局唯一的,新提交的重复模式Captrue会覆盖旧的重复模式Captrue。

  重复模式会保留我们提交的CaptrueRequest对象用于不断重复执行Captrue操作,所以大多数情况下重复模式的CaptrueRequest和其他模式的CaptrueRequest是独立的。

  知道这些知识之后,我们便可以尝试录像过程进行拍照操作。其实本质上跟预览之后进行拍照的原理是一样的,都是从重复模式暂停执行单次模式的Captrue,执行完单次模式之后,系统会自动重启原先暂停的重复模式。 

问题描述

我先说一下我一开始的错误思路吧。我原本是想着当我录像点击拍照按钮的时候,执行一个方法,将执行录像的session会话停止关闭后,再打开一个用于拍照的session会话,在拍照结束后再打开一个录像的session会话。很明显这种方式从字面意思上就看得出,就算整个过程没有什么逻辑问题,最后也会产生两段录像,毕竟中间停止了一次嘛,后来那次相当于开了一个新的重复模式的Captrue。果不其然最后确实有问题,而且还不是我预想的问题,拍照完之后,录像结果跟预览从那帧开始一直卡帧。

解决方式

其实解决方法可以参考预览拍照功能进行一个解决。以下我们将通过代码直观的看看这个解决方法。简单来说就是在录像这个重复模式进行中的时候,提交一个捕获图像的单次模式,切勿将录像的session给关闭了,但捕获图像的单次模式执行完之后,session会自动重启之前录像的重复模式接着进行录制。

//首先对于一开始的录像session,需要发生一些改变
//可以看到surface列表需要加多一个mImageReader.getSurface()作为拍照的surface


mCameraDevice.createCaptureSession(Arrays.asList(previewsurface,mediaRcordSurface,
mImageReader.getSurface()),recordingStateCallback,mHandle);



//调用视频拍照方法
private void CaptureOneDuringRecording() {
    //准备开始设置录像截屏的captureRequestBuilder
  captureRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,CaptureRequest.CONTROL_AF_TRIGGER_START);
    if (isRecording){
        //正在录制,这是正确的
        try {
            mCaptureSession.capture(captureRequest.build(),newCameraCaptureSession.CaptureCallback() {

                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
                    super.onCaptureCompleted(session, request, result);
                    startStillCaptureRequest();
                }
            }, mHandle);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }
    else
    {
        //这是错误的,因为不拍的时候,不应该出现这个按钮
        try {
            throw new Exception("未拍照时,该方法不应该被调用");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

private void startStillCaptureRequest() {
    try {
        captureRequest=mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
        captureRequest.addTarget(mImageReader.getSurface());
        //先不设置照片方向
        captureRequest.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(myOrientoinListener.angle));
        mCaptureSession.capture(captureRequest.build(), new CameraCaptureSession.CaptureCallback() {
            @Override
            public void onCaptureStarted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, long timestamp, long frameNumber) {
                super.onCaptureStarted(session, request, timestamp, frameNumber);
            }
        },mHandle);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值