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
This commit is contained in:
Marc Rousavy 2023-12-04 13:43:17 +03:00 committed by GitHub
parent d78d3ea214
commit a5e10a8606
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 26 additions and 39 deletions

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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() {

View File

@ -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

View File

@ -40,6 +40,9 @@ type NativeRecordVideoOptions = Omit<RecordVideoOptions, 'onRecordingError' | 'o
videoBitRateMultiplier?: number
}
type RefType = React.Component<NativeCameraViewProps> & Readonly<NativeMethods>
interface CameraState {
isRecordingWithFlash: boolean
}
//#endregion
//#region Camera Component
@ -71,7 +74,7 @@ type RefType = React.Component<NativeCameraViewProps> & Readonly<NativeMethods>
*
* @component
*/
export class Camera extends React.PureComponent<CameraProps> {
export class Camera extends React.PureComponent<CameraProps, CameraState> {
/** @internal */
static displayName = 'Camera'
/** @internal */
@ -90,6 +93,9 @@ export class Camera extends React.PureComponent<CameraProps> {
this.onCodeScanned = this.onCodeScanned.bind(this)
this.ref = React.createRef<RefType>()
this.lastFrameProcessor = undefined
this.state = {
isRecordingWithFlash: false,
}
}
private get handle(): number {
@ -163,6 +169,13 @@ export class Camera extends React.PureComponent<CameraProps> {
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<CameraProps> {
}
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<CameraProps> {
}
const shouldEnableBufferCompression = props.video === true && frameProcessor == null
const torch = this.state.isRecordingWithFlash ? 'on' : props.torch
return (
<NativeCameraView
{...props}
cameraId={device.id}
ref={this.ref}
torch={torch}
onViewReady={this.onViewReady}
onInitialized={this.onInitialized}
onCodeScanned={this.onCodeScanned}