From e1b04088c664b5548ba4fd1ecfae4273982883f5 Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Mon, 21 Aug 2023 14:24:06 +0200 Subject: [PATCH] fix: Clean up codebase --- .../java/com/mrousavy/camera/CameraSession.kt | 5 +- .../mrousavy/camera/CameraView+RecordVideo.kt | 7 ++- .../mrousavy/camera/CameraView+TakePhoto.kt | 3 -- .../com/mrousavy/camera/CameraViewManager.kt | 3 +- .../main/java/com/mrousavy/camera/Errors.kt | 49 +------------------ .../CamcorderProfile+getQualityForSize.kt | 27 ---------- .../extensions/Context+displayRotation.kt | 36 -------------- .../MediaFormat.setDynamicRangeProfile.kt | 38 -------------- .../camera/extensions/Size+Extensions.kt | 4 -- .../extensions/WritableArray+Nullables.kt | 24 --------- .../extensions/WritableMap+Nullables.kt | 7 --- .../mrousavy/camera/parsers/PixelFormat.kt | 7 --- .../com/mrousavy/camera/utils/ExifUtils.kt | 20 -------- .../mrousavy/camera/utils/RecordingSession.kt | 10 +++- .../camera/utils/outputs/CameraOutputs.kt | 5 +- example/src/views/CaptureButton.tsx | 1 - src/PhotoFile.ts | 15 ++---- 17 files changed, 26 insertions(+), 235 deletions(-) delete mode 100644 android/src/main/java/com/mrousavy/camera/extensions/CamcorderProfile+getQualityForSize.kt delete mode 100644 android/src/main/java/com/mrousavy/camera/extensions/Context+displayRotation.kt delete mode 100644 android/src/main/java/com/mrousavy/camera/extensions/MediaFormat.setDynamicRangeProfile.kt delete mode 100644 android/src/main/java/com/mrousavy/camera/extensions/WritableArray+Nullables.kt delete mode 100644 android/src/main/java/com/mrousavy/camera/utils/ExifUtils.kt diff --git a/android/src/main/java/com/mrousavy/camera/CameraSession.kt b/android/src/main/java/com/mrousavy/camera/CameraSession.kt index f476c0b..443a2c4 100644 --- a/android/src/main/java/com/mrousavy/camera/CameraSession.kt +++ b/android/src/main/java/com/mrousavy/camera/CameraSession.kt @@ -221,13 +221,14 @@ class CameraSession(private val context: Context, suspend fun startRecording(enableAudio: Boolean, codec: VideoCodec, fileType: VideoFileType, - callback: (video: RecordingSession.Video) -> Unit) { + callback: (video: RecordingSession.Video) -> Unit, + onError: (error: RecorderError) -> Unit) { mutex.withLock { if (recording != null) throw RecordingInProgressError() val outputs = outputs ?: throw CameraNotReadyError() val videoOutput = outputs.videoOutput ?: throw VideoNotEnabledError() - val recording = RecordingSession(context, enableAudio, videoOutput.size, fps, codec, orientation, fileType, callback) + val recording = RecordingSession(context, enableAudio, videoOutput.size, fps, codec, orientation, fileType, callback, onError) recording.start() this.recording = recording } diff --git a/android/src/main/java/com/mrousavy/camera/CameraView+RecordVideo.kt b/android/src/main/java/com/mrousavy/camera/CameraView+RecordVideo.kt index 0a3d173..8e59e78 100644 --- a/android/src/main/java/com/mrousavy/camera/CameraView+RecordVideo.kt +++ b/android/src/main/java/com/mrousavy/camera/CameraView+RecordVideo.kt @@ -9,6 +9,7 @@ import com.mrousavy.camera.parsers.Torch import com.mrousavy.camera.parsers.VideoCodec import com.mrousavy.camera.parsers.VideoFileType import com.mrousavy.camera.utils.RecordingSession +import com.mrousavy.camera.utils.makeErrorMap import java.util.* suspend fun CameraView.startRecording(options: ReadableMap, onRecordCallback: Callback) { @@ -39,7 +40,11 @@ suspend fun CameraView.startRecording(options: ReadableMap, onRecordCallback: Ca map.putDouble("duration", video.durationMs.toDouble() / 1000.0) onRecordCallback(map, null) } - cameraSession.startRecording(audio == true, codec, fileType, callback) + val onError = { error: RecorderError -> + val errorMap = makeErrorMap(error.code, error.message) + onRecordCallback(null, errorMap) + } + cameraSession.startRecording(audio == true, codec, fileType, callback, onError) } @SuppressLint("RestrictedApi") diff --git a/android/src/main/java/com/mrousavy/camera/CameraView+TakePhoto.kt b/android/src/main/java/com/mrousavy/camera/CameraView+TakePhoto.kt index 25ec701..bf91a4f 100644 --- a/android/src/main/java/com/mrousavy/camera/CameraView+TakePhoto.kt +++ b/android/src/main/java/com/mrousavy/camera/CameraView+TakePhoto.kt @@ -30,7 +30,6 @@ suspend fun CameraView.takePhoto(optionsMap: ReadableMap): WritableMap { val flash = options["flash"] as? String ?: "off" val enableAutoRedEyeReduction = options["enableAutoRedEyeReduction"] == true val enableAutoStabilization = options["enableAutoStabilization"] == true - val skipMetadata = options["skipMetadata"] == true val flashMode = Flash.fromUnionValue(flash) val qualityPrioritizationMode = QualityPrioritization.fromUnionValue(qualityPrioritization) @@ -58,8 +57,6 @@ suspend fun CameraView.takePhoto(optionsMap: ReadableMap): WritableMap { map.putBoolean("isRawPhoto", photo.format == ImageFormat.RAW_SENSOR) map.putBoolean("isMirrored", photo.isMirrored) - // TODO: Add metadata prop to resulting photo - return map } } diff --git a/android/src/main/java/com/mrousavy/camera/CameraViewManager.kt b/android/src/main/java/com/mrousavy/camera/CameraViewManager.kt index d99408b..3d7b8c0 100644 --- a/android/src/main/java/com/mrousavy/camera/CameraViewManager.kt +++ b/android/src/main/java/com/mrousavy/camera/CameraViewManager.kt @@ -1,6 +1,5 @@ package com.mrousavy.camera -import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReadableMap import com.facebook.react.common.MapBuilder import com.facebook.react.uimanager.ThemedReactContext @@ -13,7 +12,7 @@ import com.mrousavy.camera.parsers.Torch import com.mrousavy.camera.parsers.VideoStabilizationMode @Suppress("unused") -class CameraViewManager(reactContext: ReactApplicationContext) : ViewGroupManager() { +class CameraViewManager() : ViewGroupManager() { public override fun createViewInstance(context: ThemedReactContext): CameraView { return CameraView(context) diff --git a/android/src/main/java/com/mrousavy/camera/Errors.kt b/android/src/main/java/com/mrousavy/camera/Errors.kt index d64c3a7..b8194a7 100644 --- a/android/src/main/java/com/mrousavy/camera/Errors.kt +++ b/android/src/main/java/com/mrousavy/camera/Errors.kt @@ -40,17 +40,11 @@ class NoCameraDeviceError : CameraError("device", "no-device", "No device was se class NoFlashAvailableError : CameraError("device", "flash-unavailable", "The Camera Device does not have a flash unit! Make sure you select a device where `hasFlash`/`hasTorch` is true!") class PixelFormatNotSupportedError(format: String) : CameraError("device", "pixel-format-not-supported", "The pixelFormat $format is not supported on the given Camera Device!") -class FpsNotContainedInFormatError(fps: Int) : CameraError("format", "invalid-fps", "The given format cannot run at $fps FPS! Make sure your FPS is lower than `format.maxFps` but higher than `format.minFps`.") class HdrNotContainedInFormatError : CameraError( "format", "invalid-hdr", "The currently selected format does not support HDR capture! " + "Make sure you select a format which includes `supportsPhotoHDR`!" ) -class LowLightBoostNotContainedInFormatError : CameraError( - "format", "invalid-low-light-boost", - "The currently selected format does not support low-light boost (night mode)! " + - "Make sure you select a format which includes `supportsLowLightBoost`." -) class CameraNotReadyError : CameraError("session", "camera-not-ready", "The Camera is not ready yet! Wait for the onInitialized() callback!") class CameraCannotBeOpenedError(cameraId: String, error: CameraDeviceError) : CameraError("session", "camera-cannot-be-opened", "The given Camera device (id: $cameraId) could not be opened! Error: $error") @@ -62,48 +56,7 @@ class PhotoNotEnabledError : CameraError("capture", "photo-not-enabled", "Photo class CaptureAbortedError(wasImageCaptured: Boolean) : CameraError("capture", "aborted", "The image capture was aborted! Was Image captured: $wasImageCaptured") class UnknownCaptureError(wasImageCaptured: Boolean) : CameraError("capture", "unknown", "An unknown error occurred while trying to capture an Image! Was Image captured: $wasImageCaptured") -class VideoEncoderError(cause: Throwable?) : CameraError("capture", "encoder-error", "The recording failed while encoding.\n" + - "This error may be generated when the video or audio codec encounters an error during encoding. " + - "When this happens and the output file is generated, the output file is not properly constructed. " + - "The application will need to clean up the output file, such as deleting the file.", - cause) - -class InvalidVideoOutputOptionsError(cause: Throwable?) : CameraError("capture", "invalid-video-options", - "The recording failed due to invalid output options.\n" + - "This error is generated when invalid output options have been used while preparing a recording", - cause) - -class RecorderError(cause: Throwable?) : CameraError("capture", "recorder-error", - "The recording failed because the Recorder is in an unrecoverable error state.\n" + - "When this happens and the output file is generated, the output file is not properly constructed. " + - "The application will need to clean up the output file, such as deleting the file. " + - "Such an error will usually require creating a new Recorder object to start a new recording.", - cause) - -class NoValidDataError(cause: Throwable?) : CameraError("capture", "no-valid-data", - "The recording failed because no valid data was produced to be recorded.\n" + - "This error is generated when the essential data for a recording to be played correctly is missing, for example, " + - "a recording must contain at least one key frame. The application will need to clean up the output file, such as deleting the file.", - cause) - -class InactiveSourceError(cause: Throwable?) : CameraError("capture", "inactive-source", - "The recording failed because the source becomes inactive and stops sending frames.\n" + - "One case is that if camera is closed due to lifecycle stopped, the active recording will be finalized with this error, " + - "and the output will be generated, containing the frames produced before camera closing. " + - "Attempting to start a new recording will be finalized immediately if the source remains inactive and no output will be generated.", - cause) - -class InsufficientStorageError(cause: Throwable?) : CameraError("capture", "insufficient-storage", - "The recording failed due to insufficient storage space.\n" + - "There are two possible cases that will cause this error.\n" + - "1. The storage is already full before the recording starts, so no output file will be generated.\n" + - "2. The storage becomes full during recording, so the output file will be generated.", - cause) - -class FileSizeLimitReachedError(cause: Throwable?) : CameraError("capture", "file-size-limit-reached", - "The recording failed due to file size limitation.\n" + - "The file size limitation will refer to OutputOptions.getFileSizeLimit(). The output file will still be generated with this error.", - cause) +class RecorderError(name: String, extra: Int) : CameraError("capture", "recorder-error", "An error occured while recording a video! $name $extra") class NoRecordingInProgressError : CameraError("capture", "no-recording-in-progress", "There was no active video recording in progress! Did you call stopRecording() twice?") class RecordingInProgressError : CameraError("capture", "recording-in-progress", "There is already an active video recording in progress! Did you call startRecording() twice?") diff --git a/android/src/main/java/com/mrousavy/camera/extensions/CamcorderProfile+getQualityForSize.kt b/android/src/main/java/com/mrousavy/camera/extensions/CamcorderProfile+getQualityForSize.kt deleted file mode 100644 index 3390870..0000000 --- a/android/src/main/java/com/mrousavy/camera/extensions/CamcorderProfile+getQualityForSize.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.mrousavy.camera.extensions - -import android.media.CamcorderProfile -import android.util.Size - -private val qualitiesMap = mapOf( - Size(176 - 1, 144 - 1) to CamcorderProfile.QUALITY_LOW, - Size(176, 144) to CamcorderProfile.QUALITY_QCIF, - Size(320, 240) to CamcorderProfile.QUALITY_QVGA, - Size(352, 288) to CamcorderProfile.QUALITY_CIF, - Size(640, 480) to CamcorderProfile.QUALITY_VGA, - Size(720, 480) to CamcorderProfile.QUALITY_480P, - Size(1280, 720) to CamcorderProfile.QUALITY_720P, - Size(1920, 1080) to CamcorderProfile.QUALITY_1080P, - Size(2048, 1080) to CamcorderProfile.QUALITY_2K, - Size(2560, 1440) to CamcorderProfile.QUALITY_QHD, - Size(3840, 2160) to CamcorderProfile.QUALITY_2160P, - Size(4096, 2160) to CamcorderProfile.QUALITY_4KDCI, - Size(7680, 4320) to CamcorderProfile.QUALITY_8KUHD, - Size(7680 + 1, 4320 + 1) to CamcorderProfile.QUALITY_HIGH, -) - -fun getCamcorderQualityForSize(size: Size): Int { - // Find closest match - val closestMatch = qualitiesMap.keys.closestTo(size) - return qualitiesMap[closestMatch] ?: CamcorderProfile.QUALITY_HIGH -} diff --git a/android/src/main/java/com/mrousavy/camera/extensions/Context+displayRotation.kt b/android/src/main/java/com/mrousavy/camera/extensions/Context+displayRotation.kt deleted file mode 100644 index bb61cce..0000000 --- a/android/src/main/java/com/mrousavy/camera/extensions/Context+displayRotation.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.mrousavy.camera.extensions - -import android.content.Context -import android.os.Build -import android.view.Surface -import android.view.WindowManager -import com.facebook.react.bridge.ReactContext - -val Context.displayRotation: Int - get() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - // Context.display - this.display?.let { display -> - return display.rotation - } - - // ReactContext.currentActivity.display - if (this is ReactContext) { - currentActivity?.display?.let { display -> - return display.rotation - } - } - } - - // WindowManager.defaultDisplay - val windowManager = getSystemService(Context.WINDOW_SERVICE) as? WindowManager - if (windowManager != null) { - @Suppress("DEPRECATION") // deprecated since SDK 30 - windowManager.defaultDisplay?.let { display -> - return display.rotation - } - } - - // 0 - return Surface.ROTATION_0 - } diff --git a/android/src/main/java/com/mrousavy/camera/extensions/MediaFormat.setDynamicRangeProfile.kt b/android/src/main/java/com/mrousavy/camera/extensions/MediaFormat.setDynamicRangeProfile.kt deleted file mode 100644 index fa2b7b3..0000000 --- a/android/src/main/java/com/mrousavy/camera/extensions/MediaFormat.setDynamicRangeProfile.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.mrousavy.camera.extensions - -import android.hardware.camera2.params.DynamicRangeProfiles -import android.media.MediaCodecInfo -import android.media.MediaFormat -import android.os.Build -import android.util.Log -import androidx.annotation.RequiresApi - -@RequiresApi(Build.VERSION_CODES.N) -private fun getTransferFunction(codecProfile: Int) = when (codecProfile) { - MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10 -> MediaFormat.COLOR_TRANSFER_HLG - MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10 -> MediaFormat.COLOR_TRANSFER_ST2084 - MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus -> MediaFormat.COLOR_TRANSFER_ST2084 - else -> MediaFormat.COLOR_TRANSFER_SDR_VIDEO -} - -fun MediaFormat.setDynamicRangeProfile(dynamicRangeProfile: Long) { - val profile = when (dynamicRangeProfile) { - DynamicRangeProfiles.HLG10 -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10 - DynamicRangeProfiles.HDR10 -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10 - DynamicRangeProfiles.HDR10_PLUS -> MediaCodecInfo.CodecProfileLevel.HEVCProfileMain10HDR10Plus - else -> null - } - - if (profile != null) { - Log.i("MediaFormat", "Using HDR Profile $profile") - this.setInteger(MediaFormat.KEY_PROFILE, profile) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - this.setInteger(MediaFormat.KEY_COLOR_STANDARD, MediaFormat.COLOR_STANDARD_BT2020) - this.setInteger(MediaFormat.KEY_COLOR_RANGE, MediaFormat.COLOR_RANGE_FULL) - this.setInteger(MediaFormat.KEY_COLOR_TRANSFER, getTransferFunction(profile)) - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - this.setFeatureEnabled(MediaCodecInfo.CodecCapabilities.FEATURE_HdrEditing, true) - } - } -} diff --git a/android/src/main/java/com/mrousavy/camera/extensions/Size+Extensions.kt b/android/src/main/java/com/mrousavy/camera/extensions/Size+Extensions.kt index 5de0f31..3c2cabf 100644 --- a/android/src/main/java/com/mrousavy/camera/extensions/Size+Extensions.kt +++ b/android/src/main/java/com/mrousavy/camera/extensions/Size+Extensions.kt @@ -15,10 +15,6 @@ fun List.closestToOrMax(size: Size?): Size { } } -fun Collection.closestTo(size: Size): Size { - return this.minBy { abs(it.width - size.width) + abs(it.height - size.height) } -} - /** * Rotate by a given Surface Rotation */ diff --git a/android/src/main/java/com/mrousavy/camera/extensions/WritableArray+Nullables.kt b/android/src/main/java/com/mrousavy/camera/extensions/WritableArray+Nullables.kt deleted file mode 100644 index 780dffb..0000000 --- a/android/src/main/java/com/mrousavy/camera/extensions/WritableArray+Nullables.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.mrousavy.camera.extensions - -import com.facebook.react.bridge.WritableArray - -fun WritableArray.pushInt(value: Int?) { - if (value == null) - this.pushNull() - else - this.pushInt(value) -} - -fun WritableArray.pushDouble(value: Double?) { - if (value == null) - this.pushNull() - else - this.pushDouble(value) -} - -fun WritableArray.pushBoolean(value: Boolean?) { - if (value == null) - this.pushNull() - else - this.pushBoolean(value) -} diff --git a/android/src/main/java/com/mrousavy/camera/extensions/WritableMap+Nullables.kt b/android/src/main/java/com/mrousavy/camera/extensions/WritableMap+Nullables.kt index 91f3d69..13e5d00 100644 --- a/android/src/main/java/com/mrousavy/camera/extensions/WritableMap+Nullables.kt +++ b/android/src/main/java/com/mrousavy/camera/extensions/WritableMap+Nullables.kt @@ -15,10 +15,3 @@ fun WritableMap.putDouble(key: String, value: Double?) { else this.putDouble(key, value) } - -fun WritableMap.putBoolean(key: String, value: Boolean?) { - if (value == null) - this.putNull(key) - else - this.putBoolean(key, value) -} diff --git a/android/src/main/java/com/mrousavy/camera/parsers/PixelFormat.kt b/android/src/main/java/com/mrousavy/camera/parsers/PixelFormat.kt index b5e7996..06707d6 100644 --- a/android/src/main/java/com/mrousavy/camera/parsers/PixelFormat.kt +++ b/android/src/main/java/com/mrousavy/camera/parsers/PixelFormat.kt @@ -11,13 +11,6 @@ enum class PixelFormat(override val unionValue: String): JSUnionValue { NATIVE("native"), UNKNOWN("unknown"); - private fun bestMatch(formats: IntArray, targetFormats: Array): Int? { - targetFormats.forEach { format -> - if (formats.contains(format)) return format - } - return null - } - fun toImageFormat(): Int { val result = when (this) { YUV -> ImageFormat.YUV_420_888 diff --git a/android/src/main/java/com/mrousavy/camera/utils/ExifUtils.kt b/android/src/main/java/com/mrousavy/camera/utils/ExifUtils.kt deleted file mode 100644 index 04984d4..0000000 --- a/android/src/main/java/com/mrousavy/camera/utils/ExifUtils.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.mrousavy.camera.utils - -import androidx.exifinterface.media.ExifInterface - -class ExifUtils { - companion object { - fun computeExifOrientation(rotationDegrees: Int, mirrored: Boolean) = when { - rotationDegrees == 0 && !mirrored -> ExifInterface.ORIENTATION_NORMAL - rotationDegrees == 0 && mirrored -> ExifInterface.ORIENTATION_FLIP_HORIZONTAL - rotationDegrees == 180 && !mirrored -> ExifInterface.ORIENTATION_ROTATE_180 - rotationDegrees == 180 && mirrored -> ExifInterface.ORIENTATION_FLIP_VERTICAL - rotationDegrees == 270 && mirrored -> ExifInterface.ORIENTATION_TRANSVERSE - rotationDegrees == 90 && !mirrored -> ExifInterface.ORIENTATION_ROTATE_90 - rotationDegrees == 90 && mirrored -> ExifInterface.ORIENTATION_TRANSPOSE - rotationDegrees == 270 && mirrored -> ExifInterface.ORIENTATION_ROTATE_270 - rotationDegrees == 270 && !mirrored -> ExifInterface.ORIENTATION_TRANSVERSE - else -> ExifInterface.ORIENTATION_UNDEFINED - } - } -} diff --git a/android/src/main/java/com/mrousavy/camera/utils/RecordingSession.kt b/android/src/main/java/com/mrousavy/camera/utils/RecordingSession.kt index 4a31448..ccbb170 100644 --- a/android/src/main/java/com/mrousavy/camera/utils/RecordingSession.kt +++ b/android/src/main/java/com/mrousavy/camera/utils/RecordingSession.kt @@ -9,6 +9,7 @@ import android.os.Build import android.util.Log import android.util.Size import android.view.Surface +import com.mrousavy.camera.RecorderError import com.mrousavy.camera.parsers.Orientation import com.mrousavy.camera.parsers.VideoCodec import com.mrousavy.camera.parsers.VideoFileType @@ -22,7 +23,8 @@ class RecordingSession(context: Context, private val codec: VideoCodec = VideoCodec.H264, private val orientation: Orientation, private val fileType: VideoFileType = VideoFileType.MP4, - private val callback: (video: Video) -> Unit) { + private val callback: (video: Video) -> Unit, + private val onError: (error: RecorderError) -> Unit) { companion object { private const val TAG = "RecordingSession" // bits per second @@ -77,6 +79,12 @@ class RecordingSession(context: Context, recorder.setOnErrorListener { _, what, extra -> Log.e(TAG, "MediaRecorder Error: $what ($extra)") stop() + val name = when (what) { + MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN -> "unknown" + MediaRecorder.MEDIA_ERROR_SERVER_DIED -> "server-died" + else -> "unknown" + } + onError(RecorderError(name, extra)) } recorder.setOnInfoListener { _, what, extra -> Log.i(TAG, "MediaRecorder Info: $what ($extra)") diff --git a/android/src/main/java/com/mrousavy/camera/utils/outputs/CameraOutputs.kt b/android/src/main/java/com/mrousavy/camera/utils/outputs/CameraOutputs.kt index 9983dab..0513ec4 100644 --- a/android/src/main/java/com/mrousavy/camera/utils/outputs/CameraOutputs.kt +++ b/android/src/main/java/com/mrousavy/camera/utils/outputs/CameraOutputs.kt @@ -2,10 +2,10 @@ package com.mrousavy.camera.utils.outputs import android.graphics.ImageFormat import android.hardware.HardwareBuffer -import android.hardware.camera2.CameraCharacteristics import android.hardware.camera2.CameraManager import android.media.Image import android.media.ImageReader +import android.os.Build import android.util.Log import android.util.Size import android.view.Surface @@ -92,7 +92,6 @@ class CameraOutputs(val cameraId: String, init { val characteristics = cameraManager.getCameraCharacteristics(cameraId) - val config = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!! Log.i(TAG, "Preparing Outputs for Camera $cameraId...") @@ -118,6 +117,8 @@ class CameraOutputs(val cameraId: String, // Video output: High resolution repeating images (startRecording() or useFrameProcessor()) if (video != null) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) throw Error("Video Recordings and/or Frame Processors are only available on API 29 and above!") + val size = characteristics.getVideoSizes(cameraId, video.format).closestToOrMax(video.targetSize) val flags = HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE or HardwareBuffer.USAGE_VIDEO_ENCODE diff --git a/example/src/views/CaptureButton.tsx b/example/src/views/CaptureButton.tsx index 2348487..bd03de4 100644 --- a/example/src/views/CaptureButton.tsx +++ b/example/src/views/CaptureButton.tsx @@ -64,7 +64,6 @@ const _CaptureButton: React.FC = ({ qualityPrioritization: 'speed', flash: flash, quality: 90, - skipMetadata: true, }), [flash], ); diff --git a/src/PhotoFile.ts b/src/PhotoFile.ts index dace1dc..04769b2 100644 --- a/src/PhotoFile.ts +++ b/src/PhotoFile.ts @@ -38,16 +38,6 @@ export interface TakePhotoOptions { * @default false */ enableAutoDistortionCorrection?: boolean; - /** - * When set to `true`, metadata reading and mapping will be skipped. ({@linkcode PhotoFile.metadata} will be null) - * - * This might result in a faster capture, as metadata reading and mapping requires File IO. - * - * @default false - * - * @platform Android - */ - skipMetadata?: boolean; } /** @@ -80,10 +70,11 @@ export interface PhotoFile extends TemporaryFile { isMirrored: boolean; thumbnail?: Record; /** - * Metadata information describing the captured image. + * Metadata information describing the captured image. (iOS only) * * @see [AVCapturePhoto.metadata](https://developer.apple.com/documentation/avfoundation/avcapturephoto/2873982-metadata) - * @see [AndroidX ExifInterface](https://developer.android.com/reference/androidx/exifinterface/media/ExifInterface) + * + * @platform iOS */ metadata?: { /**