iOS Camera Settings #6
| @@ -50,4 +50,12 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud | |||||||
|   func resumeRecording(promise: Promise) { |   func resumeRecording(promise: Promise) { | ||||||
|     cameraSession.resumeRecording(promise: promise) |     cameraSession.resumeRecording(promise: promise) | ||||||
|   } |   } | ||||||
|  |    | ||||||
|  |   func lockExposure(promise: Promise) { | ||||||
|  |     cameraSession.lockCurrentExposure(promise: promise) | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   func unlockExposure(promise: Promise) { | ||||||
|  |     cameraSession.unlockCurrentExposure(promise: promise) | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -86,5 +86,13 @@ RCT_EXTERN_METHOD(focus | |||||||
|                   : (NSDictionary*)point resolve |                   : (NSDictionary*)point resolve | ||||||
|                   : (RCTPromiseResolveBlock)resolve reject |                   : (RCTPromiseResolveBlock)resolve reject | ||||||
|                   : (RCTPromiseRejectBlock)reject); |                   : (RCTPromiseRejectBlock)reject); | ||||||
|  | RCT_EXTERN_METHOD(lockCurrentExposure | ||||||
|  |                   : (nonnull NSNumber*)node resolve | ||||||
|  |                   : (RCTPromiseResolveBlock)resolve reject | ||||||
|  |                   : (RCTPromiseRejectBlock)reject); | ||||||
|  | RCT_EXTERN_METHOD(unlockCurrentExposure | ||||||
|  |                   : (nonnull NSNumber*)node resolve | ||||||
|  |                   : (RCTPromiseResolveBlock)resolve reject | ||||||
|  |                   : (RCTPromiseRejectBlock)reject); | ||||||
|  |  | ||||||
| @end | @end | ||||||
|   | |||||||
| @@ -111,6 +111,18 @@ final class CameraViewManager: RCTViewManager { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|    |    | ||||||
|  |   @objc | ||||||
|  |   final func lockCurrentExposure(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { | ||||||
|  |     let component = getCameraView(withTag: node) | ||||||
|  |     component.lockExposure(promise: Promise(resolver: resolve, rejecter: reject)) | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   @objc | ||||||
|  |   final func unlockCurrentExposure(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { | ||||||
|  |     let component = getCameraView(withTag: node) | ||||||
|  |     component.unlockExposure(promise: Promise(resolver: resolve, rejecter: reject)) | ||||||
|  |   } | ||||||
|  |  | ||||||
|   // MARK: Private |   // MARK: Private | ||||||
|  |  | ||||||
|   private func getCameraView(withTag tag: NSNumber) -> CameraView { |   private func getCameraView(withTag tag: NSNumber) -> CameraView { | ||||||
|   | |||||||
| @@ -18,8 +18,6 @@ extension CameraSession { | |||||||
|                       filePath: String, |                       filePath: String, | ||||||
|                       onVideoRecorded: @escaping (_ video: Video) -> Void, |                       onVideoRecorded: @escaping (_ video: Video) -> Void, | ||||||
|                       onError: @escaping (_ error: CameraError) -> Void) { |                       onError: @escaping (_ error: CameraError) -> Void) { | ||||||
|      |  | ||||||
|     lockCurrentExposure(for: captureSession) |  | ||||||
|     // Run on Camera Queue |     // Run on Camera Queue | ||||||
|     CameraQueues.cameraQueue.async { |     CameraQueues.cameraQueue.async { | ||||||
|       let start = DispatchTime.now() |       let start = DispatchTime.now() | ||||||
| @@ -194,13 +192,15 @@ extension CameraSession { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   func lockCurrentExposure(for session: AVCaptureSession) { |   func lockCurrentExposure(promise: Promise) { | ||||||
|       guard let captureDevice = AVCaptureDevice.default(for: .video) else { |     CameraQueues.cameraQueue.async { | ||||||
|  |       withPromise(promise) { | ||||||
|  |         guard let captureDevice = AVCaptureDevice.default(for: .video) else { | ||||||
|           print("No capture device available") |           print("No capture device available") | ||||||
|           return |           return | ||||||
|       } |         } | ||||||
|          |          | ||||||
|       do { |         do { | ||||||
|           // Lock the device for configuration |           // Lock the device for configuration | ||||||
|           try captureDevice.lockForConfiguration() |           try captureDevice.lockForConfiguration() | ||||||
|            |            | ||||||
| @@ -210,18 +210,45 @@ extension CameraSession { | |||||||
|            |            | ||||||
|           // Check if the device supports custom exposure settings |           // Check if the device supports custom exposure settings | ||||||
|           if captureDevice.isExposureModeSupported(.custom) { |           if captureDevice.isExposureModeSupported(.custom) { | ||||||
|               // Lock the current exposure and ISO by setting custom exposure mode |             // Lock the current exposure and ISO by setting custom exposure mode | ||||||
|               captureDevice.setExposureModeCustom(duration: currentExposureDuration, iso: currentISO, completionHandler: nil) |             captureDevice.setExposureModeCustom(duration: currentExposureDuration, iso: currentISO, completionHandler: nil) | ||||||
|               ReactLogger.log(level: .info, message: "Exposure and ISO locked at current values") |             ReactLogger.log(level: .info, message: "Exposure and ISO locked at current values") | ||||||
|           } else { |           } else { | ||||||
|               ReactLogger.log(level: .info, message:"Custom exposure mode not supported") |             ReactLogger.log(level: .info, message:"Custom exposure mode not supported") | ||||||
|           } |           } | ||||||
|            |            | ||||||
|           // Unlock the device after configuration |           // Unlock the device after configuration | ||||||
|           captureDevice.unlockForConfiguration() |           captureDevice.unlockForConfiguration() | ||||||
|            |            | ||||||
|       } catch { |         } catch { | ||||||
|         ReactLogger.log(level: .warning, message:"Error locking exposure: \(error)") |           ReactLogger.log(level: .warning, message:"Error locking exposure: \(error)") | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         return nil | ||||||
|       } |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   func unlockCurrentExposure(promise: Promise) { | ||||||
|  |     CameraQueues.cameraQueue.async { | ||||||
|  |       withPromise(promise) { | ||||||
|  |         guard let captureDevice = AVCaptureDevice.default(for: .video) else { | ||||||
|  |           print("No capture device available") | ||||||
|  |           return | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         do { | ||||||
|  |           if captureDevice.isExposureModeSupported(.autoExpose) { | ||||||
|  |             try captureDevice.lockForConfiguration() | ||||||
|  |             captureDevice.exposureMode = .continuousAutoExposure | ||||||
|  |             captureDevice.unlockForConfiguration() | ||||||
|  |           } | ||||||
|  |         } catch { | ||||||
|  |           ReactLogger.log(level: .warning, message:"Error unlocking exposure: \(error)") | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         return nil | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -319,6 +319,22 @@ export class Camera extends React.PureComponent<CameraProps, CameraState> { | |||||||
|       throw tryParseNativeCameraError(e) |       throw tryParseNativeCameraError(e) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public async lockCurrentExposure(): Promise<void> { | ||||||
|  |     try { | ||||||
|  |       return await CameraModule.lockCurrentExposure(this.handle) | ||||||
|  |     } catch (e) { | ||||||
|  |       throw tryParseNativeCameraError(e) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public async unlockCurrentExposure(): Promise<void> { | ||||||
|  |     try { | ||||||
|  |       return await CameraModule.unlockCurrentExposure(this.handle) | ||||||
|  |     } catch (e) { | ||||||
|  |       throw tryParseNativeCameraError(e) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|   //#endregion |   //#endregion | ||||||
|  |  | ||||||
|   //#region Static Functions (NativeModule) |   //#region Static Functions (NativeModule) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user