UVCAndroid,安卓UVC相机通用开发库(支持多预览和多摄像头)

Posted kanseei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVCAndroid,安卓UVC相机通用开发库(支持多预览和多摄像头)相关的知识,希望对你有一定的参考价值。

文章目录

简介

UVCandroid是一款用于安卓UVC相机的通用开发库。

GitHub源码地址https://github.com/shiyinghan/UVCAndroid

主要功能

主要功能包括:
(1) 支持USB Camera设备检测,画面实时预览;
(2) 支持抓拍jpg格式图片,可设置图片压缩质量;
(3) 支持录制mp4格式视频,可屏蔽音频,可设置视频和音频的录制参数;
(4) 支持获取camera支持的分辨率,和分辨率切换;
(5) 支持预览自动识别各种相机的分辨率;
(6) 支持旋转摄像头90度、180度、270度
(7) 支持调整对比度、亮度、色调、饱和度、白平衡等等一些相机控制参数;
(8) 支持多预览和多摄像头;
(9) 支持Android5.0+;

如何使用

1. 添加依赖到本地工程

第一步 添加mavenCentral仓库到工程gradle文件
Step 1. Add the mavenCentral repository to your build file
Add it in your root build.gradle at the end of repositories:

allprojects 
    repositories 
		...
		mavenCentral()
    

第二步 添加依赖到app Module的gradle文件

dependencies 
    implementation 'com.herohan:UVCAndroid:1.0.4'

2. 获取权限

Request permissions

 	List<String> needPermissions = new ArrayList<>();
    needPermissions.add(Manifest.permission.CAMERA);
    needPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);//拍照和录制视频时需要该权限
    //needPermissions.add(Manifest.permission.MANAGE_EXTERNAL_STORAGE); //Android 11 使用该权限替代 WRITE_EXTERNAL_STORAGE
    needPermissions.add(Manifest.permission.RECORD_AUDIO);//录制视频时需要音频时需要该权限

	//这里使用XXPermissions开源框架获取权限,你也可以使用系统原生的,或者其他开源框架获取权限
    XXPermissions.with(this)
            .permission(needPermissions)
            .request((permissions, all) -> 
                if(!all)
                    return;
                
	
	//摄像头业务操作
           );
<application
	...
	android:requestLegacyExternalStorage="true"
	>

3. 初始化UVC业务类,设置UVC摄像头状态回调,设置TextureView或者SurfaceView的Surface监听回调

Initialize CameraHelper,set UVC Camera state callback

 private ICameraHelper mCameraHelper;
 private AspectRatiosurfaceView mCameraViewMain;
 private ICameraHelper.StateCallback mStateListener;

	//UVC摄像头状态回调
	mStateListener = new ICameraHelper.StateCallback() 
		//插入UVC设备
        @Override
        public void onAttach(UsbDevice device) 
        	//设置为当前设备(如果没有权限,会显示授权对话框)
            mCameraHelper.selectDevice(device);
        

		//打开UVC设备成功(也就是已经获取到UVC设备的权限)
        @Override
        public void onDeviceOpen(UsbDevice device, boolean isFirstOpen) 
        	//打开UVC摄像头
            mCameraHelper.openCamera();
        

		//打开摄像头成功
        @Override
        public void onCameraOpen(UsbDevice device) 
        	//开始预览
            mCameraHelper.startPreview();

			//获取预览使用的Size(包括帧格式、宽度、高度、FPS)
            Size size = mCameraHelper.getPreviewSize();
            if (size != null) 
                int width = size.width;
                int height = size.height;
                //需要自适应摄像头分辨率的话,设置新的宽高比
                mCameraViewMain.setAspectRatio(width, height);
            

			//添加预览Surface
            mCameraHelper.addSurface(mCameraViewMain.getHolder().getSurface(), false);
        

		//关闭摄像头成功
        @Override
        public void onCameraClose(UsbDevice device) 
            if (mCameraHelper != null) 
            	//移除预览Surface
                mCameraHelper.removeSurface(mCameraViewMain.getHolder().getSurface());
            
        

		//关闭UVC设备成功
        @Override
        public void onDeviceClose(UsbDevice device) 
        

		//断开UVC设备
        @Override
        public void onDetach(UsbDevice device) 
        

		//用户没有授予访问UVC设备的权限
        @Override
        public void onCancel(UsbDevice device) 
        

    ;
    
    //设置SurfaceView的Surface监听回调
    mCameraViewMain.getHolder().addCallback(new SurfaceHolder.Callback() 
    
    		//创建了新的Surface
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) 
                if (mCameraHelper != null) 
                	//添加预览Surface
                    mCameraHelper.addSurface(holder.getSurface(), false);
                
            
			
			//Surface发生了改变
            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) 
            

			//销毁了原来的Surface
            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) 
                if (mCameraHelper != null) 
                	//移除预览Surface
                    mCameraHelper.removeSurface(holder.getSurface());
                
            
        );
        
		mCameraHelper = new CameraHelper();
		//设置UVC摄像头状态回调
        mCameraHelper.setStateCallback(mStateListener);

4. 释放UVC业务类(包含取消UVC摄像头状态回调,停止Camera预览,关闭Camera等操作)

Release CameraHelper(including canceling UVC Camera state callback, stopping Camera preview, etc.)

 mCameraHelper.release();

5. 图片抓拍

Image Capture

	//设置视图片抓拍全局参数(非必须,可以不设置,使用默认值)
	mCameraHelper.setImageCaptureConfig(
                mCameraHelper.getImageCaptureConfig().setCaptureMode(ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY));
//        mCameraHelper.setImageCaptureConfig(
//                mCameraHelper.getImageCaptureConfig().setJpegCompressionQuality(90));

	//设置需要保存图片文件
 	File file = FileUtils.getCaptureFile(this, Environment.DIRECTORY_DCIM, ".jpg");
    ImageCapture.OutputFileOptions options =
             new ImageCapture.OutputFileOptions.Builder(file).build();

//                ContentValues contentValues = new ContentValues();
//                contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "NEW_IMAGE");
//                contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
//
//                ImageCapture.OutputFileOptions options = new ImageCapture.OutputFileOptions.Builder(
//                        getContentResolver(),
//                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
//                        contentValues).build();

//                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//                ImageCapture.OutputFileOptions options = new ImageCapture.OutputFileOptions.Builder(outputStream).build();

	//进行图片抓拍
    mCameraHelper.takePicture(options, new ImageCapture.OnImageCaptureCallback() 
    	//图片抓拍成功
       	@Override
        public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) 
            Toast.makeText(TakePictureActivity.this,
                    "save \\"" + UriHelper.getPath(TakePictureActivity.this, outputFileResults.getSavedUri()) + "\\"",
                    Toast.LENGTH_SHORT).show();
        

		//图片抓拍出现错误
        @Override
        public void onError(int imageCaptureError, @NonNull String message, @Nullable Throwable cause) 
            Toast.makeText(TakePictureActivity.this, message, Toast.LENGTH_SHORT).show();
        
    );

6. 录制视频

Video Capture

	//设置视频录制全局参数(非必须,可以不设置,使用默认值)
	mCameraHelper.setVideoCaptureConfig(
	    mCameraHelper.getVideoCaptureConfig()
	              .setAudioCaptureEnable(true) // true:有音频;false:没有音频(默认为true)
	              .setBitRate((int) (1024 * 1024 * 25 * 0.25))
	              .setVideoFrameRate(25)
	              .setIFrameInterval(1));

	//设置需要保存视频文件
	File file = FileUtils.getCaptureFile(this, Environment.DIRECTORY_MOVIES, ".mp4");
    VideoCapture.OutputFileOptions options =
            new VideoCapture.OutputFileOptions.Builder(file).build();

//        ContentValues contentValues = new ContentValues();
//        contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, "NEW_VIDEO");
//        contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
//
//        VideoCapture.OutputFileOptions options = new VideoCapture.OutputFileOptions.Builder(
//                getContentResolver(),
//                MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
//                contentValues).build();

	//开始录制
    mCameraHelper.startRecording(options, new VideoCapture.OnVideoCaptureCallback() 
        @Override
        public void onStart() 
        

		//视频录制成功
        @Override
        public void onVideoSaved(@NonNull VideoCapture.OutputFileResults outputFileResults) 
            Toast.makeText(
                    RecordVideoActivity.this,
                    "save \\"" + UriHelper.getPath(RecordVideoActivity.this, outputFileResults.getSavedUri()) + "\\"",
                    Toast.LENGTH_SHORT).show();
        
		
		//视频录制出现错误
        @Override
        public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) 
            Toast.makeText(RecordVideoActivity.this, message, Toast.LENGTH_LONG).show();
        
    );

7. 改变摄像机预览参数(包括帧格式、宽度、高度、FPS)

Set camera preview parameters (including frame format, width, height, FPS)

	//停止相机预览
	mCameraHelper.stopPreview();
	//设置摄像机预览参数
	mCameraHelper.setPreviewSize(size);
	//开始相机预览
	mCameraHelper.startPreview();

	//需要自适应摄像头分辨率的话,设置新的宽高比
	mCameraViewMain.setAspectRatio(mPreviewWidth, mPreviewHeight);

8. 调整对比度、亮度、色调、饱和度、白平衡等等一些相机控制参数

Adjust contrast, brightness, hue, saturation, white balance, and other camera controls

//获取UVCControl对象,通过该对象调整相机控制参数
UVCControl control = mCameraHelper.getUVCControl();

//根据监听器设置各种相机控制参数
private void setAllControlChangeListener(UVCControl controls) 
        // Brightness
        isbBrightness.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setBrightness(seekParams.progress));
        // Contrast
        isbContrast.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setContrast(seekParams.progress));
        // Contrast Auto
        cbContrastAuto.setOnCheckedChangeListener((buttonView, isChecked) -> 
            controls.setContrastAuto(isChecked);
        );
        // Hue
        isbHue.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setHue(seekParams.progress));
        // Hue Auto
        cbHueAuto.setOnCheckedChangeListener((buttonView, isChecked) -> 
            controls.setHueAuto(isChecked);
        );
        // Saturation
        isbSaturation.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setSaturation(seekParams.progress));
        // Sharpness
        isbSharpness.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setSharpness(seekParams.progress));
        // Gamma
        isbGamma.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setGamma(seekParams.progress));
        // White Balance
        isbWhiteBalance.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setWhiteBalance(seekParams.progress));
        // White Balance Auto
        cbWhiteBalanceAuto.setOnCheckedChangeListener((buttonView, isChecked) -> 
            controls.setWhiteBalanceAuto(isChecked);
        );
        // Backlight Compensation
        isbBacklightComp.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setBacklightComp(seekParams.progress));
        // Gain
        isbGain.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setGain(seekParams.progress));
        // Exposure Time
        isbExposureTime.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setExposureTimeAbsolute(seekParams.progress));
        // Exposure Time Auto
        cbExposureTimeAuto.setOnCheckedChangeListener((buttonView, isChecked) -> 
            controls.setExposureTimeAuto(isChecked);
        );
        // Iris
        isbIris.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setIrisAbsolute(seekParams.progress));
        // Focus
        isbFocus.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setFocusAbsolute(seekParams.progress));
        // Focus Auto
        cbFocusAuto.setOnCheckedChangeListener((buttonView, isChecked) -> 
            controls.setFocusAuto(isChecked);
        );
        // Zoom
        isbZoom.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setZoomAbsolute(seekParams.progress));
        // Pan
        isbPan.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setPanAbsolute(seekParams.progress));
        // Tilt
        isbTilt.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setTiltAbsolute(seekParams.progress));
        // Roll
        isbRoll.setOnSeekChangeListener(
                (MyOnSeekChangeListener) seekParams -> controls.setRollAbsolute(seekParams.progress));
        // Power Line Frequency
        rgPowerLineFrequency.setOnCheckedChangeListener((group, checkedId) -> 
            int value = 0;
            if (checkedId == R.id.rbPowerLineFrequencyDisable) 
                value = 0;
             else if (checkedId == R.id.rbPowerLineFrequency50Hz) 
                value = 1;
             else if (checkedId == R.id.rbPowerLineFrequency60Hz) 
                value = 2;
             else if (checkedId == R.id.rbPowerLineFrequencyAuto) 
                value = 3;
            
            controls.setPowerlineFrequency(value);
        );
    

// 重置所有相机控制参数为初试值
private void resetAllControlParams(UVCControl control) 
        // Brightness
        control.resetBrightness();
        // Contrast
        control.resetContrast();
        // Contrast Auto
        control.resetContrastAuto();
        // Hue
        control.resetHue();
        // Hue Auto
        control.resetHueAuto();
        // Saturation
        control.resetSaturation();
        // Sharpness
        control.resetSharpness();
        // Gamma
        control.resetGamma();
        // White Balance
        control.resetWhiteBalance();
        // White Balance Auto
        control.resetWhiteBalanceAuto();
        // Backlight Compensation
        control.resetBacklightComp();
        // Gain
        control.resetGain()

Ubuntu14.04安装libusb

libuvc是一个跨平台的USB视频设备库,建立在libusb之上。 它能够对导出标准USB视频类(UVC)接口的USB视频设备进行细化控制,使开发人员能够为以前不支持的设备编写驱动程序,或者以通用的方式访问UVC设备。

首先安装libusb。

先用sudo apt-get install安装了libusb-dev,安装完成但libuvc make的时候还是找不到libusb.h文件。所以用源代码安装。

1.环境

VMware下ubuntu14.04

2.获取源代码

下载 libusb-1.0.21.tar.bz2   http://sourceforge.net/projects/libusb/

3.解压源码

cd /下载
tar -xjvf libusb-1.0.21.tar.bz2

4.按照INSTALL文件给出的提示进行安装:./configure - make - make install

先configure:

cd libusb-1.0.21/
./configure

configure失败,configure: error: "udev support requested but libudev not installed"

安装依赖项libudev-dev:

cd
sudo apt-get install libudev-dev

安装成功后重新configure,成功,再make,make install,安装成功。

make
make install  

 5.安装libuvc

此时安装libuvc成功,可以找到libusb.h文件了。

以上是关于UVCAndroid,安卓UVC相机通用开发库(支持多预览和多摄像头)的主要内容,如果未能解决你的问题,请参考以下文章

枚举相机属性集的 UVC 属性项

安卓系统手机怎么装uvc?

杂记4--森云相机UVC驱动编译过程一些问题解决记录

uvc是啥

高手进 VB 支持 UVC摄像头吗?

Ubuntu14.04安装libusb