diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 0a5b4a1d..39582b37 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -1302,6 +1302,15 @@ public class CameraView extends FrameLayout implements LifecycleObserver { }); } + /** + * Starts recording a fast, low quality video snapshot. Video will be written to the given file, + * so callers should ensure they have appropriate permissions to write to the file. + * + * Throws an exception if API level is below 18, or if the preview being used is not + * {@link Preview#GL_SURFACE}. + * + * @param file a file where the video will be saved + */ public void takeVideoSnapshot(@Nullable File file) { if (getWidth() == 0 || getHeight() == 0) return; if (file == null) { @@ -1332,34 +1341,65 @@ public class CameraView extends FrameLayout implements LifecycleObserver { final int old = getVideoMaxDuration(); addCameraListener(new CameraListener() { @Override - public void onVideoTaken(VideoResult result) { + public void onVideoTaken(@NonNull VideoResult result) { setVideoMaxDuration(old); removeCameraListener(this); } + + @Override + public void onCameraError(@NonNull CameraException exception) { + super.onCameraError(exception); + if (exception.getReason() == CameraException.REASON_VIDEO_FAILED) { + setVideoMaxDuration(old); + removeCameraListener(this); + } + } }); setVideoMaxDuration(durationMillis); takeVideo(file); } + /** + * Starts recording a fast, low quality video snapshot. Video will be written to the given file, + * so callers should ensure they have appropriate permissions to write to the file. + * Recording will be automatically stopped after the given duration, overriding + * temporarily any duration limit set by {@link #setVideoMaxDuration(int)}. + * + * Throws an exception if API level is below 18, or if the preview being used is not + * {@link Preview#GL_SURFACE}. + * + * @param file a file where the video will be saved + * @param durationMillis recording max duration + * + */ public void takeVideoSnapshot(@Nullable File file, int durationMillis) { final int old = getVideoMaxDuration(); addCameraListener(new CameraListener() { @Override - public void onVideoTaken(VideoResult result) { + public void onVideoTaken(@NonNull VideoResult result) { setVideoMaxDuration(old); removeCameraListener(this); } + + @Override + public void onCameraError(@NonNull CameraException exception) { + super.onCameraError(exception); + if (exception.getReason() == CameraException.REASON_VIDEO_FAILED) { + setVideoMaxDuration(old); + removeCameraListener(this); + } + } }); setVideoMaxDuration(durationMillis); takeVideoSnapshot(file); } - // TODO: pauseCapturingVideo and resumeCapturingVideo. There is mediarecorder.pause(), but API 24... + // TODO: pauseVideo and resumeVideo? There is mediarecorder.pause(), but API 24... /** - * Stops capturing video, if there was a video record going on. + * Stops capturing video or video snapshots being recorded, if there was any. * This will fire {@link CameraListener#onVideoTaken(VideoResult)}. */ public void stopVideo() { diff --git a/docs/_posts/2018-12-20-capturing-media.md b/docs/_posts/2018-12-20-capturing-media.md index 34e698e0..38c25f41 100644 --- a/docs/_posts/2018-12-20-capturing-media.md +++ b/docs/_posts/2018-12-20-capturing-media.md @@ -75,8 +75,10 @@ This is allowed at the following conditions: |`isTakingPicture()`|Returns true if the camera is currently capturing a picture.| |`takePicture()`|Takes a high quality picture.| |`takeVideo(File)`|Takes a high quality video.| +|`takeVideo(File, long)`|Takes a high quality video, stopping after the given duration.| |`takePictureSnapshot()`|Takes a picture snapshot.| |`takeVideoSnapshot(File)`|Takes a video snapshot.| +|`takeVideoSnapshot(File, long)`|Takes a video snapshot, stopping after the given duration.| |`getPictureSize()`|Returns the output picture size, accounting for any rotation. Null while in `VIDEO` mode.| |`getVideoSize()`|Returns the output video size, accounting for any rotation. Null while in `PICTURE` mode.| |`getSnapshotSize()`|Returns the size of pictures taken with `takePictureSnapshot()` or videos taken with `takeVideoSnapshot()`. Accounts for rotation and cropping.| \ No newline at end of file