赞
踩
1、git下载:https://github.com/jiangdongguo/AndroidUSBCamera
2、下载后解压,将模块 libusbcamera、libutils集成到自已的项目中,直接拷贝到项目根目录下,相关配置
settings.gradle 后添加 , ':libusbcamera', ':libutils'
app build.gradle 文件 implementation project(':libusbcamera')
project build.gradle 文件
- allprojects {
- repositories {
- jcenter()
- google()
- maven { url 'https://jitpack.io' }
- maven { url 'https://raw.githubusercontent.com/saki4510t/libcommon/master/repository/' }
-
- }
- }
AndroidManifest.xml 文件开启相关权限
- <uses-permission android:name="android.permission.RECORD_AUDIO"/>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-
- <uses-feature android:name="android.hardware.usb.host"/>
项目ndk 要设置上 最后项目async
3、MainActivity
- public class MainActivity extends AppCompatActivity implements CameraViewInterface.Callback {
-
- private final String TAG = MainActivity.class.getSimpleName();
-
- public View mTextureView;
- private UVCCameraHelper mCameraHelper;
- private CameraViewInterface mUVCCameraView;
-
- private boolean isRequest = false;
- private boolean isPreview = false;
- private boolean isRecording = false;
- private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() {
-
- @Override
- public void onAttachDev(UsbDevice device) {
- // request open permission
- Log.d(TAG, "camera: usb 设备 " + device.getProductName() + " 新连接");
- if (mCameraHelper == null || mCameraHelper.getUsbDeviceCount() == 0) {
- showShortMsg("未检测到USB摄像头设备");
- return;
- }
- List<UsbDevice> devList = mCameraHelper.getUsbDeviceList();
- /*
- * usb连接时,判断是不是这个摄像头,是就打开,实现了热插拔,插拔一次,
- * 设备的id就加一,所以地址就改变,机器重启id初始化,getProductName()获得的是摄像头
- * 名称
- * */
- if (!isRequest)
- for (int i = 0; i < devList.size(); i++) {
- UsbDevice _device = devList.get(i);
- if (_device.getProductName().indexOf("camera") > -1) {
- isRequest = true;
- mCameraHelper.requestPermission(i);//打开usb摄像头
- }
- }
- }
-
- @Override
- public void onDettachDev(UsbDevice device) {
- // close camera
- Log.d(TAG, "camera: usb 设备 " + device.getProductName() + " 已拔出");
- if (isRequest) {
- isRequest = false;
- mCameraHelper.closeCamera();
- showShortMsg(device.getProductName() + " 已拨出");
- }
- }
-
- @Override
- public void onConnectDev(UsbDevice device, boolean isConnected) {
- Log.d(TAG, "camera: usb 设备 " + device.getProductName() + " 连接失败");
- if (!isConnected) {
- showShortMsg("连接失败,请检查分辨率参数是否正确");
- isPreview = false;
- } else {
- isPreview = true;
- showShortMsg("usb 设备正在连接");
- // need to wait UVCCamera initialize over
- Log.d(TAG, "camera is connected");
- }
- }
-
- @Override
- public void onDisConnectDev(UsbDevice device) {
- Log.d(TAG, "camera: usb disconnecting");
- showShortMsg("usb设备连接断开");
- }
- };
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mContext = this;
- // step.1 initialize UVCCameraHelper
- mTextureView = findViewById(R.id.camera_view);
- mUVCCameraView = (CameraViewInterface) mTextureView;
- mUVCCameraView.setCallback(this);
- mCameraHelper = UVCCameraHelper.getInstance();
- mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_YUYV);
- /*
- * 初始化分辨率,一定是设备支持的分辨率,否则摄像不能正常使用
- * */
- mCameraHelper.setDefaultPreviewSize(640, 480);
- mCameraHelper.initUSBMonitor(this, mUVCCameraView, listener);
- mCameraHelper.setOnPreviewFrameListener(new AbstractUVCCameraHandler.OnPreViewResultListener() {
- int printNum = 0;
-
- @Override
- public void onPreviewResult(byte[] nv21Yuv) {
- printNum++;
- if (printNum == 300) {
- printNum = 0;
- Log.d(TAG, "onPreviewResult: " + nv21Yuv.length + "摄像头预览");
- }
-
- }
- });
- }
-
- //录像
- private void cameraRecording(Boolean isStartRecording, String Name) {
- isRecording = isStartRecording;
- if (mCameraHelper == null || !mCameraHelper.isCameraOpened() || !isPreview) {
- showShortMsg("摄像头异常,请重新更换插口并重启app");
- return;
- }
- String OrderRecordStr = prefs.getString(Config.ORDER_RECORDING, "");
- Log.d(TAG, "OrderRecorde1=" + OrderRecordStr);
- if (!mCameraHelper.isPushing() && isStartRecording) {
- //文件地址自已设置
- String videoPath = Config.VIDEO_DIRECTORY + "/ " + Name;
- OrderRecordStr = OrderRecordStr + "&" + Name;
- prefs.edit().putString(Config.ORDER_RECORDING, OrderRecordStr).apply();
- RecordParams params = new RecordParams();
- params.setRecordPath(videoPath);
- params.setRecordDuration(0); // auto divide saved,default 0 means not divided
- params.setVoiceClose(true); // is close voice
- params.setSupportOverlay(true); // overlay only support armeabi-v7a & arm64-v8a
- mCameraHelper.startPusher(params, new AbstractUVCCameraHandler.OnEncodeResultListener() {
- @Override
- public void onEncodeResult(byte[] data, int offset, int length, long timestamp, int type) {
- // type = 1,h264 video stream
- if (type == 1) {
- FileUtils.putFileStream(data, offset, length);
- }
- // type = 0,aac audio stream
- if (type == 0) {
-
- }
- }
-
- @Override
- public void onRecordResult(String videoPath) {
- if (TextUtils.isEmpty(videoPath)) {
- return;
- }
- new Handler(getMainLooper()).post(() -> Toast.makeText(MainActivity.this, "save videoPath:" + videoPath, Toast.LENGTH_SHORT).show());
- }
- });
- // if you only want to push stream,please call like this
- // mCameraHelper.startPusher(listener);
- showShortMsg("开始录制视频");
- } else if (mCameraHelper.isPushing() && !isStartRecording) {
- FileUtils.releaseFile();
- mCameraHelper.stopPusher();
- showShortMsg("停止录制视频");
- String[] OrderRecordArr = OrderRecordStr.split("&");
- if (OrderRecordArr.length > 5) {
- String order = OrderRecordArr[1];
- String filePath = Config.VIDEO_DIRECTORY + "/ " + order + ".mp4";
- deleteFile(filePath);
- String _OrderRecordStr = "";
- for (int i = 0; i < OrderRecordArr.length; i++) {
- if (OrderRecordArr[i] != order && OrderRecordArr[i].length() > 0)
- _OrderRecordStr = _OrderRecordStr + "&" + OrderRecordArr[i];
- }
- prefs.edit().putString(Config.ORDER_RECORDING, _OrderRecordStr).apply();
- Log.d(TAG, "OrderRecorde=" + prefs.getString(Config.ORDER_RECORDING, ""));
- }
- }
- }
-
- //删除文件
- public boolean deleteFile(String filePath) {
- File file = new File(filePath);
- if (file.isFile() && file.exists()) return file.delete();
- else if (file.isFile() && !file.exists()) return true;
- return false;
- }
- @Override
- public void onResume() {
- super.onResume();
- // 恢复Camera预览
- if (mUVCCameraView != null) mUVCCameraView.onResume();
- }
-
- @Override
- protected void onStart() {
- super.onStart();
- // step.2 register USB event broadcast
- if (mCameraHelper != null) {
- mCameraHelper.registerUSB();
- }
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- // step.3 unregister USB event broadcast
- if (mCameraHelper != null) {
- mCameraHelper.unregisterUSB();
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
-
- if (mUVCCameraView != null) mUVCCameraView.onPause();
- }
-
- private void showShortMsg(String msg) {
- Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public USBMonitor getUSBMonitor() {
- return mCameraHelper.getUSBMonitor();
- }
-
- @Override
- public void onDialogResult(boolean canceled) {
-
- }
-
- public boolean isCameraOpened() {
- return mCameraHelper.isCameraOpened();
- }
-
- @Override
- public void onSurfaceCreated(CameraViewInterface view, Surface surface) {
- isPreview = false;
- new Thread(new Runnable() {
- @Override
- public void run() {
- // wait for camera created
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- Log.d(TAG, "camera: surface start preview " + isPreview + " " + isCameraOpened());
- if (!isPreview && isCameraOpened()) {
- mCameraHelper.startPreview(mUVCCameraView);
- isPreview = true;
- Log.d(TAG, "camera: surface start preview");
- }
- }
- }).start();
- }
-
- @Override
- public void onSurfaceChanged(CameraViewInterface view, Surface surface, int width, int height) {
-
- }
-
- @Override
- public void onSurfaceDestroy(CameraViewInterface view, Surface surface) {
- if (isPreview && isCameraOpened()) {
- mCameraHelper.stopPreview();
- Log.d(TAG, "surface:" + "is destroy");
- }
- isPreview = false;
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- FileUtils.releaseFile();
- // step.4 release uvc camera resources
- if (mCameraHelper != null) {
- mCameraHelper.release();
- Log.d(TAG, "camera is release");
- }
- isPreview = false;
- isRequest = false;
- }
-
- }
activity_main.xml
<com.serenegiant.usb.widget.UVCCameraTextureView android:id="@+id/camera_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center"/>
4、需要注意
(1)mCameraHelper.requestPermission(int index) 是打开usb设备,有的usb不是摄像头设备,需要对usb设备名称进行过滤,可控制需要打开特定的usb摄像头, 可以热插拔显示
(2)app关闭或后台运行 isPreview 需要重置为 false 不然再次进入app 预览无画面因为startPreview 未执行
(3)设备重启后第一次打开app, 预览画面可能没有,但实际是可以录制的,重新进入app就可以了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。