feat: Add pauseRecording
and resumeRecording
🔥 (#911)
* feat: Add `pauseRecording` and `resumeRecording` (iOS) * feat: Add `pauseRecording` and `resumeRecording` (Android) * feat: Add `pauseRecording` and `resumeRecording` (JS) * fix: Simplify Swift code for Recording
This commit is contained in:
parent
eb95add5ce
commit
4b9bcb37e0
@ -82,6 +82,30 @@ fun CameraView.startRecording(options: ReadableMap, onRecordCallback: Callback)
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
fun CameraView.pauseRecording() {
|
||||||
|
if (videoCapture == null) {
|
||||||
|
throw CameraNotReadyError()
|
||||||
|
}
|
||||||
|
if (activeVideoRecording == null) {
|
||||||
|
throw NoRecordingInProgressError()
|
||||||
|
}
|
||||||
|
|
||||||
|
activeVideoRecording!!.pause()
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
fun CameraView.resumeRecording() {
|
||||||
|
if (videoCapture == null) {
|
||||||
|
throw CameraNotReadyError()
|
||||||
|
}
|
||||||
|
if (activeVideoRecording == null) {
|
||||||
|
throw NoRecordingInProgressError()
|
||||||
|
}
|
||||||
|
|
||||||
|
activeVideoRecording!!.resume()
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("RestrictedApi")
|
@SuppressLint("RestrictedApi")
|
||||||
fun CameraView.stopRecording() {
|
fun CameraView.stopRecording() {
|
||||||
if (videoCapture == null) {
|
if (videoCapture == null) {
|
||||||
|
@ -115,6 +115,24 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun pauseRecording(viewTag: Int, promise: Promise) {
|
||||||
|
withPromise(promise) {
|
||||||
|
val view = findCameraView(viewTag)
|
||||||
|
view.pauseRecording()
|
||||||
|
return@withPromise null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ReactMethod
|
||||||
|
fun resumeRecording(viewTag: Int, promise: Promise) {
|
||||||
|
withPromise(promise) {
|
||||||
|
val view = findCameraView(viewTag)
|
||||||
|
view.resumeRecording()
|
||||||
|
return@withPromise null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
fun stopRecording(viewTag: Int, promise: Promise) {
|
fun stopRecording(viewTag: Int, promise: Promise) {
|
||||||
withPromise(promise) {
|
withPromise(promise) {
|
||||||
|
@ -161,30 +161,28 @@ extension CameraView: AVCaptureVideoDataOutputSampleBufferDelegate, AVCaptureAud
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement for JS
|
|
||||||
func pauseRecording(promise: Promise) {
|
func pauseRecording(promise: Promise) {
|
||||||
cameraQueue.async {
|
cameraQueue.async {
|
||||||
withPromise(promise) {
|
withPromise(promise) {
|
||||||
if self.isRecording {
|
guard self.recordingSession != nil else {
|
||||||
self.isRecording = false
|
// there's no active recording!
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
throw CameraError.capture(.noRecordingInProgress)
|
throw CameraError.capture(.noRecordingInProgress)
|
||||||
}
|
}
|
||||||
|
self.isRecording = false
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement for JS
|
|
||||||
func resumeRecording(promise: Promise) {
|
func resumeRecording(promise: Promise) {
|
||||||
cameraQueue.async {
|
cameraQueue.async {
|
||||||
withPromise(promise) {
|
withPromise(promise) {
|
||||||
if !self.isRecording {
|
guard self.recordingSession != nil else {
|
||||||
self.isRecording = true
|
// there's no active recording!
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
throw CameraError.capture(.noRecordingInProgress)
|
throw CameraError.capture(.noRecordingInProgress)
|
||||||
}
|
}
|
||||||
|
self.isRecording = true
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,8 @@ RCT_EXPORT_VIEW_PROPERTY(onViewReady, RCTDirectEventBlock);
|
|||||||
|
|
||||||
// Camera View Functions
|
// Camera View Functions
|
||||||
RCT_EXTERN_METHOD(startRecording:(nonnull NSNumber *)node options:(NSDictionary *)options onRecordCallback:(RCTResponseSenderBlock)onRecordCallback);
|
RCT_EXTERN_METHOD(startRecording:(nonnull NSNumber *)node options:(NSDictionary *)options onRecordCallback:(RCTResponseSenderBlock)onRecordCallback);
|
||||||
|
RCT_EXTERN_METHOD(pauseRecording:(nonnull NSNumber *)node resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
||||||
|
RCT_EXTERN_METHOD(resumeRecording:(nonnull NSNumber *)node resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
||||||
RCT_EXTERN_METHOD(stopRecording:(nonnull NSNumber *)node resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
RCT_EXTERN_METHOD(stopRecording:(nonnull NSNumber *)node resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
||||||
RCT_EXTERN_METHOD(takePhoto:(nonnull NSNumber *)node options:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
RCT_EXTERN_METHOD(takePhoto:(nonnull NSNumber *)node options:(NSDictionary *)options resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
||||||
RCT_EXTERN_METHOD(focus:(nonnull NSNumber *)node point:(NSDictionary *)point resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
RCT_EXTERN_METHOD(focus:(nonnull NSNumber *)node point:(NSDictionary *)point resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject);
|
||||||
|
@ -49,6 +49,18 @@ final class CameraViewManager: RCTViewManager {
|
|||||||
component.startRecording(options: options, callback: onRecordCallback)
|
component.startRecording(options: options, callback: onRecordCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
final func pauseRecording(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
|
let component = getCameraView(withTag: node)
|
||||||
|
component.pauseRecording(promise: Promise(resolver: resolve, rejecter: reject))
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
final func resumeRecording(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
|
let component = getCameraView(withTag: node)
|
||||||
|
component.resumeRecording(promise: Promise(resolver: resolve, rejecter: reject))
|
||||||
|
}
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
final func stopRecording(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
final func stopRecording(_ node: NSNumber, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
||||||
let component = getCameraView(withTag: node)
|
let component = getCameraView(withTag: node)
|
||||||
|
@ -190,6 +190,63 @@ export class Camera extends React.PureComponent<CameraProps> {
|
|||||||
throw tryParseNativeCameraError(e);
|
throw tryParseNativeCameraError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pauses the current video recording.
|
||||||
|
*
|
||||||
|
* @throws {@linkcode CameraCaptureError} When any kind of error occured while pausing the video recording. Use the {@linkcode CameraCaptureError.code | code} property to get the actual error
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* // Start
|
||||||
|
* await camera.current.startRecording()
|
||||||
|
* await timeout(1000)
|
||||||
|
* // Pause
|
||||||
|
* await camera.current.pauseRecording()
|
||||||
|
* await timeout(500)
|
||||||
|
* // Resume
|
||||||
|
* await camera.current.resumeRecording()
|
||||||
|
* await timeout(2000)
|
||||||
|
* // Stop
|
||||||
|
* const video = await camera.current.stopRecording()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public async pauseRecording(): Promise<void> {
|
||||||
|
try {
|
||||||
|
return await CameraModule.pauseRecording(this.handle);
|
||||||
|
} catch (e) {
|
||||||
|
throw tryParseNativeCameraError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resumes a currently paused video recording.
|
||||||
|
*
|
||||||
|
* @throws {@linkcode CameraCaptureError} When any kind of error occured while resuming the video recording. Use the {@linkcode CameraCaptureError.code | code} property to get the actual error
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* // Start
|
||||||
|
* await camera.current.startRecording()
|
||||||
|
* await timeout(1000)
|
||||||
|
* // Pause
|
||||||
|
* await camera.current.pauseRecording()
|
||||||
|
* await timeout(500)
|
||||||
|
* // Resume
|
||||||
|
* await camera.current.resumeRecording()
|
||||||
|
* await timeout(2000)
|
||||||
|
* // Stop
|
||||||
|
* const video = await camera.current.stopRecording()
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
public async resumeRecording(): Promise<void> {
|
||||||
|
try {
|
||||||
|
return await CameraModule.resumeRecording(this.handle);
|
||||||
|
} catch (e) {
|
||||||
|
throw tryParseNativeCameraError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop the current video recording.
|
* Stop the current video recording.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user