Max video file size (#104)

* Added a maximum file size for videos

* Revereted changes to the onVideoTaken callback signature

* Renamed isRecordingVideo, added xml attribute for video max size and updated the documentation
pull/130/merge
chaitanyaraghav 7 years ago committed by Mattia Iavarone
parent 34bb5f1c45
commit 1bd1816919
  1. 1
      README.md
  2. 3
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewCallbacksTest.java
  3. 10
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java
  4. 5
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java
  5. 28
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  6. 16
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java
  7. 7
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java
  8. 27
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  9. 2
      cameraview/src/main/res/values/attrs.xml
  10. 13
      demo/src/main/java/com/otaliastudios/cameraview/demo/CameraActivity.java

@ -595,6 +595,7 @@ 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.| |`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.| |`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()`.| |`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`. Take also a look at public methods in `CameraUtils`, `CameraOptions`, `ExtraProperties`.

@ -19,16 +19,13 @@ import org.mockito.stubbing.Stubber;
import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyFloat; import static org.mockito.Matchers.anyFloat;
import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;

@ -3,7 +3,6 @@ package com.otaliastudios.cameraview;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.PointF; import android.graphics.PointF;
import android.media.MediaRecorder;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.support.test.rule.ActivityTestRule; import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4; import android.support.test.runner.AndroidJUnit4;
@ -20,8 +19,13 @@ import java.io.File;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.mockito.Mockito.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.*; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
/** /**

@ -124,4 +124,9 @@ public class MockCameraController extends CameraController {
@Override @Override
public void onBufferAvailable(byte[] buffer) { public void onBufferAvailable(byte[] buffer) {
} }
@Override
void setVideoMaxSize(long videoMaxSizeInBytes) {
}
} }

@ -676,6 +676,25 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
mMediaRecorder.setOutputFile(mVideoFile.getAbsolutePath()); mMediaRecorder.setOutputFile(mVideoFile.getAbsolutePath());
mMediaRecorder.setOrientationHint(computeSensorToOutputOffset()); 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;
}
}
}
});
}
// Not needed. mMediaRecorder.setPreviewDisplay(mPreview.getSurface()); // Not needed. mMediaRecorder.setPreviewDisplay(mPreview.getSurface());
} }
@ -833,4 +852,13 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
LOG.i("size:", "sizesFromList:", result); LOG.i("size:", "sizesFromList:", result);
return result; return result;
} }
@Override
void setVideoMaxSize(long videoMaxSizeInBytes) {
mVideoMaxSizeInBytes = videoMaxSizeInBytes;
}
// -----------------
// Additional helper info
} }

@ -1,23 +1,12 @@
package com.otaliastudios.cameraview; package com.otaliastudios.cameraview;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.PointF; import android.graphics.PointF;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.location.Location; import android.location.Location;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@TargetApi(21) @TargetApi(21)
class Camera2 extends CameraController { class Camera2 extends CameraController {
@ -125,4 +114,9 @@ class Camera2 extends CameraController {
public void onBufferAvailable(byte[] buffer) { public void onBufferAvailable(byte[] buffer) {
} }
@Override
void setVideoMaxSize(long videoMaxSizeInBytes) {
}
} }

@ -66,6 +66,7 @@ abstract class CameraController implements
protected boolean mIsCapturingVideo = false; protected boolean mIsCapturingVideo = false;
protected int mState = STATE_STOPPED; protected int mState = STATE_STOPPED;
protected long mVideoMaxSizeInBytes = 0;
// Used for testing. // Used for testing.
Task<Void> mZoomTask = new Task<>(); Task<Void> mZoomTask = new Task<>();
@ -317,6 +318,8 @@ abstract class CameraController implements
abstract void startAutoFocus(@Nullable Gesture gesture, PointF point); abstract void startAutoFocus(@Nullable Gesture gesture, PointF point);
abstract void setVideoMaxSize(long videoMaxSizeInBytes);
//endregion //endregion
//region final getters //region final getters
@ -383,6 +386,10 @@ abstract class CameraController implements
return mPreviewSize; return mPreviewSize;
} }
final boolean isCapturingVideo() {
return mIsCapturingVideo;
}
//endregion //endregion
//region Orientation utils //region Orientation utils

@ -144,6 +144,10 @@ public class CameraView extends FrameLayout {
GestureAction pinchGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGesturePinch, GestureAction.DEFAULT_PINCH.value())); GestureAction pinchGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGesturePinch, GestureAction.DEFAULT_PINCH.value()));
GestureAction scrollHorizontalGesture = GestureAction.fromValue(a.getInteger(R.styleable.CameraView_cameraGestureScrollHorizontal, GestureAction.DEFAULT_SCROLL_HORIZONTAL.value())); 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())); 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(); a.recycle();
// Components // Components
@ -186,6 +190,11 @@ public class CameraView extends FrameLayout {
mapGesture(Gesture.SCROLL_HORIZONTAL, scrollHorizontalGesture); mapGesture(Gesture.SCROLL_HORIZONTAL, scrollHorizontalGesture);
mapGesture(Gesture.SCROLL_VERTICAL, scrollVerticalGesture); mapGesture(Gesture.SCROLL_VERTICAL, scrollVerticalGesture);
//Set camera video maxSize
if(cameraVideoMaxSize > 0) {
setVideoMaxSize((long)cameraVideoMaxSize);
}
if (!isInEditMode()) { if (!isInEditMode()) {
mOrientationHelper = new OrientationHelper(context, mCameraCallbacks); mOrientationHelper = new OrientationHelper(context, mCameraCallbacks);
} }
@ -1364,6 +1373,24 @@ public class CameraView extends FrameLayout {
return mPlaySounds; return mPlaySounds;
} }
/**
* Set a max file size (in bytes) for a video recording. There is no file size limit by default
* unless set by the user.
*
* @param videoMaxSizeInBytes The maximum size of videos in bytes
*/
public void setVideoMaxSize(long videoMaxSizeInBytes){
mCameraController.setVideoMaxSize(videoMaxSizeInBytes);
}
/**
* Returns true if the camera is currently recording a video
* @return boolean indicating if the camera is recording a video
*/
public boolean isCapturingVideo(){
return mCameraController.isCapturingVideo();
}
//endregion //endregion
//region Callbacks and dispatching //region Callbacks and dispatching

@ -110,6 +110,8 @@
<attr name="cameraPlaySounds" format="boolean" /> <attr name="cameraPlaySounds" format="boolean" />
<attr name="cameraVideoMaxSize" format="float" />
<!-- deprecated attr name="cameraZoomMode" format="enum"> <!-- deprecated attr name="cameraZoomMode" format="enum">
<enum name="off" value="0" /> <enum name="off" value="0" />
<enum name="pinch" value="1" /> <enum name="pinch" value="1" />

@ -7,24 +7,18 @@ import android.os.Bundle;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.BottomSheetBehavior; import android.support.design.widget.BottomSheetBehavior;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Toast; import android.widget.Toast;
import com.otaliastudios.cameraview.Audio;
import com.otaliastudios.cameraview.CameraListener; import com.otaliastudios.cameraview.CameraListener;
import com.otaliastudios.cameraview.CameraLogger; import com.otaliastudios.cameraview.CameraLogger;
import com.otaliastudios.cameraview.CameraOptions; import com.otaliastudios.cameraview.CameraOptions;
import com.otaliastudios.cameraview.CameraView; import com.otaliastudios.cameraview.CameraView;
import com.otaliastudios.cameraview.Flash;
import com.otaliastudios.cameraview.Grid;
import com.otaliastudios.cameraview.SessionType; import com.otaliastudios.cameraview.SessionType;
import com.otaliastudios.cameraview.Size; import com.otaliastudios.cameraview.Size;
import com.otaliastudios.cameraview.VideoQuality;
import com.otaliastudios.cameraview.WhiteBalance;
import java.io.File; import java.io.File;
@ -53,7 +47,12 @@ public class CameraActivity extends AppCompatActivity implements View.OnClickLis
camera.addCameraListener(new CameraListener() { camera.addCameraListener(new CameraListener() {
public void onCameraOpened(CameraOptions options) { onOpened(); } public void onCameraOpened(CameraOptions options) { onOpened(); }
public void onPictureTaken(byte[] jpeg) { onPicture(jpeg); } public void onPictureTaken(byte[] jpeg) { onPicture(jpeg); }
public void onVideoTaken(File video) { onVideo(video); }
@Override
public void onVideoTaken(File video) {
super.onVideoTaken(video);
onVideo(video);
}
}); });
findViewById(R.id.edit).setOnClickListener(this); findViewById(R.id.edit).setOnClickListener(this);

Loading…
Cancel
Save