Camera1、Camera2、CameraX

Camera 1 / 2 /x介绍

Camera1 在5.0以前系统上使用、使用方法也很简单

Camera.open()打开摄像头,获取当前设备的摄像头个数,根据id打开摄像头,如果想要做视频直播的话,在设置预览回调,设置预览buffer,设置摄像头采集视频流格式、一般采集格式Nv21,android标准采集方式、在预览回调里取出预览buff,然后转换yuv数据,交给ffmpeg软编成H264数据或者通过MediaCodec硬编成H264、发送给服务器
基本上这就是camera采集数据方式

之前做过android智慧平板项目,由于系统5.0以上的比较少、所以也就一直使用camera1版本,另外扩展和借鉴的是外国大神的OpenCamera 并在Camera1上做了许多扩展 、查看地址

Camera2是5.0时,谷歌针对摄像头新推出的一套api
通过获取CameraService获取CameraManagr,并通过CameraManager.openCamera方法打开camera,并注册camera开启监听回调,新增了ImageReader设置,并通过ImageReader设置监听,通过监听回调拿到ImageReader获取的预览buffer,并拿出buffer 之后操作差不多

CameraX是jetpack的一个支持库、提供的方法

// CameraX core library.
implementation "androidx.camera:camera-core:1.0.0"
// If you want to use Camera2 extensions.
implementation "androidx.camera:camera-camera2:1.0.0"
implementation "androidx.camera:camera-lifecycle:1.0.0"

//other
// If you to use the Camera View class
implementation "androidx.camera:camera-view:1.0.0-alpha24"
// If you to use Camera Extensions
implementation "androidx.camera:camera-extensions:1.0.0-alpha24"
复制代码
 private fun startCamera() {
        //获取CameraProvider
        val cameraProviderFuture  = ProcessCameraProvider.getInstance(this)

        //添加监听
        cameraProviderFuture.addListener(Runnable {
            获取cameraProvider
            val cameraProvider = cameraProviderFuture.get()
            //设置imageCapturem模式初始化
            imageCapture = ImageCapture.Builder().setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY).build()
            //设置预览监听并把预览buffer,通过自定义接口回调出来byteBuffer
            imageAnalyzer = ImageAnalysis.Builder()
                .build()
                .also {
                    it.setAnalyzer(cameraExecutor,ImageAnalysis.Analyzer { image ->
                        val rotationDegrees = image.imageInfo.rotationDegrees
                        val buffer = image.planes[0].buffer as ByteBuffer
                        //拿到buffer处理成自己需要的就行了
                        image.close()
                    })
                }

            
            preview = Preview.Builder().build()

            val cameraSelector =
                CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build()

            cameraProvider.unbindAll()
            //绑定cameraProvider生命周期 
            camera = cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageCapture,imageAnalyzer)
            //1.0.0版本surfaceProvider系同已经创建好了
            preview?.setSurfaceProvider(viewFinder.surfaceProvider)


        }, ContextCompat.getMainExecutor(this))

    }

复制代码
//获取CameraProvider
val cameraProviderFuture  = ProcessCameraProvider.getInstance(this)


//源码方法
@NonNull
public static ListenableFuture<ProcessCameraProvider> getInstance(
        @NonNull Context context) {
    
    return Futures.transform(CameraX.getOrCreateInstance(context), cameraX ->  {
        sAppInstance.setCameraX(cameraX);
        return sAppInstance;
    }, CameraXExecutors.directExecutor());
}


@RestrictTo(Scope.LIBRARY_GROUP)
@NonNull
public static ListenableFuture<CameraX> getOrCreateInstance(@NonNull Context context) {
    Preconditions.checkNotNull(context, "Context must not be null.");
    synchronized (INSTANCE_LOCK) {
        boolean isConfigured = sConfigProvider != null;
        ListenableFuture<CameraX> instanceFuture = getInstanceLocked();
        if (instanceFuture.isDone()) {
            try {
                instanceFuture.get();
            } catch (InterruptedException e) {
                // Should not be possible since future is complete.
                throw new RuntimeException("Unexpected thread interrupt. Should not be "
                        + "possible since future is already complete.", e);
            } catch (ExecutionException e) {
                // Either initialization failed or initialize() has not been called, ensure we
                // can try to reinitialize.
                shutdownLocked();
                instanceFuture = null;
            }
        }

        if (instanceFuture == null) {
            if (!isConfigured) {
                // Attempt initialization through Application or Resources
                CameraXConfig.Provider configProvider = getConfigProvider(context);
                if (configProvider == null) {
                    throw new IllegalStateException("CameraX is not configured properly. "
                            + "The most likely cause is you did not include a default "
                            + "implementation in your build such as 'camera-camera2'.");
                }

                configureInstanceLocked(configProvider);
            }
            //初始化cameraX方法
            initializeInstanceLocked(context);
            instanceFuture = getInstanceLocked();
        }

        return instanceFuture;
    }
}

@GuardedBy("INSTANCE_LOCK")
private static void initializeInstanceLocked(@NonNull Context context) {
    Preconditions.checkNotNull(context);
    Preconditions.checkState(sInstance == null, "CameraX already initialized.");
    Preconditions.checkNotNull(sConfigProvider);
    //初始化camerax
    CameraX cameraX = new CameraX(sConfigProvider.getCameraXConfig());
    sInstance = cameraX;
    sInitializeFuture = CallbackToFutureAdapter.getFuture(completer -> {
        synchronized (INSTANCE_LOCK) {
            // The sShutdownFuture should always be successful, otherwise it will not
            // propagate to transformAsync() due to the behavior of FutureChain.
            ListenableFuture<Void> future = FutureChain.from(sShutdownFuture)
                    .transformAsync(input -> cameraX.initInternal(context),
                            CameraXExecutors.directExecutor());

            Futures.addCallback(future, new FutureCallback<Void>() {
                @Override
                public void onSuccess(@Nullable Void result) {
                    completer.set(null);
                }

                @SuppressWarnings("FutureReturnValueIgnored")
                @Override
                public void onFailure(Throwable t) {
                    Logger.w(TAG, "CameraX initialize() failed", t);
                    // Call shutdown() automatically, if initialization fails.
                    synchronized (INSTANCE_LOCK) {
                        // Make sure it is the same instance to prevent reinitialization
                        // during initialization.
                        if (sInstance == cameraX) {
                            shutdownLocked();
                        }
                    }
                    completer.setException(t);
                }
            }, CameraXExecutors.directExecutor());
            return "CameraX-initialize";
        }
    });
}
复制代码

preview?.setSurfaceProvider(viewFinder.surfaceProvider)

使用PreviewViews视图创建预览方法时,系统已经给我们创建好了一个Preview.SurfaceProvider()直接绑定就行了

  // Synthetic access
    @SuppressWarnings("WeakerAccess")
    final Preview.SurfaceProvider mSurfaceProvider = new Preview.SurfaceProvider() {

        @OptIn(markerClass = ExperimentalUseCaseGroup.class)
        @Override
        @AnyThread
        public void onSurfaceRequested(@NonNull SurfaceRequest surfaceRequest) {
            if (!Threads.isMainThread()) {
                // Post on main thread to ensure thread safety.
                ContextCompat.getMainExecutor(getContext()).execute(
                        () -> mSurfaceProvider.onSurfaceRequested(surfaceRequest));
                return;
            }
            Logger.d(TAG, "Surface requested by Preview.");
            CameraInternal camera = surfaceRequest.getCamera();
            surfaceRequest.setTransformationInfoListener(
                    ContextCompat.getMainExecutor(getContext()),
                    transformationInfo -> {
                        Logger.d(TAG,
                                "Preview transformation info updated. " + transformationInfo);
                        // TODO(b/159127402): maybe switch to COMPATIBLE mode if target
                        //  rotation is not display rotation.
                        boolean isFrontCamera =
                                camera.getCameraInfoInternal().getLensFacing()
                                        == CameraSelector.LENS_FACING_FRONT;
                        mPreviewTransform.setTransformationInfo(transformationInfo,
                                surfaceRequest.getResolution(), isFrontCamera);
                        redrawPreview();
                    });

            mImplementation = shouldUseTextureView(surfaceRequest, mImplementationMode)
                    ? new TextureViewImplementation(PreviewView.this, mPreviewTransform)
                    : new SurfaceViewImplementation(PreviewView.this, mPreviewTransform);

            PreviewStreamStateObserver streamStateObserver =
                    new PreviewStreamStateObserver(camera.getCameraInfoInternal(),
                            mPreviewStreamStateLiveData, mImplementation);
            mActiveStreamStateObserver.set(streamStateObserver);

            camera.getCameraState().addObserver(
                    ContextCompat.getMainExecutor(getContext()), streamStateObserver);
            mImplementation.onSurfaceRequested(surfaceRequest, () -> {
                // We've no longer needed this observer, if there is no new StreamStateObserver
                // (another SurfaceRequest), reset the streamState to IDLE.
                // This is needed for the case when unbinding preview while other use cases are
                // still bound.
                if (mActiveStreamStateObserver.compareAndSet(streamStateObserver, null)) {
                    streamStateObserver.updatePreviewStreamState(StreamState.IDLE);
                }
                streamStateObserver.clear();
                camera.getCameraState().removeObserver(streamStateObserver);
            });
        }
    };

复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享