From 0993e849f0d38b8f5d3f5895601f3df35445bf41 Mon Sep 17 00:00:00 2001 From: jiangdongguo <765067602@qq.com> Date: Thu, 1 Mar 2018 15:28:38 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E8=A7=86=E9=A2=91=E5=BD=95?= =?UTF-8?q?=E5=88=B6=E3=80=81=E6=8B=8D=E6=91=84=E5=9B=BE=E7=89=87=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usbcamera/view/USBCameraActivity.java | 68 ++++++++------- .../main/res/layout/activity_usbcamera.xml | 14 ++++ .../jiangdg/usbcamera/UVCCameraHelper.java | 41 ++++----- .../jiangdg/usbcamera/utils/FileUtils.java | 6 +- .../java/com/serenegiant/usb/USBMonitor.java | 6 ++ .../usb/common/AbstractUVCCameraHandler.java | 84 +++++++++++-------- .../usb/common/UVCCameraHandler.java | 4 +- .../common/UVCCameraHandlerMultiSurface.java | 4 +- 8 files changed, 130 insertions(+), 97 deletions(-) diff --git a/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java b/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java index ef24337..4c8ec11 100644 --- a/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java +++ b/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java @@ -9,6 +9,7 @@ import android.support.v7.app.ActionBar; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -16,9 +17,11 @@ import android.view.Surface; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.CompoundButton; import android.widget.ListView; import android.widget.SeekBar; import android.widget.SimpleAdapter; +import android.widget.Switch; import android.widget.Toast; import com.jiangdg.usbcamera.R; @@ -44,6 +47,7 @@ import butterknife.ButterKnife; */ public class USBCameraActivity extends AppCompatActivity implements CameraDialog.CameraDialogParent, CameraViewInterface.Callback { + private static final String TAG = "Debug"; @BindView(R.id.camera_view) public View mTextureView; @BindView(R.id.toolbar) @@ -52,6 +56,8 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog public SeekBar mSeekBrightness; @BindView(R.id.seekbar_contrast) public SeekBar mSeekContrast; + @BindView(R.id.switch_rec_voice) + public Switch mSwitchVoice; private UVCCameraHelper mCameraHelper; private CameraViewInterface mUVCCameraView; @@ -126,19 +132,24 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog setContentView(R.layout.activity_usbcamera); ButterKnife.bind(this); initView(); + // step.1 initialize UVCCameraHelper mUVCCameraView = (CameraViewInterface) mTextureView; mUVCCameraView.setCallback(this); mCameraHelper = UVCCameraHelper.getInstance(); mCameraHelper.initUSBMonitor(this, mUVCCameraView, listener); + + mCameraHelper.setOnPreviewFrameListener(new AbstractUVCCameraHandler.OnPreViewResultListener() { + @Override + public void onPreviewResult(byte[] nv21Yuv) { + + } + }); } private void initView() { setSupportActionBar(mToolbar); - ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.setDisplayHomeAsUpEnabled(true); - } + mSeekBrightness.setMax(100); mSeekBrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override @@ -225,43 +236,53 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog showShortMsg("sorry,camera open failed"); return super.onOptionsItemSelected(item); } - if (!mCameraHelper.isRecording()) { String videoPath = UVCCameraHelper.ROOT_PATH + System.currentTimeMillis(); - FileUtils.createfile(FileUtils.ROOT_PATH + "test666.h264"); +// FileUtils.createfile(FileUtils.ROOT_PATH + "test666.h264"); RecordParams params = new RecordParams(); params.setRecordPath(videoPath); - params.setRecordDuration(0); // 设置为0,不分割保存 - params.setVoiceClose(false); // 不屏蔽声音 + params.setRecordDuration(0); // 设置为0,不分割保存 + params.setVoiceClose(mSwitchVoice.isChecked()); // is close voice mCameraHelper.startRecording(params, new AbstractUVCCameraHandler.OnEncodeResultListener() { @Override public void onEncodeResult(byte[] data, int offset, int length, long timestamp, int type) { - // type = 0,aac stream - // type = 1,h264 stream + // type = 1,h264 video stream if (type == 1) { - FileUtils.putFileStream(data, offset, length); +// FileUtils.putFileStream(data, offset, length); + } + // type = 0,aac audio stream + if(type == 0) { + } } @Override public void onRecordResult(String videoPath) { - showShortMsg(videoPath); + Log.i(TAG,"videoPath = "+videoPath); } }); showShortMsg("start record..."); + mSwitchVoice.setEnabled(false); } else { - FileUtils.releaseFile(); +// FileUtils.releaseFile(); mCameraHelper.stopRecording(); showShortMsg("stop record..."); + mSwitchVoice.setEnabled(true); } break; case R.id.menu_resolution: + if (mCameraHelper == null || !mCameraHelper.isCameraOpened()) { + showShortMsg("sorry,camera open failed"); + return super.onOptionsItemSelected(item); + } showResolutionListDialog(); break; case R.id.menu_focus: - if (mCameraHelper != null) { - mCameraHelper.startCameraFoucs(); + if (mCameraHelper == null || !mCameraHelper.isCameraOpened()) { + showShortMsg("sorry,camera open failed"); + return super.onOptionsItemSelected(item); } + mCameraHelper.startCameraFoucs(); break; } return super.onOptionsItemSelected(item); @@ -285,14 +306,7 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog if (tmp != null && tmp.length >= 2) { int widht = Integer.valueOf(tmp[0]); int height = Integer.valueOf(tmp[1]); - mCameraHelper.updateResolution(widht, height, new UVCCameraHelper.OnPreviewListener() { - @Override - public void onPreviewResult(boolean isSuccess) { - if (isSuccess) { - showShortMsg("update resolution to " + resolution + " success"); - } - } - }); + mCameraHelper.updateResolution(widht, height); } mDialog.dismiss(); } @@ -410,6 +424,7 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog @Override protected void onDestroy() { super.onDestroy(); + FileUtils.releaseFile(); // step.4 release uvc camera resources if (mCameraHelper != null) { mCameraHelper.release(); @@ -439,12 +454,7 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog @Override public void onSurfaceCreated(CameraViewInterface view, Surface surface) { if (!isPreview && mCameraHelper.isCameraOpened()) { - mCameraHelper.startPreview(mUVCCameraView, new AbstractUVCCameraHandler.OnPreViewResultListener() { - @Override - public void onPreviewResult(boolean result) { - - } - }); + mCameraHelper.startPreview(mUVCCameraView); isPreview = true; } } diff --git a/app/src/main/res/layout/activity_usbcamera.xml b/app/src/main/res/layout/activity_usbcamera.xml index d8a5e64..fc839fb 100644 --- a/app/src/main/res/layout/activity_usbcamera.xml +++ b/app/src/main/res/layout/activity_usbcamera.xml @@ -77,4 +77,18 @@ android:layout_height="match_parent" /> + + \ No newline at end of file diff --git a/libusbcamera/src/main/java/com/jiangdg/usbcamera/UVCCameraHelper.java b/libusbcamera/src/main/java/com/jiangdg/usbcamera/UVCCameraHelper.java index be22997..314101e 100644 --- a/libusbcamera/src/main/java/com/jiangdg/usbcamera/UVCCameraHelper.java +++ b/libusbcamera/src/main/java/com/jiangdg/usbcamera/UVCCameraHelper.java @@ -73,10 +73,6 @@ public class UVCCameraHelper { void onDisConnectDev(UsbDevice device); } - public interface OnPreviewListener { - void onPreviewResult(boolean isSuccess); - } - public void initUSBMonitor(Activity activity, CameraViewInterface cameraView, final OnMyDevConnectListener listener) { this.mActivityWrf = new WeakReference<>(activity); this.mCamViewWrf = new WeakReference<>(cameraView); @@ -106,14 +102,10 @@ public class UVCCameraHelper { public void onConnect(final UsbDevice device, USBMonitor.UsbControlBlock ctrlBlock, boolean createNew) { mCtrlBlock = ctrlBlock; openCamera(ctrlBlock); - startPreview(mCamViewWrf.get(), new AbstractUVCCameraHandler.OnPreViewResultListener() { - @Override - public void onPreviewResult(boolean isConnected) { - if (listener != null) { - listener.onConnectDev(device, isConnected); - } - } - }); + startPreview(mCamViewWrf.get()); + if(listener != null) { + listener.onConnectDev(device,true); + } } // called by disconnect to usb camera @@ -148,7 +140,7 @@ public class UVCCameraHelper { previewWidth, previewHeight, PREVIEW_FORMAT); } - public void updateResolution(int width, int height, final OnPreviewListener mPreviewListener) { + public void updateResolution(int width, int height) { if (previewWidth == width && previewHeight == height) { return; } @@ -162,14 +154,7 @@ public class UVCCameraHelper { mCameraHandler = UVCCameraHandler.createHandler(mActivityWrf.get(), mCamViewWrf.get(), 2, previewWidth, previewHeight, PREVIEW_FORMAT); openCamera(mCtrlBlock); - startPreview(mCamViewWrf.get(), new AbstractUVCCameraHandler.OnPreViewResultListener() { - @Override - public void onPreviewResult(boolean result) { - if (mPreviewListener != null) { - mPreviewListener.onPreviewResult(result); - } - } - }); + startPreview(mCamViewWrf.get()); } public void registerUSB() { @@ -229,9 +214,9 @@ public class UVCCameraHelper { return mUSBMonitor.getDeviceList(deviceFilters.get(0)); } - public void capturePicture(String savePath, AbstractUVCCameraHandler.OnCaptureListener listener) { + public void capturePicture(String savePath) { if (mCameraHandler != null && mCameraHandler.isOpened()) { - mCameraHandler.captureStill(savePath, listener); + mCameraHandler.captureStill(savePath); } } @@ -278,16 +263,22 @@ public class UVCCameraHelper { return mUSBMonitor; } + public void setOnPreviewFrameListener(AbstractUVCCameraHandler.OnPreViewResultListener listener) { + if(mCameraHandler != null) { + mCameraHandler.setOnPreViewResultListener(listener); + } + } + private void openCamera(USBMonitor.UsbControlBlock ctrlBlock) { if (mCameraHandler != null) { mCameraHandler.open(ctrlBlock); } } - public void startPreview(CameraViewInterface cameraView, AbstractUVCCameraHandler.OnPreViewResultListener mPreviewListener) { + public void startPreview(CameraViewInterface cameraView) { SurfaceTexture st = cameraView.getSurfaceTexture(); if (mCameraHandler != null) { - mCameraHandler.startPreview(st, mPreviewListener); + mCameraHandler.startPreview(st); } } diff --git a/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/FileUtils.java b/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/FileUtils.java index 6d1637d..cf5af28 100644 --- a/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/FileUtils.java +++ b/libusbcamera/src/main/java/com/jiangdg/usbcamera/utils/FileUtils.java @@ -31,8 +31,10 @@ public class FileUtils { public static void releaseFile(){ try { - outputStream.flush(); - outputStream.close(); + if(outputStream != null) { + outputStream.flush(); + outputStream.close(); + } } catch (IOException e) { e.printStackTrace(); } diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/USBMonitor.java b/libusbcamera/src/main/java/com/serenegiant/usb/USBMonitor.java index fe46a6c..5766184 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/USBMonitor.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/USBMonitor.java @@ -24,6 +24,7 @@ package com.serenegiant.usb; import android.annotation.SuppressLint; +import android.annotation.TargetApi; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; @@ -33,6 +34,7 @@ import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbInterface; import android.hardware.usb.UsbManager; +import android.os.Build; import android.os.Handler; import android.text.TextUtils; import android.util.Log; @@ -882,6 +884,7 @@ public final class USBMonitor { * @param _info * @return */ + @TargetApi(Build.VERSION_CODES.M) public static UsbDeviceInfo updateDeviceInfo(final UsbManager manager, final UsbDevice device, final UsbDeviceInfo _info) { final UsbDeviceInfo info = _info != null ? _info : new UsbDeviceInfo(); info.clear(); @@ -897,6 +900,9 @@ public final class USBMonitor { } if ((manager != null) && manager.hasPermission(device)) { final UsbDeviceConnection connection = manager.openDevice(device); + if(connection == null) { + return null; + } final byte[] desc = connection.getRawDescriptors(); if (TextUtils.isEmpty(info.usb_version)) { diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java b/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java index 14d5df8..c3f44fe 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java @@ -16,6 +16,8 @@ import android.util.Log; import android.view.Surface; import android.view.SurfaceHolder; +import com.jiangdg.usbcamera.task.SaveYuvImageTask; +import com.jiangdg.usbcamera.utils.YUVBean; import com.serenegiant.usb.IFrameCallback; import com.serenegiant.usb.Size; import com.serenegiant.usb.USBMonitor; @@ -74,7 +76,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { } public interface OnPreViewResultListener{ - void onPreviewResult(boolean result); + void onPreviewResult(byte[] data); } public interface OnCaptureListener { @@ -97,6 +99,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { private final WeakReference mWeakThread; private volatile boolean mReleased; + protected boolean isCaptureStill; protected AbstractUVCCameraHandler(final CameraThread thread) { mWeakThread = new WeakReference(thread); @@ -174,21 +177,26 @@ public abstract class AbstractUVCCameraHandler extends Handler { } // 开启Camera预览 - protected void startPreview(final Object surface,OnPreViewResultListener listener) { + public void startPreview(final Object surface) { checkReleased(); if (!((surface instanceof SurfaceHolder) || (surface instanceof Surface) || (surface instanceof SurfaceTexture))) { throw new IllegalArgumentException("surface should be one of SurfaceHolder, Surface or SurfaceTexture: "+surface); } - this.mPreviewListener = listener; sendMessage(obtainMessage(MSG_PREVIEW_START, surface)); } + public void setOnPreViewResultListener(OnPreViewResultListener listener) { + AbstractUVCCameraHandler.mPreviewListener = listener; + } + // 关闭Camera预览 public void stopPreview() { if (DEBUG) Log.v(TAG, "stopPreview:"); removeMessages(MSG_PREVIEW_START); - stopRecording(); + if(isRecording()) { + stopRecording(); + } if (isPreviewing()) { final CameraThread thread = mWeakThread.get(); if (thread == null) return; @@ -208,16 +216,11 @@ public abstract class AbstractUVCCameraHandler extends Handler { if (DEBUG) Log.v(TAG, "stopPreview:finished"); } - // 捕获图像 - protected void captureStill() { - checkReleased(); - sendEmptyMessage(MSG_CAPTURE_STILL); - } - public void captureStill(final String path,AbstractUVCCameraHandler.OnCaptureListener listener) { - AbstractUVCCameraHandler.mCaptureListener = listener; - checkReleased(); - sendMessage(obtainMessage(MSG_CAPTURE_STILL, path)); + // old method, to get screen size picture +// AbstractUVCCameraHandler.mCaptureListener = listener; +// checkReleased(); +// sendMessage(obtainMessage(MSG_CAPTURE_STILL, path)); } // 开始录制 @@ -350,7 +353,8 @@ public abstract class AbstractUVCCameraHandler extends Handler { thread.handleStopPreview(); break; case MSG_CAPTURE_STILL: - thread.handleCaptureStill((String)msg.obj); +// thread.handleCaptureStill((String)msg.obj); + thread.handleStillPicture((String)msg.obj); break; case MSG_CAPTURE_START: // thread.handleStartRecording((String)msg.obj); @@ -369,13 +373,6 @@ public abstract class AbstractUVCCameraHandler extends Handler { case MSG_CAMERA_FOUCS: thread.handleCameraFoucs(); break; - // 音频线程 -// case MSG_AUDIO_START: -// thread.startAudioRecord(); -// break; -// case MSG_AUDIO_STOP: -// thread.stopAudioRecord(); -// break; default: throw new RuntimeException("unsupported message:what=" + msg.what); } @@ -529,17 +526,10 @@ public abstract class AbstractUVCCameraHandler extends Handler { if ((mUVCCamera == null) || mIsPreviewing) return; try { mUVCCamera.setPreviewSize(mWidth, mHeight, 1, 31, mPreviewMode, mBandwidthFactor); - if(mPreviewListener != null){ - mPreviewListener.onPreviewResult(true); - } // 获取USB Camera预览数据 mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_NV21); } catch (final IllegalArgumentException e) { - // 添加分辨率参数合法性检测 - if(mPreviewListener != null){ - mPreviewListener.onPreviewResult(false); - } // try { // // fallback to YUV mode // mUVCCamera.setPreviewSize(mWidth, mHeight, 1, 31, UVCCamera.DEFAULT_PREVIEW_MODE, mBandwidthFactor); @@ -568,6 +558,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { if (mIsPreviewing) { if (mUVCCamera != null) { mUVCCamera.stopPreview(); + mUVCCamera.setFrameCallback(null, 0); } synchronized (mSync) { mIsPreviewing = false; @@ -688,11 +679,10 @@ public abstract class AbstractUVCCameraHandler extends Handler { // 停止音视频编码线程 stopAudioRecord(); stopVideoRecord(); - // 停止捕获视频数据 - if (mUVCCamera != null) { - mUVCCamera.stopCapture(); - mUVCCamera.setFrameCallback(null, 0); - } +// // 停止捕获视频数据 +// if (mUVCCamera != null) { +// mUVCCamera.stopCapture(); +// } mWeakCameraView.get().setVideoEncoder(null); // you should not wait here callOnStopRecording(); @@ -751,7 +741,6 @@ public abstract class AbstractUVCCameraHandler extends Handler { if(mAacConsumer != null){ mAacConsumer.setTmpuMuxer(mMuxer); } -// isAudioThreadStart = true; } private void stopAudioRecord(){ @@ -773,7 +762,11 @@ public abstract class AbstractUVCCameraHandler extends Handler { // isAudioThreadStart = false; } - private boolean isCaptureStill; + private String picPath; + + public void handleStillPicture(String picPath) { + this.picPath = picPath; + } private final IFrameCallback mIFrameCallback = new IFrameCallback() { @Override @@ -789,9 +782,26 @@ public abstract class AbstractUVCCameraHandler extends Handler { int len = frame.capacity(); byte[] yuv = new byte[len]; frame.get(yuv); + // nv21 yuv data callback + if(mPreviewListener != null) { + mPreviewListener.onPreviewResult(yuv); + } // 捕获图片 - if(isCaptureStill) { - + if(! TextUtils.isEmpty(picPath)) { + YUVBean bean = new YUVBean(); + bean.setYuvData(yuv); + bean.setPicPath(picPath); + bean.setWidth(mWidth); + bean.setHeight(mHeight); + new SaveYuvImageTask(bean, new SaveYuvImageTask.OnSaveYuvResultListener() { + @Override + public void onSaveResult(String savePath) { + if(mCaptureListener != null) { + mCaptureListener.onCaptureResult(savePath); + } + picPath = null; + } + }).execute(); } // 视频 if(mH264Consumer != null){ diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java b/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java index c0fbf0a..22130f8 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java @@ -119,8 +119,8 @@ public class UVCCameraHandler extends AbstractUVCCameraHandler { } @Override - public void startPreview(final Object surface,final AbstractUVCCameraHandler.OnPreViewResultListener listener) { - super.startPreview(surface, listener); + public void startPreview(final Object surface) { + super.startPreview(surface); } @Override diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java b/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java index d0a756d..c50daf0 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java @@ -136,10 +136,10 @@ public class UVCCameraHandlerMultiSurface extends AbstractUVCCameraHandler { } } - public synchronized void startPreview(OnPreViewResultListener listener) { + public synchronized void startPreview() { checkReleased(); if (mRendererHolder != null) { - super.startPreview(mRendererHolder.getSurface(),listener); + super.startPreview(mRendererHolder.getSurface()); } else { throw new IllegalStateException(); }