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 6873691..7c4c2f5 100644 --- a/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java +++ b/app/src/main/java/com/jiangdg/usbcamera/view/USBCameraActivity.java @@ -156,6 +156,10 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog // mUSBManager.startCameraFoucs(); // showShortMsg("对焦相机"); List list = mUSBManager.getSupportedPreviewSizes(); + if(list == null) { + return; + } + StringBuilder sb = new StringBuilder(); for(Size size:list){ sb.append(size.width+"x"+size.height); @@ -170,9 +174,12 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog } String picPath = USBCameraManager.ROOT_PATH+System.currentTimeMillis() +USBCameraManager.SUFFIX_PNG; - mUSBManager.capturePicture(picPath); - - showShortMsg("保存路径:"+picPath); + mUSBManager.capturePicture(picPath, new AbstractUVCCameraHandler.OnCaptureListener() { + @Override + public void onCaptureResult(String path) { + showShortMsg("保存路径:"+path); + } + }); break; case R.id.btn_rec_video: if(mUSBManager == null || ! mUSBManager.isCameraOpened()){ @@ -196,6 +203,11 @@ public class USBCameraActivity extends AppCompatActivity implements CameraDialog FileUtils.putFileStream(data,offset,length); } } + + @Override + public void onRecordResult(String videoPath) { + showShortMsg(videoPath); + } }); mBtnRecord.setText("正在录制"); diff --git a/libusbcamera/src/main/java/com/jiangdg/usbcamera/USBCameraManager.java b/libusbcamera/src/main/java/com/jiangdg/usbcamera/USBCameraManager.java index 4fd4a05..5d3f2bb 100644 --- a/libusbcamera/src/main/java/com/jiangdg/usbcamera/USBCameraManager.java +++ b/libusbcamera/src/main/java/com/jiangdg/usbcamera/USBCameraManager.java @@ -57,6 +57,7 @@ public class USBCameraManager{ public interface OnMyDevConnectListener{ void onAttachDev(UsbDevice device); void onDettachDev(UsbDevice device); + void onConnectDev(UsbDevice device,boolean isConnected); void onDisConnectDev(UsbDevice device); } @@ -213,9 +214,9 @@ public class USBCameraManager{ } // 拍照 - public void capturePicture(String savePath){ + public void capturePicture(String savePath,AbstractUVCCameraHandler.OnCaptureListener listener){ if(mCameraHandler != null && mCameraHandler.isOpened()){ - mCameraHandler.captureStill(savePath); + mCameraHandler.captureStill(savePath,listener); } } 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 8bbd649..2c7767e 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/common/AbstractUVCCameraHandler.java @@ -70,15 +70,21 @@ public abstract class AbstractUVCCameraHandler extends Handler { public static OnEncodeResultListener mListener; public static OnPreViewResultListener mPreviewListener; + public static OnCaptureListener mCaptureListener; public interface OnEncodeResultListener{ void onEncodeResult(byte[] data, int offset, int length, long timestamp, int type); + void onRecordResult(String videoPath); } public interface OnPreViewResultListener{ void onPreviewResult(boolean result); } + public interface OnCaptureListener { + void onCaptureResult(String picPath); + } + private static final int MSG_OPEN = 0; private static final int MSG_CLOSE = 1; private static final int MSG_PREVIEW_START = 2; @@ -175,7 +181,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { protected void startPreview(final Object surface,OnPreViewResultListener listener) { checkReleased(); if (!((surface instanceof SurfaceHolder) || (surface instanceof Surface) || (surface instanceof SurfaceTexture))) { - throw new IllegalArgumentException("surface should be one of SurfaceHolder, Surface or SurfaceTexture"); + throw new IllegalArgumentException("surface should be one of SurfaceHolder, Surface or SurfaceTexture: "+surface); } this.mPreviewListener = listener; @@ -212,7 +218,8 @@ public abstract class AbstractUVCCameraHandler extends Handler { sendEmptyMessage(MSG_CAPTURE_STILL); } - protected void captureStill(final String path) { + public void captureStill(final String path,AbstractUVCCameraHandler.OnCaptureListener listener) { + AbstractUVCCameraHandler.mCaptureListener = listener; checkReleased(); sendMessage(obtainMessage(MSG_CAPTURE_STILL, path)); } @@ -401,6 +408,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { // private MediaMuxerWrapper mMuxer; private MediaVideoBufferEncoder mVideoEncoder; private Mp4MediaMuxer mMuxer; + private String videoPath; // private boolean isAudioThreadStart; /** 构造方法 @@ -583,12 +591,12 @@ public abstract class AbstractUVCCameraHandler extends Handler { // the file name is came from current time. // You should use extension name as same as CompressFormat when calling Bitmap#compress. final File outputFile = TextUtils.isEmpty(path) - ? MediaMuxerWrapper.getCaptureFile(Environment.DIRECTORY_DCIM, ".png") + ? MediaMuxerWrapper.getCaptureFile(Environment.DIRECTORY_DCIM, ".jpg") : new File(path); final BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile)); try { try { - bitmap.compress(Bitmap.CompressFormat.PNG, 100, os); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os); os.flush(); mHandler.sendMessage(mHandler.obtainMessage(MSG_MEDIA_UPDATE, outputFile.getPath())); } catch (final IOException e) { @@ -596,6 +604,9 @@ public abstract class AbstractUVCCameraHandler extends Handler { } finally { os.close(); } + if(mCaptureListener != null) { + mCaptureListener.onCaptureResult(path); + } } catch (final Exception e) { callOnError(e); } @@ -654,6 +665,7 @@ public abstract class AbstractUVCCameraHandler extends Handler { // 获取USB Camera预览数据 mUVCCamera.setFrameCallback(mIFrameCallback, UVCCamera.PIXEL_FORMAT_NV21); // 初始化混合器 + videoPath = params.getRecordPath(); mMuxer = new Mp4MediaMuxer(params.getRecordPath(), params.getRecordDuration() * 60 * 1000); @@ -685,6 +697,10 @@ public abstract class AbstractUVCCameraHandler extends Handler { mWeakCameraView.get().setVideoEncoder(null); // you should not wait here callOnStopRecording(); + // 返回路径 + if(mListener != null) { + mListener.onRecordResult(videoPath+".mp4"); + } } private void startVideoRecord() { 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 55f9121..c0fbf0a 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandler.java @@ -129,8 +129,8 @@ public class UVCCameraHandler extends AbstractUVCCameraHandler { } @Override - public void captureStill(final String path) { - super.captureStill(path); + public void captureStill(final String path,OnCaptureListener listener) { + super.captureStill(path,listener); } @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 53f7b63..d0a756d 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/common/UVCCameraHandlerMultiSurface.java @@ -163,7 +163,7 @@ public class UVCCameraHandlerMultiSurface extends AbstractUVCCameraHandler { } @Override - public void captureStill(final String path) { + public void captureStill(final String path,OnCaptureListener listener) { checkReleased(); post(new Runnable() { @Override diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/encoder/RecordParams.java b/libusbcamera/src/main/java/com/serenegiant/usb/encoder/RecordParams.java index 361f1fd..ffb9f4e 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/encoder/RecordParams.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/encoder/RecordParams.java @@ -9,6 +9,7 @@ public class RecordParams { private String recordPath; private int recordDuration; private boolean voiceClose; + private boolean isAutoSave; public boolean isVoiceClose() { return voiceClose; @@ -33,4 +34,12 @@ public class RecordParams { public void setRecordDuration(int recordDuration) { this.recordDuration = recordDuration; } + + public boolean isAutoSave() { + return isAutoSave; + } + + public void setAutoSave(boolean autoSave) { + isAutoSave = autoSave; + } } diff --git a/libusbcamera/src/main/java/com/serenegiant/usb/encoder/biz/Mp4MediaMuxer.java b/libusbcamera/src/main/java/com/serenegiant/usb/encoder/biz/Mp4MediaMuxer.java index e08b7f0..b2fa4f6 100644 --- a/libusbcamera/src/main/java/com/serenegiant/usb/encoder/biz/Mp4MediaMuxer.java +++ b/libusbcamera/src/main/java/com/serenegiant/usb/encoder/biz/Mp4MediaMuxer.java @@ -18,9 +18,9 @@ import java.nio.ByteBuffer; public class Mp4MediaMuxer { private static final boolean VERBOSE = false; private static final String TAG = Mp4MediaMuxer.class.getSimpleName(); - private final String mFilePath; + private String mFilePath; private MediaMuxer mMuxer; - private final long durationMillis; + private long durationMillis; private int index = 0; private int mVideoTrackIndex = -1; private int mAudioTrackIndex = -1; @@ -30,12 +30,17 @@ public class Mp4MediaMuxer { // 文件路径;文件时长 public Mp4MediaMuxer(String path, long durationMillis) { - mFilePath = path; + String mFilePath; this.durationMillis = durationMillis; + if(durationMillis != 0) { + mFilePath = path + "-" + index++ + ".mp4"; + }else{ + mFilePath = path+".mp4"; + } Object mux = null; try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - mux = new MediaMuxer(path + "-" + index++ + ".mp4", MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); + mux = new MediaMuxer(mFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); } } catch (IOException e) { e.printStackTrace();