当前位置:   article > 正文

AndroidUSBCamera 使用步骤_com.github.jiangdongguo.androidusbcamera:libausbc:

com.github.jiangdongguo.androidusbcamera:libausbc:3.3.3

1、git下载:https://github.com/jiangdongguo/AndroidUSBCamera

2、下载后解压,将模块 libusbcamera、libutils集成到自已的项目中,直接拷贝到项目根目录下,相关配置

settings.gradle 后添加   , ':libusbcamera', ':libutils'

app build.gradle 文件   implementation project(':libusbcamera')

project build.gradle 文件   

  1. allprojects {
  2. repositories {
  3. jcenter()
  4. google()
  5. maven { url 'https://jitpack.io' }
  6. maven { url 'https://raw.githubusercontent.com/saki4510t/libcommon/master/repository/' }
  7. }
  8. }

AndroidManifest.xml 文件开启相关权限

  1. <uses-permission android:name="android.permission.RECORD_AUDIO"/>
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  3. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  4. <uses-feature android:name="android.hardware.usb.host"/>

项目ndk 要设置上 最后项目async

3、MainActivity

  1. public class MainActivity extends AppCompatActivity implements CameraViewInterface.Callback {
  2. private final String TAG = MainActivity.class.getSimpleName();
  3. public View mTextureView;
  4. private UVCCameraHelper mCameraHelper;
  5. private CameraViewInterface mUVCCameraView;
  6. private boolean isRequest = false;
  7. private boolean isPreview = false;
  8. private boolean isRecording = false;
  9. private UVCCameraHelper.OnMyDevConnectListener listener = new UVCCameraHelper.OnMyDevConnectListener() {
  10. @Override
  11. public void onAttachDev(UsbDevice device) {
  12. // request open permission
  13. Log.d(TAG, "camera: usb 设备 " + device.getProductName() + " 新连接");
  14. if (mCameraHelper == null || mCameraHelper.getUsbDeviceCount() == 0) {
  15. showShortMsg("未检测到USB摄像头设备");
  16. return;
  17. }
  18. List<UsbDevice> devList = mCameraHelper.getUsbDeviceList();
  19. /*
  20. * usb连接时,判断是不是这个摄像头,是就打开,实现了热插拔,插拔一次,
  21. * 设备的id就加一,所以地址就改变,机器重启id初始化,getProductName()获得的是摄像头
  22. * 名称
  23. * */
  24. if (!isRequest)
  25. for (int i = 0; i < devList.size(); i++) {
  26. UsbDevice _device = devList.get(i);
  27. if (_device.getProductName().indexOf("camera") > -1) {
  28. isRequest = true;
  29. mCameraHelper.requestPermission(i);//打开usb摄像头
  30. }
  31. }
  32. }
  33. @Override
  34. public void onDettachDev(UsbDevice device) {
  35. // close camera
  36. Log.d(TAG, "camera: usb 设备 " + device.getProductName() + " 已拔出");
  37. if (isRequest) {
  38. isRequest = false;
  39. mCameraHelper.closeCamera();
  40. showShortMsg(device.getProductName() + " 已拨出");
  41. }
  42. }
  43. @Override
  44. public void onConnectDev(UsbDevice device, boolean isConnected) {
  45. Log.d(TAG, "camera: usb 设备 " + device.getProductName() + " 连接失败");
  46. if (!isConnected) {
  47. showShortMsg("连接失败,请检查分辨率参数是否正确");
  48. isPreview = false;
  49. } else {
  50. isPreview = true;
  51. showShortMsg("usb 设备正在连接");
  52. // need to wait UVCCamera initialize over
  53. Log.d(TAG, "camera is connected");
  54. }
  55. }
  56. @Override
  57. public void onDisConnectDev(UsbDevice device) {
  58. Log.d(TAG, "camera: usb disconnecting");
  59. showShortMsg("usb设备连接断开");
  60. }
  61. };
  62. @Override
  63. protected void onCreate(Bundle savedInstanceState) {
  64. super.onCreate(savedInstanceState);
  65. setContentView(R.layout.activity_main);
  66. mContext = this;
  67. // step.1 initialize UVCCameraHelper
  68. mTextureView = findViewById(R.id.camera_view);
  69. mUVCCameraView = (CameraViewInterface) mTextureView;
  70. mUVCCameraView.setCallback(this);
  71. mCameraHelper = UVCCameraHelper.getInstance();
  72. mCameraHelper.setDefaultFrameFormat(UVCCameraHelper.FRAME_FORMAT_YUYV);
  73. /*
  74. * 初始化分辨率,一定是设备支持的分辨率,否则摄像不能正常使用
  75. * */
  76. mCameraHelper.setDefaultPreviewSize(640, 480);
  77. mCameraHelper.initUSBMonitor(this, mUVCCameraView, listener);
  78. mCameraHelper.setOnPreviewFrameListener(new AbstractUVCCameraHandler.OnPreViewResultListener() {
  79. int printNum = 0;
  80. @Override
  81. public void onPreviewResult(byte[] nv21Yuv) {
  82. printNum++;
  83. if (printNum == 300) {
  84. printNum = 0;
  85. Log.d(TAG, "onPreviewResult: " + nv21Yuv.length + "摄像头预览");
  86. }
  87. }
  88. });
  89. }
  90. //录像
  91. private void cameraRecording(Boolean isStartRecording, String Name) {
  92. isRecording = isStartRecording;
  93. if (mCameraHelper == null || !mCameraHelper.isCameraOpened() || !isPreview) {
  94. showShortMsg("摄像头异常,请重新更换插口并重启app");
  95. return;
  96. }
  97. String OrderRecordStr = prefs.getString(Config.ORDER_RECORDING, "");
  98. Log.d(TAG, "OrderRecorde1=" + OrderRecordStr);
  99. if (!mCameraHelper.isPushing() && isStartRecording) {
  100. //文件地址自已设置
  101. String videoPath = Config.VIDEO_DIRECTORY + "/ " + Name;
  102. OrderRecordStr = OrderRecordStr + "&" + Name;
  103. prefs.edit().putString(Config.ORDER_RECORDING, OrderRecordStr).apply();
  104. RecordParams params = new RecordParams();
  105. params.setRecordPath(videoPath);
  106. params.setRecordDuration(0); // auto divide saved,default 0 means not divided
  107. params.setVoiceClose(true); // is close voice
  108. params.setSupportOverlay(true); // overlay only support armeabi-v7a & arm64-v8a
  109. mCameraHelper.startPusher(params, new AbstractUVCCameraHandler.OnEncodeResultListener() {
  110. @Override
  111. public void onEncodeResult(byte[] data, int offset, int length, long timestamp, int type) {
  112. // type = 1,h264 video stream
  113. if (type == 1) {
  114. FileUtils.putFileStream(data, offset, length);
  115. }
  116. // type = 0,aac audio stream
  117. if (type == 0) {
  118. }
  119. }
  120. @Override
  121. public void onRecordResult(String videoPath) {
  122. if (TextUtils.isEmpty(videoPath)) {
  123. return;
  124. }
  125. new Handler(getMainLooper()).post(() -> Toast.makeText(MainActivity.this, "save videoPath:" + videoPath, Toast.LENGTH_SHORT).show());
  126. }
  127. });
  128. // if you only want to push stream,please call like this
  129. // mCameraHelper.startPusher(listener);
  130. showShortMsg("开始录制视频");
  131. } else if (mCameraHelper.isPushing() && !isStartRecording) {
  132. FileUtils.releaseFile();
  133. mCameraHelper.stopPusher();
  134. showShortMsg("停止录制视频");
  135. String[] OrderRecordArr = OrderRecordStr.split("&");
  136. if (OrderRecordArr.length > 5) {
  137. String order = OrderRecordArr[1];
  138. String filePath = Config.VIDEO_DIRECTORY + "/ " + order + ".mp4";
  139. deleteFile(filePath);
  140. String _OrderRecordStr = "";
  141. for (int i = 0; i < OrderRecordArr.length; i++) {
  142. if (OrderRecordArr[i] != order && OrderRecordArr[i].length() > 0)
  143. _OrderRecordStr = _OrderRecordStr + "&" + OrderRecordArr[i];
  144. }
  145. prefs.edit().putString(Config.ORDER_RECORDING, _OrderRecordStr).apply();
  146. Log.d(TAG, "OrderRecorde=" + prefs.getString(Config.ORDER_RECORDING, ""));
  147. }
  148. }
  149. }
  150. //删除文件
  151. public boolean deleteFile(String filePath) {
  152. File file = new File(filePath);
  153. if (file.isFile() && file.exists()) return file.delete();
  154. else if (file.isFile() && !file.exists()) return true;
  155. return false;
  156. }
  157. @Override
  158. public void onResume() {
  159. super.onResume();
  160. // 恢复Camera预览
  161. if (mUVCCameraView != null) mUVCCameraView.onResume();
  162. }
  163. @Override
  164. protected void onStart() {
  165. super.onStart();
  166. // step.2 register USB event broadcast
  167. if (mCameraHelper != null) {
  168. mCameraHelper.registerUSB();
  169. }
  170. }
  171. @Override
  172. protected void onStop() {
  173. super.onStop();
  174. // step.3 unregister USB event broadcast
  175. if (mCameraHelper != null) {
  176. mCameraHelper.unregisterUSB();
  177. }
  178. }
  179. @Override
  180. protected void onPause() {
  181. super.onPause();
  182. if (mUVCCameraView != null) mUVCCameraView.onPause();
  183. }
  184. private void showShortMsg(String msg) {
  185. Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
  186. }
  187. @Override
  188. public USBMonitor getUSBMonitor() {
  189. return mCameraHelper.getUSBMonitor();
  190. }
  191. @Override
  192. public void onDialogResult(boolean canceled) {
  193. }
  194. public boolean isCameraOpened() {
  195. return mCameraHelper.isCameraOpened();
  196. }
  197. @Override
  198. public void onSurfaceCreated(CameraViewInterface view, Surface surface) {
  199. isPreview = false;
  200. new Thread(new Runnable() {
  201. @Override
  202. public void run() {
  203. // wait for camera created
  204. try {
  205. Thread.sleep(1000);
  206. } catch (InterruptedException e) {
  207. e.printStackTrace();
  208. }
  209. Log.d(TAG, "camera: surface start preview " + isPreview + " " + isCameraOpened());
  210. if (!isPreview && isCameraOpened()) {
  211. mCameraHelper.startPreview(mUVCCameraView);
  212. isPreview = true;
  213. Log.d(TAG, "camera: surface start preview");
  214. }
  215. }
  216. }).start();
  217. }
  218. @Override
  219. public void onSurfaceChanged(CameraViewInterface view, Surface surface, int width, int height) {
  220. }
  221. @Override
  222. public void onSurfaceDestroy(CameraViewInterface view, Surface surface) {
  223. if (isPreview && isCameraOpened()) {
  224. mCameraHelper.stopPreview();
  225. Log.d(TAG, "surface:" + "is destroy");
  226. }
  227. isPreview = false;
  228. }
  229. @Override
  230. protected void onDestroy() {
  231. super.onDestroy();
  232. FileUtils.releaseFile();
  233. // step.4 release uvc camera resources
  234. if (mCameraHelper != null) {
  235. mCameraHelper.release();
  236. Log.d(TAG, "camera is release");
  237. }
  238. isPreview = false;
  239. isRequest = false;
  240. }
  241. }

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就可以了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/263032
推荐阅读
相关标签
  

闽ICP备14008679号