先来一段从网上找到的理论知识,对UVC协议有初步的印象
UVC协议:USB Video Class,USB视频类,是一种为USB视频捕获设备定义的协议标准。
Android 平台支持使用即插即用的 USB 摄像头(即网络摄像头),但前提是这些摄像头采用标准的 Android Camera2 API 和摄像头 HIDL 接口。网络摄像头通常支持 USB 视频类 (UVC) 驱动程序,并且在 Linux 上,系统采用标准的 Video4Linux (V4L) 驱动程序控制 UVC 摄像头。
本文主要展示具体的实现,并不研究UVC协议以及底层实现,只展示Android外界usb摄像头的预览功能的流程。文末附demo
本文的实现基于github开源库:传送门
1.项目中集成libuvccamera模块(代码可从github下载,或者是文末demo中附带)
implementation project(':libuvccamera')
2.布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.serenegiant.widget.AspectRatioSurfaceView
android:id="@+id/surfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
3.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;
/**
* CameraHelper是管理Camera服务的客户端
* (功能包括:选择设备,打开设备,连接设备,关联预览用的CameraView,拍照,录像,断开连接等操作)
* 其中通过addSurface,关联预览用的Surface比较关键,分为三种情况:
* a. 连接设备成功时,执行addSurface
* b. 旋转屏幕,成功进入OnResume时,CameraView生成Surface,并执行回调onSurfaceCreated方法,在方法中执行addSurface
*/
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);
}
/**
* 程序结束或者UVC设备断开连接时,释放CameraHelper
*/
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);
}
/**
* 获取USB设备权限之后,才开始连接USB摄像头
*/
@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://www.toymoban.com/news/detail-620834.html
demo源码 文章来源地址https://www.toymoban.com/news/detail-620834.html
到了这里,关于Android 外接基于UVC协议的摄像头并实现预览的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!