|
|
@ -1,5 +1,6 @@ |
|
|
|
package com.otaliastudios.cameraview.video; |
|
|
|
package com.otaliastudios.cameraview.video; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.otaliastudios.cameraview.CameraLogger; |
|
|
|
import com.otaliastudios.cameraview.VideoResult; |
|
|
|
import com.otaliastudios.cameraview.VideoResult; |
|
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.CallSuper; |
|
|
|
import androidx.annotation.CallSuper; |
|
|
@ -13,6 +14,9 @@ import androidx.annotation.VisibleForTesting; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public abstract class VideoRecorder { |
|
|
|
public abstract class VideoRecorder { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final static String TAG = VideoRecorder.class.getSimpleName(); |
|
|
|
|
|
|
|
private final static CameraLogger LOG = CameraLogger.create(TAG); |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Listens for video recorder events. |
|
|
|
* Listens for video recorder events. |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -37,11 +41,15 @@ public abstract class VideoRecorder { |
|
|
|
void onVideoRecordingEnd(); |
|
|
|
void onVideoRecordingEnd(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final static int STATE_IDLE = 0; |
|
|
|
|
|
|
|
private final static int STATE_RECORDING = 1; |
|
|
|
|
|
|
|
private final static int STATE_STOPPING = 2; |
|
|
|
|
|
|
|
|
|
|
|
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) VideoResult.Stub mResult; |
|
|
|
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) VideoResult.Stub mResult; |
|
|
|
private final VideoResultListener mListener; |
|
|
|
private final VideoResultListener mListener; |
|
|
|
@SuppressWarnings("WeakerAccess") |
|
|
|
@SuppressWarnings("WeakerAccess") |
|
|
|
protected Exception mError; |
|
|
|
protected Exception mError; |
|
|
|
private boolean mIsRecording; |
|
|
|
private int mState; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Creates a new video recorder. |
|
|
|
* Creates a new video recorder. |
|
|
@ -49,6 +57,7 @@ public abstract class VideoRecorder { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
VideoRecorder(@Nullable VideoResultListener listener) { |
|
|
|
VideoRecorder(@Nullable VideoResultListener listener) { |
|
|
|
mListener = listener; |
|
|
|
mListener = listener; |
|
|
|
|
|
|
|
mState = STATE_IDLE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
@ -57,8 +66,13 @@ public abstract class VideoRecorder { |
|
|
|
* @param stub the video stub |
|
|
|
* @param stub the video stub |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public final void start(@NonNull VideoResult.Stub stub) { |
|
|
|
public final void start(@NonNull VideoResult.Stub stub) { |
|
|
|
|
|
|
|
if (mState != STATE_IDLE) { |
|
|
|
|
|
|
|
LOG.e("start:", "called twice, or while stopping! " + |
|
|
|
|
|
|
|
"Ignoring. state:", mState); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
mState = STATE_RECORDING; |
|
|
|
mResult = stub; |
|
|
|
mResult = stub; |
|
|
|
mIsRecording = true; |
|
|
|
|
|
|
|
onStart(); |
|
|
|
onStart(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -67,6 +81,12 @@ public abstract class VideoRecorder { |
|
|
|
* @param isCameraShutdown whether this is a full shutdown, camera is being closed |
|
|
|
* @param isCameraShutdown whether this is a full shutdown, camera is being closed |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public final void stop(boolean isCameraShutdown) { |
|
|
|
public final void stop(boolean isCameraShutdown) { |
|
|
|
|
|
|
|
if (mState == STATE_IDLE) { |
|
|
|
|
|
|
|
LOG.e("stop:", "called twice, or called before start! " + |
|
|
|
|
|
|
|
"Ignoring. isCameraShutdown:", isCameraShutdown); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
mState = STATE_STOPPING; |
|
|
|
onStop(isCameraShutdown); |
|
|
|
onStop(isCameraShutdown); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -75,7 +95,8 @@ public abstract class VideoRecorder { |
|
|
|
* @return true if recording |
|
|
|
* @return true if recording |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public boolean isRecording() { |
|
|
|
public boolean isRecording() { |
|
|
|
return mIsRecording; |
|
|
|
// true if not idle.
|
|
|
|
|
|
|
|
return mState != STATE_IDLE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected abstract void onStart(); |
|
|
|
protected abstract void onStart(); |
|
|
@ -86,9 +107,10 @@ public abstract class VideoRecorder { |
|
|
|
* Subclasses can call this to notify that the result was obtained, |
|
|
|
* Subclasses can call this to notify that the result was obtained, |
|
|
|
* either with some error (null result) or with the actual stub, filled. |
|
|
|
* either with some error (null result) or with the actual stub, filled. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@CallSuper |
|
|
|
protected final void dispatchResult() { |
|
|
|
protected void dispatchResult() { |
|
|
|
if (!isRecording()) return; |
|
|
|
mIsRecording = false; |
|
|
|
mState = STATE_IDLE; |
|
|
|
|
|
|
|
onDispatchResult(); |
|
|
|
if (mListener != null) { |
|
|
|
if (mListener != null) { |
|
|
|
mListener.onVideoResult(mResult, mError); |
|
|
|
mListener.onVideoResult(mResult, mError); |
|
|
|
} |
|
|
|
} |
|
|
@ -96,6 +118,13 @@ public abstract class VideoRecorder { |
|
|
|
mError = null; |
|
|
|
mError = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Subclasses can override this to release resources. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
protected void onDispatchResult() { |
|
|
|
|
|
|
|
// No-op
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Subclasses can call this to notify that the video recording has started, |
|
|
|
* Subclasses can call this to notify that the video recording has started, |
|
|
|
* this will be called when camera is prepared and started. |
|
|
|
* this will be called when camera is prepared and started. |
|
|
|