接上回
前面三个章节完成之后,我们就有了一个图传的发送端(可以是esp32cam,也可以是esp32s3cam),一个是图传接收端(usb 摄像头 + 串口)。图传的发送端,淘宝上到处都是。接收端必须是esp32s3cam,因为我们要用它的usb,理论上只要支持usb的都可以。
如果我们用这套系统来搓一个fpv小车,fpv穿越机,理论上都是一样的。下面来开发一个Android 手机上的app来展示USB UVC,其实非常简单,构造UVCCamera即可。处理下USB的相关事件。
需要源码,可以咸鱼沟通
配置
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { google()
mavenCentral()
maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/google' } maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } maven { url 'https://jitpack.io' } maven { url 'https://raw.githubusercontent.com/saki4510t/libcommon/master/repository/' }
}
}
添加Ali的maven,
因为用的比较新的android studio,用的是libs.version.toml
versions
agp = "8.10.1"
junit = "4.13.2"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
appcompat = "1.7.1"
material = "1.14.0"
activity = "1.13.0"
constraintlayout = "2.2.1"
usbcamera = "2.3.4"
添加usbcamera
libraries
junit = { group = "junit", name = "junit", version.ref = "junit" }
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
android-usbcamera = { group = "com.github.jiangdongguo", name = "AndroidUSBCamera", version.ref = "usbcamera" }
这样如果一切正常的话,就能更新下来需要的库。
权限配置
<uses-permission android:name="android.permission.USB_PERMISSION" />
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000">
<com.serenegiant.usb.widget.UVCCameraTextureView
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
</FrameLayout>
Activity
主要就是对usb的monitor以及uvcCamera的使用
mCameraView = findViewById(R.id.camera_view );
mCameraView.setAspectRatio(640.0 / 480.0);
监听到usb uvc插入
mUSBMonitor = new USBMonitor(this, new USBMonitor.OnDeviceConnectListener() {
@Override
public void onAttach(UsbDevice device) {
mUSBMonitor.requestPermission(device);
}
@Override
public void onConnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock, boolean createNew) {
try {
mUVCCamera = new UVCCamera();
mUVCCamera.open(ctrlBlock);
mUVCCamera.setPreviewSize(640, 480, UVCCamera.FRAME_FORMAT_MJPEG );
if (mCameraView.getSurfaceTexture() != null) {
mUVCCamera.setPreviewDisplay(new android.view.Surface(mCameraView.getSurfaceTexture()));
}
mCameraView.post(() -> setTextureViewFull(640, 480));
mUVCCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onDisconnect(UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock) {
closeCamera();
}
@Override public void onDettach(UsbDevice device) { }
@Override public void onCancel(UsbDevice device) { }
});
主要在onConnect里面构建UVCCamera,然后初始化等操作。
然后插上设备,授权。搞定。
终章
