先来一段从网上找到的理论知识,对UVC协议有初步的印象
UVC协议:USB Video Class,USB视频类,是一种为USB视频捕获设备定义的协议标准。
Android 平台支持使用即插即用的 USB 摄像头(即网络摄像头),但前提是这些摄像头采用标准的 Android Camera2 API 和摄像头 HIDL 接口。网络摄像头通常支持 USB 视频类 (UVC) 驱动程序,并且在 Linux 上,系统采用标准的 Video4Linux (V4L) 驱动程序控制 UVC 摄像头。
本文主要展示具体的实现,并不研究UVC协议以及底层实现,只展示Android外界usb摄像头的预览功能的流程。文末附demo
本文的实现基于github开源库:传送门
项目中集成libuvccamera模块(代码可从github下载,或者是文末demo中附带)
implementation project(':libuvccamera')
布局文件
MainActivity
public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private static final boolean DEBUG = true; private ActivityMainBinding binding; private UsbDevice mUsbDevice; private ICameraHelper mCameraHelper; private final ICameraHelper.StateCallback mStateCallback = new MyCameraHelperCallback(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); } @Override public void onStart() { super.onStart(); resetCameraHelper(); } private void resetCameraHelper() { clearCameraHelper(); initCameraHelper(); } public void initCameraHelper() { mCameraHelper = new CameraHelper(); mCameraHelper.setStateCallback(mStateCallback); } private void clearCameraHelper() { if (mCameraHelper != null) { mCameraHelper.releaseAll(); mCameraHelper = null; } } private class MyCameraHelperCallback implements ICameraHelper.StateCallback { @Override public void onAttach(UsbDevice device) { if (DEBUG) Log.v(TAG, "onAttach:device=" + device.getDeviceName()); mCameraHelper.selectDevice(device); } @Override public void onDeviceOpen(UsbDevice device, boolean createNew) { if (DEBUG) Log.v(TAG, "onDeviceOpen:device=" + device.getDeviceName()); if (mCameraHelper != null) { mCameraHelper.openCamera(); } } @Override public void onCameraOpen(UsbDevice device) { if (DEBUG) Log.v(TAG, "onCameraOpen:"); mCameraHelper.startPreview(); // 和摄像头成功建立连接之后,就可以获取摄像头当前预览的实际分辨率 Size size = mCameraHelper.getPreviewSize(); if (size != null) { // 设置TextureView的宽高比,使之符合摄像头的真实比例 binding.surfaceView.setAspectRatio(size.width, size.height); } if (mCameraHelper != null && binding.surfaceView != null && binding.surfaceView.getHolder() != null && binding.surfaceView.getHolder().getSurface() != null) { mCameraHelper.addSurface(binding.surfaceView.getHolder().getSurface(), false); } } @Override public void onCameraClose(UsbDevice device) { if (DEBUG) Log.v(TAG, "onCameraClose:"); if (mCameraHelper != null && binding.surfaceView != null && binding.surfaceView.getHolder() != null && binding.surfaceView.getHolder().getSurface() != null) { mCameraHelper.removeSurface(binding.surfaceView.getHolder().getSurface()); } } @Override public void onDeviceClose(UsbDevice device) { if (DEBUG) Log.v(TAG, "onDeviceClose:"); } @Override public void onDetach(UsbDevice device) { if (DEBUG) Log.v(TAG, "onDetach:device=" + device.getDeviceName()); if (device.equals(mUsbDevice)) { mUsbDevice = null; } } @Override public void onCancel(UsbDevice device) { if (DEBUG) Log.v(TAG, "onCancel:device=" + device.getDeviceName()); if (device.equals(mUsbDevice)) { mUsbDevice = null; } } @Override public void onError(UsbDevice device, CameraException e) { if (DEBUG) Log.v(TAG, "onError:" + e); if (device.equals(mUsbDevice)) { mUsbDevice = null; } } }}
至此,就实现了对usb摄像头的简单的预览功能
来源地址:https://blog.csdn.net/weixin_53324308/article/details/130823360