[android camera2 api-通过套接字将预览帧传输到服务器

问题描述 投票:1回答:1

我浏览了android文档以及camera2basic存储库,并能够在TextureView上显示相机预览帧。我有两个按钮:一个可以录制视频,另一个可以捕获静态图像并将其存储在设备的内存中。我想要实现的是不同的东西,我想将所有摄像机帧通过套接字实时地顺序发送到服务器。我已将任务分解为较小的块,目前正在尝试将所有相机帧捕获为jpeg图像。这是CameraCaptureSession.CaptureCallback代码,据此,我调用savePreviewShot(),它实际上复制了Camera2basic存储库的原始captureStillPicture()函数:

private CameraCaptureSession.CaptureCallback mCaptureCallback
        = new CameraCaptureSession.CaptureCallback() {

    private void process(CaptureResult result) {
        switch (mState) {
            case STATE_PREVIEW: {
                // We have nothing to do when the camera preview is working normally.
                    savePreviewShot();
                break;
            }
            case STATE_WAITING_LOCK: {
                Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                if (afState == null) {
                    captureStillPicture();
                } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                        CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
                    // CONTROL_AE_STATE can be null on some devices
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null ||
                            aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                        mState = STATE_PICTURE_TAKEN;
                        captureStillPicture();
                    } else {
                        runPrecaptureSequence();
                    }
                }
                break;
            }
            case STATE_WAITING_PRECAPTURE: {
                // CONTROL_AE_STATE can be null on some devices
                Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                if (aeState == null ||
                        aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
                        aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
                    mState = STATE_WAITING_NON_PRECAPTURE;
                }
                break;
            }
            case STATE_WAITING_NON_PRECAPTURE: {
                // CONTROL_AE_STATE can be null on some devices
                Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
                    mState = STATE_PICTURE_TAKEN;
                    captureStillPicture();
                }
                break;
            }
        }
    }

这是savePreviewShot()函数:

private void savePreviewShot(){
    try {
        final Activity activity = getActivity();
        if (null == activity || null == mCameraDevice) {
            return;
        }
        // This is the CaptureRequest.Builder that we use to take a picture.
        final CaptureRequest.Builder captureBuilder =
                mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
        captureBuilder.addTarget(mImageReader.getSurface());

        // Orientation
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));

        CameraCaptureSession.CaptureCallback CaptureCallback
                = new CameraCaptureSession.CaptureCallback() {

            @Override
            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
                                           TotalCaptureResult result) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss:SSS");
                Date resultdate = new Date(System.currentTimeMillis());
                String mFileName = sdf.format(resultdate);
                mFile = new File(getActivity().getExternalFilesDir(null), "pic "+mFileName+" preview.jpg");

                Log.i("Saved file", ""+mFile.toString());
                unlockFocus();
            }
        };

        mCaptureSession.stopRepeating();
        mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
    } catch (Exception e) {
        e.printStackTrace();
    }
};

但是,正如您可能已经知道的那样,这样的调用在在地图上显示预览时会造成巨大的滞后,而且我也没有保存这些帧。希望您有我的目标和面临的问题。我已经在SO和Google上浏览了很多内容,但是没有一个对您有所帮助。

android sockets android-camera2
1个回答
0
投票

具有相同的确切问题,我想知道您是否已解决问题。我所做的是设置了ImageReader;

private ImageReader videoReader;
private final ImageReader.OnImageAvailableListener onVideoFrameAvailableListener

当我打开相机时将其加载

videoReader = ImageReader.newInstance(videoImageSize.getWidth(), videoImageSize.getHeight(), ImageFormat.JPEG, 2);
videoReader.setOnImageAvailableListener(onVideoFrameAvailableListener, backgroundHandler);

将Surface添加到captureSession并使用frame = reader.acquireLatestImage();在侦听器中处理了图像但是,是的,预览工作滞后很多,不知道解决方案可能是什么。

© www.soinside.com 2019 - 2024. All rights reserved.