From 2657ff0e8e2d0f2cbe332f4718e01338de8ca6f5 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Thu, 1 Mar 2018 18:03:08 +0100 Subject: [PATCH] Add setVideoMaxDuration() API --- README.md | 53 +++++++++++++------ .../cameraview/MockCameraController.java | 5 ++ .../com/otaliastudios/cameraview/Camera1.java | 38 ++++++------- .../com/otaliastudios/cameraview/Camera2.java | 5 ++ .../cameraview/CameraController.java | 5 +- .../otaliastudios/cameraview/CameraView.java | 36 ++++++++----- cameraview/src/main/res/values/attrs.xml | 2 + 7 files changed, 96 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 4a46c8da..2e3703f3 100644 --- a/README.md +++ b/README.md @@ -139,8 +139,8 @@ ensure lower quality output. ### Capturing Video -To capture video just call `CameraView.startRecordingVideo(file)` to start, and -`CameraView.stopRecordingVideo()` to finish. Make sure you setup a `CameraListener` to handle +To capture video just call `CameraView.startCapturingVideo(file)` to start, and +`CameraView.stopCapturingVideo()` to finish. Make sure you setup a `CameraListener` to handle the video callback. ```java @@ -154,20 +154,16 @@ camera.addCameraListener(new CameraListener() { // Select output file. Make sure you have write permissions. File file = ...; +camera.startCapturingVideo(file); -// Record a 2500 ms video: -camera.startRecordingVideo(file, 2500); - -// Full version -camera.startRecordingVideo(file); -camera.postDelayed(new Runnable() { - @Override - public void run() { - // This will trigger onVideoTaken(). - camera.stopRecordingVideo(); - } -}, 2500); +// Later... stop recording. This will trigger onVideoTaken(). +camera.stopCapturingVideo(); +// You can also use one of the video constraints: +// videoMaxSize and videoMaxDuration will automatically stop recording when satisfied. +camera.setVideoMaxSize(100000); +camera.setVideoMaxDuration(5000); +camera.startCapturingVideo(file); ``` ### Other camera events @@ -406,7 +402,9 @@ Most camera parameters can be controlled through XML attributes or linked method app:cameraWhiteBalance="auto" app:cameraHdr="off" app:cameraAudio="on" - app:cameraPlaySounds="true"/> + app:cameraPlaySounds="true" + app:cameraVideoMaxSize="0" + app:cameraVideoMaxDuration="0"/> ``` |XML Attribute|Method|Values|Default Value| @@ -422,6 +420,8 @@ Most camera parameters can be controlled through XML attributes or linked method |[`cameraHdr`](#camerahdr)|`setHdr()`|`off` `on`|`off`| |[`cameraAudio`](#cameraaudio)|`setAudio()`|`off` `on`|`on`| |[`cameraPlaySounds`](#cameraplaysounds)|`setPlaySounds()`|`true` `false`|`true`| +|[`cameraVideoMaxSize`](#cameravideomaxsize)|`setVideoMaxSize()`|number|`0`| +|[`cameraVideoMaxDuration`](#cameravideomaxduration)|`setVideoMaxDuration()`|number|`0`| #### cameraSessionType @@ -547,6 +547,28 @@ cameraView.setPlaySounds(true); cameraView.setPlaySounds(false); ``` +#### cameraVideoMaxSize + +Defines the maximum size in bytes for recorded video files. +Once this size is reached, the recording will automatically stop. +Defaults to unlimited size. Use 0 or negatives to disable. + +```java +cameraView.setVideoMaxSize(100000); +cameraView.setVideoMaxSize(0); // Disable +``` + +#### cameraVideoMaxDuration + +Defines the maximum duration in milliseconds for video recordings. +Once this duration is reached, the recording will automatically stop. +Defaults to unlimited duration. Use 0 or negatives to disable. + +```java +cameraView.setVideoMaxDuration(100000); +cameraView.setVideoMaxDuration(0); // Disable +``` + ## Frame Processing We support frame processors that will receive data from the camera preview stream: @@ -606,7 +628,6 @@ Other APIs not mentioned above are provided, and are well documented and comment |`getPreviewSize()`|Returns the size of the preview surface. If CameraView was not constrained in its layout phase (e.g. it was `wrap_content`), this will return the same aspect ratio of CameraView.| |`getSnapshotSize()`|Returns `getPreviewSize()`, since a snapshot is a preview frame.| |`getPictureSize()`|Returns the size of the output picture. The aspect ratio is consistent with `getPreviewSize()`.| -|`setVideoMaxSize(long)`|Set a max file size (in bytes) for a video recording. There is no file size limit by default unless set by the user.| Take also a look at public methods in `CameraUtils`, `CameraOptions`, `ExtraProperties`. diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java index a9e16af4..950fa5a8 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java @@ -130,6 +130,11 @@ public class MockCameraController extends CameraController { } + @Override + void setVideoMaxDuration(int videoMaxDurationMillis) { + + } + @Override void setPlaySounds(boolean playSounds) { diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java index 893dab91..a4fe058c 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java @@ -696,31 +696,28 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera } if (mLocation != null) { - mMediaRecorder.setLocation((float) mLocation.getLatitude(), + mMediaRecorder.setLocation( + (float) mLocation.getLatitude(), (float) mLocation.getLongitude()); } mMediaRecorder.setOutputFile(mVideoFile.getAbsolutePath()); mMediaRecorder.setOrientationHint(computeSensorToOutputOffset()); - //If the user sets a max file size, set it to the max file size - if (mVideoMaxSizeInBytes > 0) { - mMediaRecorder.setMaxFileSize(mVideoMaxSizeInBytes); - - //Attach a listener to the media recorder to listen for file size notifications - mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() { - @Override - public void onInfo(MediaRecorder mediaRecorder, int i, int i1) { - switch (i) { - case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED: { - endVideoImmediately(); - break; - } - } + mMediaRecorder.setMaxFileSize(mVideoMaxSize); + mMediaRecorder.setMaxDuration(mVideoMaxDuration); + mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() { + @Override + public void onInfo(MediaRecorder mediaRecorder, int what, int extra) { + switch (what) { + case MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED: + case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED: + endVideoImmediately(); + break; } - }); - } + } + }); // Not needed. mMediaRecorder.setPreviewDisplay(mPreview.getSurface()); } @@ -881,7 +878,12 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera @Override void setVideoMaxSize(long videoMaxSizeInBytes) { - mVideoMaxSizeInBytes = videoMaxSizeInBytes; + mVideoMaxSize = videoMaxSizeInBytes; + } + + @Override + void setVideoMaxDuration(int videoMaxDurationMillis) { + mVideoMaxDuration = videoMaxDurationMillis; } @Override diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java index 9b827890..3ed92e0e 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java @@ -120,6 +120,11 @@ class Camera2 extends CameraController { } + @Override + void setVideoMaxDuration(int videoMaxDurationMillis) { + + } + @Override void setPlaySounds(boolean playSounds) { diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java index d98f9e96..10fe8423 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java @@ -55,6 +55,8 @@ abstract class CameraController implements protected SizeSelector mPictureSizeSelector; protected MediaRecorder mMediaRecorder; protected File mVideoFile; + protected long mVideoMaxSize; + protected int mVideoMaxDuration; protected Size mPictureSize; protected Size mPreviewSize; protected int mPreviewFormat; @@ -67,7 +69,6 @@ abstract class CameraController implements protected boolean mIsCapturingVideo = false; protected int mState = STATE_STOPPED; - protected long mVideoMaxSizeInBytes = 0; // Used for testing. Task mZoomTask = new Task<>(); @@ -322,6 +323,8 @@ abstract class CameraController implements abstract void setVideoMaxSize(long videoMaxSizeInBytes); + abstract void setVideoMaxDuration(int videoMaxDurationMillis); + abstract void setPlaySounds(boolean playSounds); //endregion diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 46e35d49..af476dbc 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -107,6 +107,8 @@ public class CameraView extends FrameLayout { SessionType sessionType = SessionType.fromValue(a.getInteger(R.styleable.CameraView_cameraSessionType, SessionType.DEFAULT.value())); Hdr hdr = Hdr.fromValue(a.getInteger(R.styleable.CameraView_cameraHdr, Hdr.DEFAULT.value())); Audio audio = Audio.fromValue(a.getInteger(R.styleable.CameraView_cameraAudio, Audio.DEFAULT.value())); + long videoMaxSize = (long) a.getFloat(R.styleable.CameraView_cameraVideoMaxSize, 0); + int videoMaxDuration = a.getInteger(R.styleable.CameraView_cameraVideoMaxDuration, 0); // Size selectors List constraints = new ArrayList<>(3); @@ -145,9 +147,6 @@ public class CameraView extends FrameLayout { GestureAction scrollHorizontalGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureScrollHorizontal, GestureAction.DEFAULT_SCROLL_HORIZONTAL.value())); GestureAction scrollVerticalGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureScrollVertical, GestureAction.DEFAULT_SCROLL_VERTICAL.value())); - //Get max size - float cameraVideoMaxSize = a.getFloat(R.styleable.CameraView_cameraVideoMaxSize, -1); - a.recycle(); // Components @@ -182,6 +181,8 @@ public class CameraView extends FrameLayout { setHdr(hdr); setAudio(audio); setPictureSize(selector); + setVideoMaxSize(videoMaxSize); + setVideoMaxDuration(videoMaxDuration); // Apply gestures mapGesture(Gesture.TAP, tapGesture); @@ -190,11 +191,6 @@ public class CameraView extends FrameLayout { mapGesture(Gesture.SCROLL_HORIZONTAL, scrollHorizontalGesture); mapGesture(Gesture.SCROLL_VERTICAL, scrollVerticalGesture); - //Set camera video maxSize - if(cameraVideoMaxSize > 0) { - setVideoMaxSize((long)cameraVideoMaxSize); - } - if (!isInEditMode()) { mOrientationHelper = new OrientationHelper(context, mCameraCallbacks); } @@ -1253,9 +1249,11 @@ public class CameraView extends FrameLayout { * * @param file a file where the video will be saved * @param durationMillis video max duration - * * @throws IllegalArgumentException if durationMillis is less than 500 milliseconds + * + * @deprecated This is not reliable. Please use {@link #setVideoMaxDuration(int)}. */ + @Deprecated public void startCapturingVideo(File file, long durationMillis) { if (durationMillis < 500) { throw new IllegalArgumentException("Video duration can't be < 500 milliseconds"); @@ -1379,15 +1377,27 @@ public class CameraView extends FrameLayout { } /** - * Set a max file size (in bytes) for a video recording. There is no file size limit by default - * unless set by the user. + * Sets the maximum size in bytes for recorded video files. + * Once this size is reached, the recording will automatically stop. + * Defaults to unlimited size. Use 0 or negatives to disable. * - * @param videoMaxSizeInBytes The maximum size of videos in bytes + * @param videoMaxSizeInBytes The maximum video size in bytes */ - public void setVideoMaxSize(long videoMaxSizeInBytes){ + public void setVideoMaxSize(long videoMaxSizeInBytes) { mCameraController.setVideoMaxSize(videoMaxSizeInBytes); } + /** + * Sets the maximum duration in milliseconds for video recordings. + * Once this duration is reached, the recording will automatically stop. + * Defaults to unlimited duration. Use 0 or negatives to disable. + * + * @param videoMaxDurationMillis The maximum video duration in milliseconds + */ + public void setVideoMaxDuration(int videoMaxDurationMillis) { + mCameraController.setVideoMaxDuration(videoMaxDurationMillis); + } + /** * Returns true if the camera is currently recording a video * @return boolean indicating if the camera is recording a video diff --git a/cameraview/src/main/res/values/attrs.xml b/cameraview/src/main/res/values/attrs.xml index d52abdd1..f38db8ea 100644 --- a/cameraview/src/main/res/values/attrs.xml +++ b/cameraview/src/main/res/values/attrs.xml @@ -112,6 +112,8 @@ + +