From a5e10a8606d47694a2c36daf4b27af1bb809acad Mon Sep 17 00:00:00 2001 From: Marc Rousavy Date: Mon, 4 Dec 2023 13:43:17 +0300 Subject: [PATCH] fix: Fix `torch` not staying on while recording (#2249) * fix: Fix `zoom` on native gesture * fix: Control `torch` from JS side * Update CameraView+RecordVideo.kt * Update CameraView+Zoom.swift --- .../mrousavy/camera/CameraView+RecordVideo.kt | 14 ----------- package/ios/CameraView+RecordVideo.swift | 12 ---------- package/ios/CameraView+Zoom.swift | 7 +++--- package/ios/Core/CameraSession+Video.swift | 8 ------- package/src/Camera.tsx | 24 ++++++++++++++++++- 5 files changed, 26 insertions(+), 39 deletions(-) diff --git a/package/android/src/main/java/com/mrousavy/camera/CameraView+RecordVideo.kt b/package/android/src/main/java/com/mrousavy/camera/CameraView+RecordVideo.kt index ea16c7c..4cbdf82 100644 --- a/package/android/src/main/java/com/mrousavy/camera/CameraView+RecordVideo.kt +++ b/package/android/src/main/java/com/mrousavy/camera/CameraView+RecordVideo.kt @@ -9,9 +9,7 @@ import com.mrousavy.camera.core.MicrophonePermissionError import com.mrousavy.camera.core.RecorderError import com.mrousavy.camera.core.RecordingSession import com.mrousavy.camera.core.code -import com.mrousavy.camera.types.Flash import com.mrousavy.camera.types.RecordVideoOptions -import com.mrousavy.camera.types.Torch import com.mrousavy.camera.utils.makeErrorMap import java.util.* @@ -23,14 +21,6 @@ suspend fun CameraView.startRecording(options: RecordVideoOptions, onRecordCallb } } - val enableFlash = options.flash == Flash.ON - if (enableFlash) { - // overrides current torch mode value to enable flash while recording - cameraSession.configure { config -> - config.torch = Torch.ON - } - } - val callback = { video: RecordingSession.Video -> val map = Arguments.createMap() map.putString("path", video.path) @@ -57,8 +47,4 @@ suspend fun CameraView.resumeRecording() { @SuppressLint("RestrictedApi") suspend fun CameraView.stopRecording() { cameraSession.stopRecording() - // Set torch back to it's original value in case we just used it as a flash for the recording. - cameraSession.configure { config -> - config.torch = torch - } } diff --git a/package/ios/CameraView+RecordVideo.swift b/package/ios/CameraView+RecordVideo.swift index a9a4153..8ecad27 100644 --- a/package/ios/CameraView+RecordVideo.swift +++ b/package/ios/CameraView+RecordVideo.swift @@ -18,13 +18,6 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud do { let options = try RecordVideoOptions(fromJSValue: options) - // If flash is on, just enable torch - if options.flash != .off { - cameraSession.configure { config in - config.torch = options.flash - } - } - // Start Recording with success and error callbacks cameraSession.startRecording( options: options, @@ -47,11 +40,6 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud func stopRecording(promise: Promise) { cameraSession.stopRecording(promise: promise) - - // If flash was used, we had the torch enabled. Now set it back to it's original state. - cameraSession.configure { config in - config.torch = try Torch(jsValue: torch) - } } func pauseRecording(promise: Promise) { diff --git a/package/ios/CameraView+Zoom.swift b/package/ios/CameraView+Zoom.swift index e7ecabd..74dc647 100644 --- a/package/ios/CameraView+Zoom.swift +++ b/package/ios/CameraView+Zoom.swift @@ -18,10 +18,9 @@ extension CameraView { return } - // Update zoom on Camera - cameraSession.configure { configuration in - configuration.zoom = scale - } + // Update zoom React prop + zoom = NSNumber(value: scale) + didSetProps(["zoom"]) } func addPinchGestureRecognizer() { diff --git a/package/ios/Core/CameraSession+Video.swift b/package/ios/Core/CameraSession+Video.swift index 39ce060..8836b71 100644 --- a/package/ios/Core/CameraSession+Video.swift +++ b/package/ios/Core/CameraSession+Video.swift @@ -43,14 +43,6 @@ extension CameraSession { self.deactivateAudioSession() } } - // Reset flash - if options.flash != .off { - // Set torch mode back to what it was before if we used it for the video flash. - self.configure { config in - let torch = self.configuration?.torch ?? .off - config.torch = torch - } - } } self.isRecording = false diff --git a/package/src/Camera.tsx b/package/src/Camera.tsx index 2a6adf8..d219c0e 100644 --- a/package/src/Camera.tsx +++ b/package/src/Camera.tsx @@ -40,6 +40,9 @@ type NativeRecordVideoOptions = Omit & Readonly +interface CameraState { + isRecordingWithFlash: boolean +} //#endregion //#region Camera Component @@ -71,7 +74,7 @@ type RefType = React.Component & Readonly * * @component */ -export class Camera extends React.PureComponent { +export class Camera extends React.PureComponent { /** @internal */ static displayName = 'Camera' /** @internal */ @@ -90,6 +93,9 @@ export class Camera extends React.PureComponent { this.onCodeScanned = this.onCodeScanned.bind(this) this.ref = React.createRef() this.lastFrameProcessor = undefined + this.state = { + isRecordingWithFlash: false, + } } private get handle(): number { @@ -163,6 +169,13 @@ export class Camera extends React.PureComponent { if (typeof onRecordingError !== 'function' || typeof onRecordingFinished !== 'function') throw new CameraRuntimeError('parameter/invalid-parameter', 'The onRecordingError or onRecordingFinished functions were not set!') + if (options.flash === 'on') { + // Enable torch for video recording + this.setState({ + isRecordingWithFlash: true, + }) + } + const nativeOptions: NativeRecordVideoOptions = passThruOptions if (typeof videoBitRate === 'number') { // If the user passed an absolute number as a bit-rate, we just use this as a full override. @@ -173,6 +186,13 @@ export class Camera extends React.PureComponent { } const onRecordCallback = (video?: VideoFile, error?: CameraCaptureError): void => { + if (this.state.isRecordingWithFlash) { + // disable torch again if it was enabled + this.setState({ + isRecordingWithFlash: false, + }) + } + if (error != null) return onRecordingError(error) if (video != null) return onRecordingFinished(video) } @@ -450,12 +470,14 @@ export class Camera extends React.PureComponent { } const shouldEnableBufferCompression = props.video === true && frameProcessor == null + const torch = this.state.isRecordingWithFlash ? 'on' : props.torch return (