diff --git a/package/example/ios/Podfile.lock b/package/example/ios/Podfile.lock index a1f8b39391..1443582e4a 100644 --- a/package/example/ios/Podfile.lock +++ b/package/example/ios/Podfile.lock @@ -344,7 +344,7 @@ PODS: - react-native-video/Video (= 5.2.1) - react-native-video/Video (5.2.1): - React-Core - - react-native-worklets-core (0.3.0): + - react-native-worklets-core (0.4.0): - React - React-callinvoker - React-Core @@ -484,7 +484,7 @@ PODS: - libwebp (~> 1.0) - SDWebImage/Core (~> 5.10) - SocketRocket (0.6.1) - - VisionCamera (4.0.0-beta.6): + - VisionCamera (4.0.0-beta.7): - React - React-callinvoker - React-Core @@ -697,7 +697,7 @@ SPEC CHECKSUMS: react-native-mmkv: e97c0c79403fb94577e5d902ab1ebd42b0715b43 react-native-safe-area-context: 0ee144a6170530ccc37a0fd9388e28d06f516a89 react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253 - react-native-worklets-core: a894d572639fcf37c6d284cc799882d25d00c93d + react-native-worklets-core: 2efe80a3ee87fe5e6fefa814e0e20c2708d3ad25 React-NativeModulesApple: b6868ee904013a7923128892ee4a032498a1024a React-perflogger: 31ea61077185eb1428baf60c0db6e2886f141a5a React-RCTActionSheet: 392090a3abc8992eb269ef0eaa561750588fc39d @@ -724,7 +724,7 @@ SPEC CHECKSUMS: SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 - VisionCamera: 7a9e59cc5e65d458d9809a9ac23700265df0f14e + VisionCamera: e0f80a131dbfa1361fdfc0231cb02e3312903acf Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5 PODFILE CHECKSUM: 27f53791141a3303d814e09b55770336416ff4eb diff --git a/package/example/package.json b/package/example/package.json index 58f98a1b53..516ff7fa42 100644 --- a/package/example/package.json +++ b/package/example/package.json @@ -29,7 +29,7 @@ "react-native-static-safe-area-insets": "^2.2.0", "react-native-vector-icons": "^10.0.0", "react-native-video": "^5.2.1", - "react-native-worklets-core": "0.3.0" + "react-native-worklets-core": "0.4.0" }, "devDependencies": { "@babel/core": "^7.22.10", diff --git a/package/example/yarn.lock b/package/example/yarn.lock index 81e887cfaa..86fea6f444 100644 --- a/package/example/yarn.lock +++ b/package/example/yarn.lock @@ -5178,10 +5178,10 @@ react-native-video@^5.2.1: prop-types "^15.7.2" shaka-player "^2.5.9" -react-native-worklets-core@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-0.3.0.tgz#4d6c4c4999d3bf2f8c67fa46fdd70d8b5bc7ba0e" - integrity sha512-bOoo6xbl+f+mz0Q65bLkUP3FxgYt7f/Bzi0c5Yj8Ix4vQCKMtgHwafrqCNRhW32N7TpTv3+zOoyQMJwQVr/frQ== +react-native-worklets-core@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-0.4.0.tgz#708f204d89327d88e155cccb5fc23421ca764b6f" + integrity sha512-0rYCwxnG6L85mih+3xe1r2RhhwKqjgVN9jikVh0iMPKDf9L4OZMJnl6Kh4zjXiW9rkyI5lBghfM4XIcLMfeU6w== dependencies: string-hash-64 "^1.0.3" diff --git a/package/ios/CameraView.swift b/package/ios/CameraView.swift index 44c662e42d..16254df1a2 100644 --- a/package/ios/CameraView.swift +++ b/package/ios/CameraView.swift @@ -25,7 +25,6 @@ public final class CameraView: UIView, CameraSessionDelegate { // props that require reconfiguring @objc var cameraId: NSString? @objc var enableDepthData = false - @objc var enableHighQualityPhotos = false @objc var enablePortraitEffectsMatteDelivery = false @objc var enableBufferCompression = false // use cases @@ -179,10 +178,9 @@ public final class CameraView: UIView, CameraSessionDelegate { // Photo if photo { - config.photo = .enabled(config: CameraConfiguration.Photo(enableHighQualityPhotos: enableHighQualityPhotos, + config.photo = .enabled(config: CameraConfiguration.Photo(qualityBalance: getPhotoQualityBalance(), enableDepthData: enableDepthData, - enablePortraitEffectsMatte: enablePortraitEffectsMatteDelivery, - qualityBalance: getPhotoQualityBalance())) + enablePortraitEffectsMatte: enablePortraitEffectsMatteDelivery)) } else { config.photo = .disabled } diff --git a/package/ios/CameraViewManager.m b/package/ios/CameraViewManager.m index ca4b34d370..00e3f03eab 100644 --- a/package/ios/CameraViewManager.m +++ b/package/ios/CameraViewManager.m @@ -25,7 +25,6 @@ @interface RCT_EXTERN_REMAP_MODULE (CameraView, CameraViewManager, RCTViewManage RCT_EXPORT_VIEW_PROPERTY(isActive, BOOL); RCT_EXPORT_VIEW_PROPERTY(cameraId, NSString); RCT_EXPORT_VIEW_PROPERTY(enableDepthData, BOOL); -RCT_EXPORT_VIEW_PROPERTY(enableHighQualityPhotos, BOOL); RCT_EXPORT_VIEW_PROPERTY(enablePortraitEffectsMatteDelivery, BOOL); RCT_EXPORT_VIEW_PROPERTY(enableBufferCompression, BOOL); // use cases diff --git a/package/ios/Core/CameraConfiguration.swift b/package/ios/Core/CameraConfiguration.swift index 7269fa4cc3..3ecaf831ce 100644 --- a/package/ios/Core/CameraConfiguration.swift +++ b/package/ios/Core/CameraConfiguration.swift @@ -147,10 +147,9 @@ class CameraConfiguration { A Photo Output configuration */ struct Photo: Equatable { - var enableHighQualityPhotos = false + var qualityBalance = QualityBalance.balanced var enableDepthData = false var enablePortraitEffectsMatte = false - var qualityBalance = QualityBalance.balanced } /** diff --git a/package/ios/Core/CameraSession+Configuration.swift b/package/ios/Core/CameraSession+Configuration.swift index 2148f50472..47da5f5d17 100644 --- a/package/ios/Core/CameraSession+Configuration.swift +++ b/package/ios/Core/CameraSession+Configuration.swift @@ -80,23 +80,6 @@ extension CameraSession { let qualityPrioritization = AVCapturePhotoOutput.QualityPrioritization(fromQualityBalance: photo.qualityBalance) photoOutput.maxPhotoQualityPrioritization = qualityPrioritization } - if photo.enableHighQualityPhotos { - // TODO: Refactor this into an extension method. Same for AVCapturePhotoOutput. - if #available(iOS 16.0, *) { - if let device = videoDeviceInput?.device, - let targetFormat = configuration.format { - guard let format = device.formats.first(where: { f in targetFormat.isEqualTo(format: f) }) else { - throw CameraError.parameter(.invalid(unionName: "format", receivedValue: targetFormat.toJSValue().description)) - } - guard let maxSupportedDimension = format.supportedMaxPhotoDimensions.max(by: { ($0.width * $0.height) < ($1.width * $1.height) }) else { - throw CameraError.unknown(message: "supportedMaxPhotoDimensions was empty!", cause: nil) - } - photoOutput.maxPhotoDimensions = maxSupportedDimension - } - } else { - photoOutput.isHighResolutionCaptureEnabled = true - } - } // TODO: Enable isResponsiveCaptureEnabled? (iOS 17+) // TODO: Enable isFastCapturePrioritizationEnabled? (iOS 17+) if photo.enableDepthData { @@ -215,7 +198,7 @@ extension CameraSession { ReactLogger.log(level: .info, message: "Successfully configured Format!") } - func configurePixelFormat(configuration: CameraConfiguration) throws { + func configureVideoOutputFormat(configuration: CameraConfiguration) throws { guard case let .enabled(video) = configuration.video, let videoOutput else { // Video is not enabled @@ -230,6 +213,22 @@ extension CameraSession { ] } + func configurePhotoOutputFormat(configuration _: CameraConfiguration) throws { + guard let videoDeviceInput, let photoOutput else { + // Photo is not enabled + return + } + + // Configure the PhotoOutput Settings to use the given max-resolution. + // We need to run this after device.activeFormat has been set, otherwise the resolution is different. + let format = videoDeviceInput.device.activeFormat + if #available(iOS 16.0, *) { + photoOutput.maxPhotoDimensions = format.photoDimensions + } else { + photoOutput.isHighResolutionCaptureEnabled = true + } + } + // pragma MARK: Side-Props /** diff --git a/package/ios/Core/CameraSession+Photo.swift b/package/ios/Core/CameraSession+Photo.swift index cc78628681..d29c84fa16 100644 --- a/package/ios/Core/CameraSession+Photo.swift +++ b/package/ios/Core/CameraSession+Photo.swift @@ -41,14 +41,11 @@ extension CameraSession { // Create photo settings let photoSettings = AVCapturePhotoSettings() - // high resolution capture - if photo.enableHighQualityPhotos { - // TODO: On iOS 16+ this will be removed in favor of maxPhotoDimensions. - if #available(iOS 16.0, *) { - photoSettings.maxPhotoDimensions = photoOutput.maxPhotoDimensions - } else { - photoSettings.isHighResolutionPhotoEnabled = true - } + // set photo resolution + if #available(iOS 16.0, *) { + photoSettings.maxPhotoDimensions = photoOutput.maxPhotoDimensions + } else { + photoSettings.isHighResolutionPhotoEnabled = photoOutput.isHighResolutionCaptureEnabled } // depth data diff --git a/package/ios/Core/CameraSession.swift b/package/ios/Core/CameraSession.swift index 3357aa2db9..cb9e4ff955 100644 --- a/package/ios/Core/CameraSession.swift +++ b/package/ios/Core/CameraSession.swift @@ -154,10 +154,11 @@ class CameraSession: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVC if difference.formatChanged { try self.configureFormat(configuration: config, device: device) } - // 5. After step 2. and 4., we also need to configure the PixelFormat. - // This needs to be done AFTER we updated the `format`, as this controls the supported PixelFormats. + // 5. After step 2. and 4., we also need to configure some output properties that depend on format. + // This needs to be done AFTER we updated the `format`, as this controls the supported properties. if difference.outputsChanged || difference.formatChanged { - try self.configurePixelFormat(configuration: config) + try self.configureVideoOutputFormat(configuration: config) + try self.configurePhotoOutputFormat(configuration: config) } // 6. Configure side-props (fps, lowLightBoost) if difference.sidePropsChanged { diff --git a/package/package.json b/package/package.json index b49e44ca41..d3a8504bc1 100644 --- a/package/package.json +++ b/package/package.json @@ -98,7 +98,7 @@ "react": "^18.2.0", "react-native": "^0.72.3", "react-native-builder-bob": "^0.21.3", - "react-native-worklets-core": "^0.3.0", + "react-native-worklets-core": "^0.4.0", "release-it": "^16.1.3", "typescript": "^5.1.6" }, diff --git a/package/src/CameraProps.ts b/package/src/CameraProps.ts index 2e65934bac..03800cf785 100644 --- a/package/src/CameraProps.ts +++ b/package/src/CameraProps.ts @@ -265,18 +265,6 @@ export interface CameraProps extends ViewProps { * @default false */ enablePortraitEffectsMatteDelivery?: boolean - /** - * Indicates whether the Camera should prepare the photo pipeline to provide maximum quality photos. - * - * This enables: - * * High Resolution Capture ([`isHighResolutionCaptureEnabled`](https://developer.apple.com/documentation/avfoundation/avcapturephotooutput/1648721-ishighresolutioncaptureenabled)) - * * Virtual Device fusion for greater detail ([`isVirtualDeviceConstituentPhotoDeliveryEnabled`](https://developer.apple.com/documentation/avfoundation/avcapturephotooutput/3192189-isvirtualdeviceconstituentphotod)) - * * Dual Device fusion for greater detail ([`isDualCameraDualPhotoDeliveryEnabled`](https://developer.apple.com/documentation/avfoundation/avcapturephotosettings/2873917-isdualcameradualphotodeliveryena)) - * - * @platform iOS - * @default false - */ - enableHighQualityPhotos?: boolean /** * If `true`, show a debug view to display the FPS of the Video Pipeline (Frame Processor). * This is useful for debugging your Frame Processor's speed. diff --git a/package/yarn.lock b/package/yarn.lock index 24df4223be..ed82ddcdcc 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -6599,10 +6599,10 @@ react-native-builder-bob@^0.21.3: optionalDependencies: jetifier "^2.0.0" -react-native-worklets-core@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-0.3.0.tgz#4d6c4c4999d3bf2f8c67fa46fdd70d8b5bc7ba0e" - integrity sha512-bOoo6xbl+f+mz0Q65bLkUP3FxgYt7f/Bzi0c5Yj8Ix4vQCKMtgHwafrqCNRhW32N7TpTv3+zOoyQMJwQVr/frQ== +react-native-worklets-core@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-0.4.0.tgz#708f204d89327d88e155cccb5fc23421ca764b6f" + integrity sha512-0rYCwxnG6L85mih+3xe1r2RhhwKqjgVN9jikVh0iMPKDf9L4OZMJnl6Kh4zjXiW9rkyI5lBghfM4XIcLMfeU6w== dependencies: string-hash-64 "^1.0.3"