马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
有的自界说系统,对于自己外接的USB摄像头,android原生的camera和camera2都无法打开,CameraX也用不了。这时候就要用libusbCamera,这个库可以打开摄像头,还可以多摄像头同时预览。本文主要是同时打开3个USB摄像头的项目记录,详细的接口先容请拜见原博客。
特别感谢(原博客):UVCAndroid,安卓UVC相机通用开发库(支持多预览和多摄像头)_android com.herohan.uvcapp-CSDN博客
0,测试效果:
1,new一个project
2,增加依赖
- implementation 'com.herohan:UVCAndroid:1.0.5'
- implementation 'com.github.getActivity:XXPermissions:13.5'
复制代码
3,增加配置
- android.enableJetifier = true
复制代码
4,增加堆栈
- maven { url 'https://jitpack.io' }
复制代码
5,存储权限(这个我以为不是必须的)
- android:requestLegacyExternalStorage="true"
复制代码
6,布局源码:
- <?xml version="1.0" encoding="utf-8"?>
- <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:orientation="vertical">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:orientation="vertical">
- <TextView
- android:id="@+id/textViewLeft"
- android:text="左相机"
- android:layout_gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <com.serenegiant.widget.AspectRatioSurfaceView
- android:id="@+id/svCameraViewLeft"
- android:layout_gravity="center"
- android:layout_width="440dp"
- android:layout_height="220dp"
- />
- </LinearLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginLeft="10dp"
- android:orientation="vertical">
- <TextView
- android:id="@+id/textViewRight"
- android:text="右相机"
- android:layout_gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <com.serenegiant.widget.AspectRatioSurfaceView
- android:id="@+id/svCameraViewRight"
- android:layout_gravity="center"
- android:layout_width="440dp"
- android:layout_height="220dp"
- />
- </LinearLayout>
- </LinearLayout>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:layout_marginTop="5dp"
- android:orientation="vertical">
- <TextView
- android:id="@+id/textViewCenter"
- android:text="中间相机"
- android:layout_gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <com.serenegiant.widget.AspectRatioSurfaceView
- android:id="@+id/svCameraViewCenter"
- android:layout_gravity="center"
- android:layout_width="440dp"
- android:layout_height="220dp"
- />
- </LinearLayout>
- </LinearLayout>
- </androidx.coordinatorlayout.widget.CoordinatorLayout>
复制代码 7,页面源码
- package com.qz.camera;
- import androidx.annotation.NonNull;
- import androidx.appcompat.app.AppCompatActivity;
- import android.Manifest;
- import android.content.Intent;
- import android.hardware.usb.UsbDevice;
- import android.os.Bundle;
- import android.os.ConditionVariable;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.util.Log;
- import android.view.SurfaceHolder;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
- import com.herohan.uvcapp.CameraHelper;
- import com.herohan.uvcapp.ICameraHelper;
- import com.hjq.permissions.XXPermissions;
- import com.serenegiant.usb.Size;
- import com.serenegiant.usb.UVCCamera;
- import com.serenegiant.usb.UVCParam;
- import com.serenegiant.widget.AspectRatioSurfaceView;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.concurrent.ConcurrentLinkedQueue;
- public class MainActivity extends AppCompatActivity {
- private static final boolean DEBUG = true;
- private static final String TAG = MainActivity.class.getSimpleName();
- private static final int DEFAULT_WIDTH = 640;
- private static final int DEFAULT_HEIGHT = 480;
- private TextView mCameraNameLeft,mCameraNameRight, mCameraNameCenter;
- private UsbDevice mUsbDeviceLeft,mUsbDeviceRight, mUsbDeviceCenter;
- private ICameraHelper mCameraHelperLeft, mCameraHelperRight, mCameraHelperCenter;
- private AspectRatioSurfaceView svCameraViewLeft, svCameraViewRight, svCameraViewCenter;
- private ConcurrentLinkedQueue<UsbDevice> mReadyUsbDeviceList = new ConcurrentLinkedQueue<>();
- private ConditionVariable mReadyDeviceConditionVariable = new ConditionVariable();
- private final Object mSync = new Object();
- private HandlerThread mHandlerThread;
- private Handler mAsyncHandler;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- //setTitle(R.string.entry_multi_camera_new);
- if (DEBUG) Log.d(TAG, "huahua--onCreate:");
- mCameraNameLeft = findViewById(R.id.textViewLeft);
- mCameraNameRight = findViewById(R.id.textViewRight);
- mCameraNameCenter = findViewById(R.id.textViewCenter);
- List<String> needPermissions = new ArrayList<>();
- needPermissions.add(Manifest.permission.CAMERA);
- XXPermissions.with(this)
- .permission(needPermissions)
- .request((permissions, all) -> {
- if (!all) {
- return;
- }
- initViews();
- mHandlerThread = new HandlerThread(TAG);
- mHandlerThread.start();
- mAsyncHandler = new Handler(mHandlerThread.getLooper());
- initCameraHelper();
- });
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mHandlerThread.quitSafely();
- mAsyncHandler.removeCallbacksAndMessages(null);
- }
- private void initViews() {
- setCameraViewLeft();
- setCameraViewRight();
- setCameraViewCenter();
- }
- private void setCameraViewLeft() {
- svCameraViewLeft = findViewById(R.id.svCameraViewLeft);
- svCameraViewLeft.setAspectRatio(DEFAULT_WIDTH, DEFAULT_HEIGHT);
- 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());
- }
- }
- });
- }
- private void setCameraViewRight() {
- svCameraViewRight = findViewById(R.id.svCameraViewRight);
- 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());
- }
- }
- });
- }
- private void setCameraViewCenter() {
- svCameraViewCenter = findViewById(R.id.svCameraViewCenter);
- svCameraViewCenter.setAspectRatio(DEFAULT_WIDTH, DEFAULT_HEIGHT);
- svCameraViewCenter.getHolder().addCallback(new SurfaceHolder.Callback() {
- @Override
- public void surfaceCreated(@NonNull SurfaceHolder holder) {
- if (mCameraHelperCenter != null) {
- mCameraHelperCenter.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 (mCameraHelperCenter != null) {
- mCameraHelperCenter.removeSurface(holder.getSurface());
- }
- }
- });
- }
- @Override
- protected void onStart() {
- if (DEBUG) Log.d(TAG, "huahua--onStart:");
- super.onStart();
- }
- @Override
- protected void onStop() {
- if (DEBUG) Log.d(TAG, "onStop:");
- super.onStop();
- clearCameraHelper();
- }
- public void initCameraHelper() {
- if (DEBUG) Log.d(TAG, "initCameraHelper:");
- if (mCameraHelperLeft == null) {
- mCameraHelperLeft = new CameraHelper();
- mCameraHelperLeft.setStateCallback(mStateListenerLeft);
- }
- if (mCameraHelperRight == null) {
- mCameraHelperRight = new CameraHelper();
- mCameraHelperRight.setStateCallback(mStateListenerRight);
- }
- if (mCameraHelperCenter == null) {
- mCameraHelperCenter = new CameraHelper();
- mCameraHelperCenter.setStateCallback(mStateListenerCenter);
- }
- }
- private void clearCameraHelper() {
- if (DEBUG) Log.d(TAG, "clearCameraHelper:");
- if (mCameraHelperLeft != null) {
- mCameraHelperLeft.release();
- mCameraHelperLeft = null;
- }
- if (mCameraHelperRight != null) {
- mCameraHelperRight.release();
- mCameraHelperRight = null;
- }
- if (mCameraHelperCenter != null) {
- mCameraHelperCenter.release();
- mCameraHelperCenter = null;
- }
- }
- private void selectDeviceLeft(final UsbDevice device) {
- if (DEBUG) Log.v(TAG, "selectDeviceLeft:device=" + device.getDeviceName());
- mUsbDeviceLeft = device;
- mAsyncHandler.post(() -> {
- waitCanSelectDevice(device);
- if (mCameraHelperLeft != null) {
- mCameraHelperLeft.selectDevice(device);
- }
- });
- }
- private void selectDeviceRight(final UsbDevice device) {
- if (DEBUG) Log.v(TAG, "selectDeviceRight:device=" + device.getDeviceName());
- mUsbDeviceRight = device;
- mAsyncHandler.post(() -> {
- waitCanSelectDevice(device);
- if (mCameraHelperRight != null) {
- mCameraHelperRight.selectDevice(device);
- }
- });
- }
- private void selectDeviceCenter(final UsbDevice device) {
- if (DEBUG) Log.v(TAG, "selectDeviceCenter:device=" + device.getDeviceName());
- mUsbDeviceCenter = device;
- mAsyncHandler.post(() -> {
- waitCanSelectDevice(device);
- if (mCameraHelperCenter != null) {
- mCameraHelperCenter.selectDevice(device);
- }
- });
- }
- /**
- * wait for only one camera need request permission
- *
- * @param device
- */
- private void waitCanSelectDevice(UsbDevice device) {
- mReadyUsbDeviceList.add(device);
- while (mReadyUsbDeviceList.size() > 1) {
- mReadyDeviceConditionVariable.block();
- mReadyDeviceConditionVariable.close();
- }
- }
- /**
- * remove ready camera that wait for select
- *
- * @param device
- */
- private void removeSelectedDevice(UsbDevice device) {
- mReadyUsbDeviceList.remove(device);
- mReadyDeviceConditionVariable.open();
- }
- private final ICameraHelper.StateCallback mStateListenerLeft = new ICameraHelper.StateCallback() {
- private final String LOG_PREFIX = "ListenerLeft#";
- @Override
- public void onAttach(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onAttach:");
- synchronized (mSync) {
- if (mUsbDeviceLeft == null && !device.equals(mUsbDeviceRight) && !device.equals(mUsbDeviceCenter)) {
- selectDeviceLeft(device);
- mCameraNameLeft.setText("左相机("+device.getDeviceName()+")");
- }
- }
- }
- @Override
- public void onDeviceOpen(UsbDevice device, boolean isFirstOpen) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDeviceOpen:");
- if (mCameraHelperLeft != null && device.equals(mUsbDeviceLeft)) {
- UVCParam param = new UVCParam();
- param.setQuirks(UVCCamera.UVC_QUIRK_FIX_BANDWIDTH);
- mCameraHelperLeft.openCamera(param);
- }
- removeSelectedDevice(device);
- }
- @Override
- public void onCameraOpen(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCameraOpen:");
- if (mCameraHelperLeft != null && 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);
- }
- }
- @Override
- public void onCameraClose(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCameraClose:");
- if (device.equals(mUsbDeviceLeft)) {
- if (mCameraHelperLeft != null) {
- mCameraHelperLeft.removeSurface(svCameraViewLeft.getHolder().getSurface());
- }
- }
- }
- @Override
- public void onDeviceClose(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDeviceClose:");
- }
- @Override
- public void onDetach(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDetach:");
- if (device.equals(mUsbDeviceLeft)) {
- mUsbDeviceLeft = null;
- }
- removeSelectedDevice(device);
- }
- @Override
- public void onCancel(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCancel:");
- if (device.equals(mUsbDeviceLeft)) {
- mUsbDeviceLeft = null;
- }
- removeSelectedDevice(device);
- }
- };
- private final ICameraHelper.StateCallback mStateListenerRight = new ICameraHelper.StateCallback() {
- private final String LOG_PREFIX = "ListenerRight#";
- @Override
- public void onAttach(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onAttach:");
- synchronized (mSync) {
- if (mUsbDeviceRight == null && !device.equals(mUsbDeviceLeft) && !device.equals(mUsbDeviceCenter)) {
- selectDeviceRight(device);
- mCameraNameRight.setText("右相机("+device.getDeviceName()+")");
- }
- }
- }
- @Override
- public void onDeviceOpen(UsbDevice device, boolean isFirstOpen) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDeviceOpen:");
- if (mCameraHelperRight != null && device.equals(mUsbDeviceRight)) {
- UVCParam param = new UVCParam();
- param.setQuirks(UVCCamera.UVC_QUIRK_FIX_BANDWIDTH);
- mCameraHelperRight.openCamera(param);
- }
- removeSelectedDevice(device);
- }
- @Override
- public void onCameraOpen(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCameraOpen:");
- if (mCameraHelperRight != null && 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);
- }
- }
- @Override
- public void onCameraClose(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCameraClose:");
- if (device.equals(mUsbDeviceRight)) {
- if (mCameraHelperRight != null) {
- mCameraHelperRight.removeSurface(svCameraViewRight.getHolder().getSurface());
- }
- }
- }
- @Override
- public void onDeviceClose(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDeviceClose:");
- }
- @Override
- public void onDetach(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDetach:");
- if (device.equals(mUsbDeviceRight)) {
- mUsbDeviceRight = null;
- }
- removeSelectedDevice(device);
- }
- @Override
- public void onCancel(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCancel:");
- if (device.equals(mUsbDeviceRight)) {
- mUsbDeviceRight = null;
- }
- removeSelectedDevice(device);
- }
- };
- private final ICameraHelper.StateCallback mStateListenerCenter = new ICameraHelper.StateCallback() {
- private final String LOG_PREFIX = "ListenerCenter#";
- @Override
- public void onAttach(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onAttach:");
- synchronized (mSync) {
- if (mUsbDeviceCenter == null && !device.equals(mUsbDeviceRight) && !device.equals(mUsbDeviceLeft)) {
- selectDeviceCenter(device);
- mCameraNameCenter.setText("中间相机("+device.getDeviceName()+")");
- }
- }
- }
- @Override
- public void onDeviceOpen(UsbDevice device, boolean isFirstOpen) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDeviceOpen:");
- if (mCameraHelperCenter != null && device.equals(mUsbDeviceCenter)) {
- UVCParam param = new UVCParam();
- param.setQuirks(UVCCamera.UVC_QUIRK_FIX_BANDWIDTH);
- mCameraHelperCenter.openCamera(param);
- }
- removeSelectedDevice(device);
- }
- @Override
- public void onCameraOpen(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCameraOpen:");
- if (mCameraHelperCenter != null && device.equals(mUsbDeviceCenter)) {
- mCameraHelperCenter.startPreview();
- Size size = mCameraHelperCenter.getPreviewSize();
- if (size != null) {
- int width = size.width;
- int height = size.height;
- //auto aspect ratio
- svCameraViewCenter.setAspectRatio(width, height);
- }
- mCameraHelperCenter.addSurface(svCameraViewCenter.getHolder().getSurface(), false);
- }
- }
- @Override
- public void onCameraClose(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCameraClose:");
- if (device.equals(mUsbDeviceCenter)) {
- if (mCameraHelperCenter != null) {
- mCameraHelperCenter.removeSurface(svCameraViewCenter.getHolder().getSurface());
- }
- }
- }
- @Override
- public void onDeviceClose(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDeviceClose:");
- }
- @Override
- public void onDetach(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onDetach:");
- if (device.equals(mUsbDeviceCenter)) {
- mUsbDeviceCenter = null;
- }
- removeSelectedDevice(device);
- }
- @Override
- public void onCancel(UsbDevice device) {
- if (DEBUG) Log.v(TAG, LOG_PREFIX + "onCancel:");
- if (device.equals(mUsbDeviceCenter)) {
- mUsbDeviceCenter = null;
- }
- removeSelectedDevice(device);
- }
- };
- }
复制代码 对于较为标准的android系统调用,可以利用更加简便的CameraX调用,博文链接:
Android相机调用-CameraX【外接摄像头】【USB摄像头】_安卓调取摄像头设备的方式-CSDN博客
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |