ale*_*apa 9 java android android-camera2
我有一个 UVC 摄像头,想要从我的 Android Pie (Android 9) 代码中访问和抓取帧。
这是我用来枚举连接到 Android 手机的摄像头的代码:
@Override
public void onResume()
{
CameraManager manager =
(CameraManager)getSystemService(CAMERA_SERVICE);
try {
for (String cameraId : manager.getCameraIdList()) {
CameraCharacteristics chars
= manager.getCameraCharacteristics(cameraId);
// Do something with the characteristics
int deviceLevel = chars.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
Log.d(TAG, " **** device ["+cameraId+"] level:"+deviceLevel);
}
} catch(CameraAccessException e){
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
我在 Android 9/Pie (Pixel 3) 上跳来跳去,这显示了连接的 USB 摄像头。但是只列出了两个设备,手机的前置和后置摄像头。
这是我的清单文件 (AndroidManifest.xml) 中的功能和权限列表:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.usb.host" />
Run Code Online (Sandbox Code Playgroud)
我在互联网上找不到任何示例代码如何实现这一点,即访问在 Android 9 及更高版本上使用的 USB 摄像头。
我缺少什么让我的代码枚举 USB 摄像头?我见过一些适用于 Android 的 3rd 方 UVC 库,但我不想使用它们,而是想使用原生 Android 代码。
小智 17
我花了太长时间试图让它发挥作用,所以我想我应该与读到这篇文章的人分享我的发现。之前的海报已经提到了其中的大部分内容,但希望我可以添加一些有价值的内容。
Android有Camera2 API,它似乎支持外部摄像头。据说您可以获取每个连接的相机的特征并寻找一个LENS_FACING_EXTERNAL。
实际上,这似乎还不适用于许多手机。我在三部三星手机(S9、A31、A51)和一部 Google Pixel 2 XL 上进行了尝试。这给了我 Android 10 和 11 的混合版本。这些手机都不支持外部摄像头。
有些应用程序(例如USB Camera)仍然可以使其正常工作。我相信他们正在使用像UVCCamera这样的库。这基本上是一个完整的 UVC(USB 视频类)实现 + USB 主机,这最终允许您捕获视频。
我自己决定不使用 UVCCamera 的原因是它没有“Android Blessing”,并且在不同设备上或在 Android 升级期间,事情可能会以奇怪的方式出现问题。我自己没有能力支持这一点。
您可以轻松下载并构建Camera2Video示例 ( ./gradlew assembleRelease -x test),因为这为您提供了一个现成的应用程序,可以显示所有检测到的摄像机。您需要一个 USB OTG 适配器才能将网络摄像头插入手机,但只需几美元即可购买。
就目前的情况来看,Android 上对外部 USB 摄像头的支持有点令人悲伤。似乎没有官方支持的方式来使用可在大多数设备上使用的外部 USB 摄像头。
这里有一些示例代码,如果您愿意的话,可以让您尝试枚举自己手机上的摄像头。这只是从我自己的实验代码中提取的一些片段,因此错误处理/正确性很差。然而,据我所知,它仍然是您需要了解的最重要的代码片段。
public class CameraUtils {
final Context context;
final CameraManager cameraManager;
public CameraUtils(Context context) {
this.context = context;
this.cameraManager = (CameraManager)context.getSystemService(Context.CAMERA_SERVICE);
}
/**
* Get the IDs of all available cameras.
*/
public String[] getCameraIds() {
return this.cameraManager.getCameraIdList();
}
/**
* Get the "lens facing" for a particular camera ID returned by `getCameraIds()`.
*/
public bool getLensFacing(String cameraId) {
CameraCharacteristics characteristics = this.cameraManager.getCameraCharacteristics(cameraId);
// This will return one of CameraMetadata.LENS_FACING_FRONT,
// CameraMetadata.LENS_FACING_BACK or CameraMetadata.LENS_FACING_EXTERNAL.
return characteristics.get(CameraCharacteristics.LENS_FACING);
}
/**
* Return true if this kernel supports external cameras, false otherwise.
*/
public bool supportsExternalCameras() {
return this.context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL);
}
}
Run Code Online (Sandbox Code Playgroud)
PS 我已尽力确保此信息正确。如果我有什么不对的地方,请随时纠正我!关于如何在 Android 上使用外部 USB 摄像头的文档充其量也很少。
ese*_*sov 10
您可以使用常量FEATURE_CAMERA_EXTERNAL调用PackageManager.hasSystemFeature来检查您的设备是否支持外部摄像头。Pixel 3 不支持此功能。
事实上,有多个库和应用程序提供 USB 摄像头支持。但他们不使用 android API 并自己实现一切。最常见的方法似乎是使用Video for linux内核模块(如果内核是用这个模块编译的)。它还需要访问/dev/video设备的权限,这在非 root 设备上通常不是这种情况。但实现相当简单。例如android-webcam使用这种方法。
另一种方法是使用USB 主机 api并自己实现所有协议。这不需要 root 访问权限,但实现要复杂得多。你可以检查这个库是这样的。
我想我找到了自己问题的答案。我购买了三星 Galaxy S10e,没有任何修改的完全相同的代码将 USB 摄像头作为列表中的第一个返回。即这条线Log.d(TAG, " **** device ["+cameraId+"] level:"+deviceLevel);打印 3 次,一次用于 USB 摄像头,两次用于内部摄像头。
我最好的猜测是,大多数在 2018 年 10 月发布 Android 9 之后设计和制造的手机都启用了此功能。大约在那个时间或之前发布然后后来收到 Android 9 (Pie) 更新的手机不太可能具有此功能。
| 归档时间: |
|
| 查看次数: |
7620 次 |
| 最近记录: |