parent
1dabf4db01
commit
c353ae808e
@ -0,0 +1,52 @@ |
|||||||
|
package com.otaliastudios.cameraview.video; |
||||||
|
|
||||||
|
import android.hardware.Camera; |
||||||
|
import android.media.MediaRecorder; |
||||||
|
|
||||||
|
import com.otaliastudios.cameraview.CameraLogger; |
||||||
|
import com.otaliastudios.cameraview.VideoResult; |
||||||
|
import com.otaliastudios.cameraview.engine.Camera1Engine; |
||||||
|
import com.otaliastudios.cameraview.internal.utils.CamcorderProfiles; |
||||||
|
import com.otaliastudios.cameraview.size.Size; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
|
||||||
|
/** |
||||||
|
* A {@link VideoRecorder} that uses {@link MediaRecorder} APIs |
||||||
|
* for the Camera1 engine. |
||||||
|
*/ |
||||||
|
public class Full1VideoRecorder extends FullVideoRecorder { |
||||||
|
|
||||||
|
private static final String TAG = Full1VideoRecorder.class.getSimpleName(); |
||||||
|
private static final CameraLogger LOG = CameraLogger.create(TAG); |
||||||
|
|
||||||
|
private final Camera1Engine mEngine; |
||||||
|
private final Camera mCamera; |
||||||
|
private final int mCameraId; |
||||||
|
|
||||||
|
public Full1VideoRecorder(@NonNull Camera1Engine engine, |
||||||
|
@NonNull Camera camera, int cameraId) { |
||||||
|
super(engine); |
||||||
|
mCamera = camera; |
||||||
|
mEngine = engine; |
||||||
|
mCameraId = cameraId; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected boolean onPrepareMediaRecorder(@NonNull VideoResult.Stub stub, @NonNull MediaRecorder mediaRecorder) { |
||||||
|
mediaRecorder.setCamera(mCamera); |
||||||
|
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); |
||||||
|
|
||||||
|
// Get a profile of quality compatible with the chosen size.
|
||||||
|
Size size = stub.rotation % 180 != 0 ? stub.size.flip() : stub.size; |
||||||
|
mProfile = CamcorderProfiles.get(mCameraId, size); |
||||||
|
return super.onPrepareMediaRecorder(stub, mediaRecorder); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void onStop() { |
||||||
|
// Restore frame processing.
|
||||||
|
mCamera.setPreviewCallbackWithBuffer(mEngine); |
||||||
|
super.onStop(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,96 @@ |
|||||||
|
package com.otaliastudios.cameraview.video; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.graphics.SurfaceTexture; |
||||||
|
import android.hardware.camera2.CameraAccessException; |
||||||
|
import android.hardware.camera2.CameraCaptureSession; |
||||||
|
import android.hardware.camera2.CameraDevice; |
||||||
|
import android.hardware.camera2.CaptureFailure; |
||||||
|
import android.hardware.camera2.CaptureRequest; |
||||||
|
import android.media.Image; |
||||||
|
import android.media.MediaActionSound; |
||||||
|
import android.media.MediaRecorder; |
||||||
|
import android.os.Build; |
||||||
|
import android.view.Surface; |
||||||
|
|
||||||
|
import com.otaliastudios.cameraview.CameraLogger; |
||||||
|
import com.otaliastudios.cameraview.VideoResult; |
||||||
|
import com.otaliastudios.cameraview.engine.Camera2Engine; |
||||||
|
import com.otaliastudios.cameraview.internal.utils.CamcorderProfiles; |
||||||
|
import com.otaliastudios.cameraview.size.Size; |
||||||
|
|
||||||
|
import androidx.annotation.NonNull; |
||||||
|
import androidx.annotation.Nullable; |
||||||
|
import androidx.annotation.RequiresApi; |
||||||
|
|
||||||
|
/** |
||||||
|
* A {@link VideoRecorder} that uses {@link MediaRecorder} APIs |
||||||
|
* for the Camera2 engine. |
||||||
|
*/ |
||||||
|
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) |
||||||
|
public class Full2VideoRecorder extends FullVideoRecorder { |
||||||
|
|
||||||
|
private static final String TAG = Full2VideoRecorder.class.getSimpleName(); |
||||||
|
private static final CameraLogger LOG = CameraLogger.create(TAG); |
||||||
|
|
||||||
|
// This actually didn't work as I expected, we're never using this. Should remove.
|
||||||
|
@SuppressWarnings("PointlessBooleanExpression") // TODO
|
||||||
|
public static final boolean SUPPORTS_PERSISTENT_SURFACE = false && Build.VERSION.SDK_INT >= 23; |
||||||
|
|
||||||
|
private final String mCameraId; |
||||||
|
private Surface mInputSurface; |
||||||
|
private final boolean mUseInputSurface; |
||||||
|
|
||||||
|
public Full2VideoRecorder(@NonNull Camera2Engine engine, |
||||||
|
@NonNull String cameraId, |
||||||
|
@Nullable Surface surface) { |
||||||
|
super(engine); |
||||||
|
mCameraId = cameraId; |
||||||
|
mUseInputSurface = surface != null && SUPPORTS_PERSISTENT_SURFACE; |
||||||
|
mInputSurface = mUseInputSurface ? surface : null; |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint("NewApi") |
||||||
|
@Override |
||||||
|
protected boolean onPrepareMediaRecorder(@NonNull VideoResult.Stub stub, @NonNull MediaRecorder mediaRecorder) { |
||||||
|
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); |
||||||
|
Size size = stub.rotation % 180 != 0 ? stub.size.flip() : stub.size; |
||||||
|
mProfile = CamcorderProfiles.get(mCameraId, size); |
||||||
|
if (mUseInputSurface) { |
||||||
|
//noinspection ConstantConditions
|
||||||
|
mediaRecorder.setInputSurface(mInputSurface); |
||||||
|
} |
||||||
|
return super.onPrepareMediaRecorder(stub, mediaRecorder); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* This method should be called just once. |
||||||
|
* @return a surface |
||||||
|
* @throws PrepareException if prepare went wrong |
||||||
|
*/ |
||||||
|
@NonNull |
||||||
|
public Surface createInputSurface(@NonNull VideoResult.Stub stub) throws PrepareException { |
||||||
|
if (mUseInputSurface) { |
||||||
|
throw new IllegalStateException("We are using the input surface (API23+), can't createInputSurface here."); |
||||||
|
} |
||||||
|
if (!prepareMediaRecorder(stub)) { |
||||||
|
throw new PrepareException(mError); |
||||||
|
} |
||||||
|
mInputSurface = mMediaRecorder.getSurface(); |
||||||
|
return mInputSurface; |
||||||
|
} |
||||||
|
|
||||||
|
@Nullable |
||||||
|
public Surface getInputSurface() { |
||||||
|
return mInputSurface; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess") |
||||||
|
public class PrepareException extends Exception { |
||||||
|
private PrepareException(Throwable cause) { |
||||||
|
super(cause); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue