当前位置:   article > 正文

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

android com.herohan.uvcapp

简介

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()
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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

dependencies {
    implementation 'com.herohan:UVCAndroid:1.0.5'
}
  • 1
  • 2
  • 3

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;
                }
	
	//摄像头业务操作
           });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
<application
	...
	android:requestLegacyExternalStorage="true"
	>
  • 1
  • 2
  • 3
  • 4

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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95

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

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

 mCameraHelper.release();
  • 1

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();
        }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

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();
        }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

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

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

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

	//需要自适应摄像头分辨率的话,设置新的宽高比
	mCameraViewMain.setAspectRatio(mPreviewWidth, mPreviewHeight);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Size里面的帧格式type只支持UVCCamera.UVC_VS_FRAME_UNCOMPRESSED(YUV格式)和UVCCamera.UVC_VS_FRAME_MJPEG(Mjpeg格式),使用的时候需要摄像头支持(摄像头可能支持YUV格式或者Mjpeg格式)。

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();
        // Exposure Time
        control.resetExposureTimeAbsolute();
        // Auto-Exposure Mode
        control.resetAutoExposureMode();
        // Iris
        control.resetIrisAbsolute();
        // Focus
        control.resetFocusAbsolute();
        // Focus Auto
        control.resetFocusAuto();
        // Zoom
        control.resetZoomAbsolute();
        // Pan
        control.resetPanAbsolute();
        // Tilt
        control.resetTiltAbsolute();
        // Roll
        control.resetRollAbsolute();
        // Power Line Frequency
        control.resetPowerlineFrequency();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136

9.旋转摄像头90度、180度、270度,设置摄像头预览镜像

Rotate the camera 90 degrees, 180 degrees, and 270 degrees , set the camera preview mirror

	//旋转摄像头
	private void rotateBy(int angle) {
        mPreviewRotation += angle;
        mPreviewRotation %= 360;
        if (mPreviewRotation < 0) {
            mPreviewRotation += 360;
        }

        if (mCameraHelper != null) {
            mCameraHelper.setPreviewConfig(
                    mCameraHelper.getPreviewConfig().setRotation(mPreviewRotation));
        }
    }

	//设置水平镜像显示
    private void flipHorizontally() {
        if (mCameraHelper != null) {
            mCameraHelper.setPreviewConfig(
                    mCameraHelper.getPreviewConfig().setMirror(MirrorMode.MIRROR_HORIZONTAL));
        }
    }

	//设置垂直镜像显示
    private void flipVertically() {
        if (mCameraHelper != null) {
            mCameraHelper.setPreviewConfig(
                    mCameraHelper.getPreviewConfig().setMirror(MirrorMode.MIRROR_VERTICAL));
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

10.设置多个预览

Set multiple previews

mCameraHelper.addSurface(svCameraViewMain.getHolder().getSurface(), false);
mCameraHelper.addSurface(svCameraViewSecond.getHolder().getSurface(), false);
mCameraHelper.addSurface(svCameraViewThird.getHolder().getSurface(), false);
mCameraHelper.addSurface(svCameraViewFourth.getHolder().getSurface(), false);
  • 1
  • 2
  • 3
  • 4

11.设置多个摄像头(USB2.0受带宽所限,有可能无法同时连接多个摄像头)

Setting multiple Cameras

	private ICameraHelper mCameraHelperLeft;
    private ICameraHelper mCameraHelperRight;

    private AspectRatioSurfaceView svCameraViewLeft;
    private AspectRatioSurfaceView svCameraViewRight;

	private UsbDevice mUsbDeviceLeft;
    private UsbDevice mUsbDeviceRight;

	private final ICameraHelper.StateCallback mStateListenerLeft = new ICameraHelper.StateCallback() {
		@Override
        public void onAttach(UsbDevice device) {
            synchronized (mSync) {
                if (mUsbDeviceLeft == null && !device.equals(mUsbDeviceRight)) {
                    selectDeviceLeft(device);
                }
            }
        }
        @Override
        public void onDeviceOpen(UsbDevice device, boolean isFirstOpen) {
            if (device.equals(mUsbDeviceLeft)) {
                UVCParam param = new UVCParam();
                param.setQuirks(UVCCamera.UVC_QUIRK_FIX_BANDWIDTH);
                mCameraHelperLeft.openCamera(param);
            }
        }
        @Override
        public void onCameraOpen(UsbDevice device) {
            if (device.equals(mUsbDeviceLeft)) {
                mCameraHelperLeft.startPreview();

                Size size = mCameraHelperLeft.getPreviewSize();
                if (size != null) {
                    int width = size.width;
                    int height = size.height;
                    //auto aspect ratio
                    svCameraViewLeft.setAspectRatio(width, height);
                }

                mCameraHelperLeft.addSurface(svCameraViewLeft.getHolder().getSurface(), false);

                mIsCameraLeftConnected = true;
            }
        }

        @Override
        public void onCameraClose(UsbDevice device) {
            if (device.equals(mUsbDeviceLeft)) {
                if (mCameraHelperLeft != null) {
                   mCameraHelperLeft.removeSurface(svCameraViewLeft.getHolder().getSurface());
                }

                mIsCameraLeftConnected = false;
            }
        }

        @Override
        public void onDeviceClose(UsbDevice device) {
        }

        @Override
        public void onDetach(UsbDevice device) {
            if (device.equals(mUsbDeviceLeft)) {
                mUsbDeviceLeft = null;
            }
        }

        @Override
        public void onCancel(UsbDevice device) {
            if (device.equals(mUsbDeviceLeft)) {
                mUsbDeviceLeft = null;
            }
        }
	};
	private final ICameraHelper.StateCallback mStateListenerRight = new ICameraHelper.StateCallback() {
		@Override
        public void onAttach(UsbDevice device) {
            synchronized (mSync) {
                if (mUsbDeviceRight == null && !device.equals(mUsbDeviceLeft)) {
                    selectDeviceRight(device);
                }
            }
        }

        @Override
        public void onDeviceOpen(UsbDevice device, boolean isFirstOpen) {
            if (device.equals(mUsbDeviceRight)) {
                UVCParam param = new UVCParam();
                param.setQuirks(UVCCamera.UVC_QUIRK_FIX_BANDWIDTH);
                mCameraHelperRight.openCamera(param);
            }
        }

        @Override
        public void onCameraOpen(UsbDevice device) {
            if (device.equals(mUsbDeviceRight)) {
                mCameraHelperRight.startPreview();

                Size size = mCameraHelperRight.getPreviewSize();
                if (size != null) {
                    int width = size.width;
                    int height = size.height;
                    //auto aspect ratio
                    svCameraViewRight.setAspectRatio(width, height);
                }

                mCameraHelperRight.addSurface(svCameraViewRight.getHolder().getSurface(), false);

                mIsCameraRightConnected = true;
            }
        }

        @Override
        public void onCameraClose(UsbDevice device) {
            if (device.equals(mUsbDeviceRight)) {
                if (mCameraHelperRight != null) {
                    mCameraHelperRight.removeSurface(svCameraViewRight.getHolder().getSurface());
                }

                mIsCameraRightConnected = false;
            }
        }

        @Override
        public void onDeviceClose(UsbDevice device) {
        }

        @Override
        public void onDetach(UsbDevice device) {
            if (device.equals(mUsbDeviceRight)) {
                mUsbDeviceRight = null;
            }
        }

        @Override
        public void onCancel(UsbDevice device) {
            if (device.equals(mUsbDeviceRight)) {
                mUsbDeviceRight = null;
            }
        }
	};

	svCameraViewLeft.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                if (mCameraHelperLeft != null) {
                    mCameraHelperLeft.addSurface(holder.getSurface(), false);
                }
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                if (mCameraHelperLeft != null) {
                    mCameraHelperLeft.removeSurface(holder.getSurface());
                }
            }
        });
	svCameraViewRight.setAspectRatio(DEFAULT_WIDTH, DEFAULT_HEIGHT);

        svCameraViewRight.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(@NonNull SurfaceHolder holder) {
                if (mCameraHelperRight != null) {
                    mCameraHelperRight.addSurface(holder.getSurface(), false);
                }
            }

            @Override
            public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
                if (mCameraHelperRight != null) {
                    mCameraHelperRight.removeSurface(holder.getSurface());
                }
            }
        });

	mCameraHelperLeft = new CameraHelper();
	mCameraHelperLeft.setStateCallback(mStateListenerLeft);
	mCameraHelperRight = new CameraHelper();
	mCameraHelperRight.setStateCallback(mStateListenerRight);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189

其他API

方法说明
getDeviceList()获取当前检测到的所有UVC设备
getSupportedFormatList()获取当前摄像头支持的Format列表
getSupportedSizeList()获取当前摄像头支持的Size列表
getPreviewSize()获取当前摄像头正在使用的预览Size
setButtonCallback()设置按钮事件回调
setFrameCallback()设置实时预览图像数据回调(请在StateCallback的onDeviceOpen或者onCameraOpen回调函数里面调用,使用方法可以参考demo里面的SetFrameCallbackActivity),支持格式 UVCCamera.PIXEL_FORMAT_YUV;PIXEL_FORMAT_NV12;PIXEL_FORMAT_NV21;PIXEL_FORMAT_RGB565;PIXEL_FORMAT_RGBX等格式
openCamera(Size size)用指定格式打开当前摄像头
closeCamera()关闭当前摄像头
isRecording()是否正在录像
isCameraOpened()是否已经打开当前摄像头

下载演示APK

Download demo APK
在这里插入图片描述
app-debug.apk

在这里插入图片描述
demo-debug.apk

参考

saki4510t/UVCCamera

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/472574
推荐阅读
相关标签
  

闽ICP备14008679号