feat: Video Stabilization (#160)
* Set video stabilization mode * Fix video stabilization below iOS 13 * swift format
This commit is contained in:
parent
e5fe5ab175
commit
0b5d277514
@ -53,6 +53,7 @@ public final class CameraView: UIView {
|
|||||||
@objc var isActive = false
|
@objc var isActive = false
|
||||||
@objc var torch = "off"
|
@objc var torch = "off"
|
||||||
@objc var zoom: NSNumber = 0.0 // in percent
|
@objc var zoom: NSNumber = 0.0 // in percent
|
||||||
|
@objc var videoStabilizationMode: NSString?
|
||||||
// events
|
// events
|
||||||
@objc var onInitialized: RCTDirectEventBlock?
|
@objc var onInitialized: RCTDirectEventBlock?
|
||||||
@objc var onError: RCTDirectEventBlock?
|
@objc var onError: RCTDirectEventBlock?
|
||||||
@ -164,8 +165,15 @@ public final class CameraView: UIView {
|
|||||||
let shouldCheckActive = willReconfigure || changedProps.contains("isActive") || captureSession.isRunning != isActive
|
let shouldCheckActive = willReconfigure || changedProps.contains("isActive") || captureSession.isRunning != isActive
|
||||||
let shouldUpdateTorch = willReconfigure || changedProps.contains("torch") || shouldCheckActive
|
let shouldUpdateTorch = willReconfigure || changedProps.contains("torch") || shouldCheckActive
|
||||||
let shouldUpdateZoom = willReconfigure || changedProps.contains("zoom") || shouldCheckActive
|
let shouldUpdateZoom = willReconfigure || changedProps.contains("zoom") || shouldCheckActive
|
||||||
|
let shouldUpdateVideoStabilization = willReconfigure || changedProps.contains("videoStabilizationMode")
|
||||||
|
|
||||||
if shouldReconfigure || shouldCheckActive || shouldUpdateTorch || shouldUpdateZoom || shouldReconfigureFormat || shouldReconfigureDevice {
|
if shouldReconfigure ||
|
||||||
|
shouldCheckActive ||
|
||||||
|
shouldUpdateTorch ||
|
||||||
|
shouldUpdateZoom ||
|
||||||
|
shouldReconfigureFormat ||
|
||||||
|
shouldReconfigureDevice ||
|
||||||
|
shouldUpdateVideoStabilization {
|
||||||
cameraQueue.async {
|
cameraQueue.async {
|
||||||
if shouldReconfigure {
|
if shouldReconfigure {
|
||||||
self.configureCaptureSession()
|
self.configureCaptureSession()
|
||||||
@ -176,6 +184,9 @@ public final class CameraView: UIView {
|
|||||||
if shouldReconfigureDevice {
|
if shouldReconfigureDevice {
|
||||||
self.configureDevice()
|
self.configureDevice()
|
||||||
}
|
}
|
||||||
|
if shouldUpdateVideoStabilization, let videoStabilizationMode = self.videoStabilizationMode as String? {
|
||||||
|
self.captureSession.setVideoStabilizationMode(videoStabilizationMode)
|
||||||
|
}
|
||||||
|
|
||||||
if shouldUpdateZoom {
|
if shouldUpdateZoom {
|
||||||
let zoomPercent = CGFloat(max(min(self.zoom.doubleValue, 1.0), 0.0))
|
let zoomPercent = CGFloat(max(min(self.zoom.doubleValue, 1.0), 0.0))
|
||||||
|
@ -34,6 +34,7 @@ RCT_EXPORT_VIEW_PROPERTY(frameProcessorFps, NSNumber);
|
|||||||
RCT_EXPORT_VIEW_PROPERTY(hdr, NSNumber); // nullable bool
|
RCT_EXPORT_VIEW_PROPERTY(hdr, NSNumber); // nullable bool
|
||||||
RCT_EXPORT_VIEW_PROPERTY(lowLightBoost, NSNumber); // nullable bool
|
RCT_EXPORT_VIEW_PROPERTY(lowLightBoost, NSNumber); // nullable bool
|
||||||
RCT_EXPORT_VIEW_PROPERTY(colorSpace, NSString);
|
RCT_EXPORT_VIEW_PROPERTY(colorSpace, NSString);
|
||||||
|
RCT_EXPORT_VIEW_PROPERTY(videoStabilizationMode, NSString);
|
||||||
// other props
|
// other props
|
||||||
RCT_EXPORT_VIEW_PROPERTY(preset, NSString);
|
RCT_EXPORT_VIEW_PROPERTY(preset, NSString);
|
||||||
RCT_EXPORT_VIEW_PROPERTY(torch, NSString);
|
RCT_EXPORT_VIEW_PROPERTY(torch, NSString);
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// AVCaptureSession+setVideoStabilizationMode.swift
|
||||||
|
// VisionCamera
|
||||||
|
//
|
||||||
|
// Created by Marc Rousavy on 02.06.21.
|
||||||
|
// Copyright © 2021 Facebook. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import AVFoundation
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension AVCaptureSession {
|
||||||
|
/**
|
||||||
|
Set the given video stabilization mode for all capture connections.
|
||||||
|
*/
|
||||||
|
func setVideoStabilizationMode(_ mode: String) {
|
||||||
|
if #available(iOS 13.0, *) {
|
||||||
|
guard let mode = try? AVCaptureVideoStabilizationMode(withString: mode) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
connections.forEach { connection in
|
||||||
|
if connection.isVideoStabilizationSupported {
|
||||||
|
connection.preferredVideoStabilizationMode = mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -51,6 +51,7 @@
|
|||||||
B88751A725E0102000DB86D6 /* CameraView+Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518225E0102000DB86D6 /* CameraView+Zoom.swift */; };
|
B88751A725E0102000DB86D6 /* CameraView+Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518225E0102000DB86D6 /* CameraView+Zoom.swift */; };
|
||||||
B88751A825E0102000DB86D6 /* CameraError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518325E0102000DB86D6 /* CameraError.swift */; };
|
B88751A825E0102000DB86D6 /* CameraError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518325E0102000DB86D6 /* CameraError.swift */; };
|
||||||
B88751A925E0102000DB86D6 /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518425E0102000DB86D6 /* CameraView.swift */; };
|
B88751A925E0102000DB86D6 /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B887518425E0102000DB86D6 /* CameraView.swift */; };
|
||||||
|
B88B47472667C8E00091F538 /* AVCaptureSession+setVideoStabilizationMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B88B47462667C8E00091F538 /* AVCaptureSession+setVideoStabilizationMode.swift */; };
|
||||||
B8994E6C263F03E100069589 /* JSIUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = B8994E6B263F03E100069589 /* JSIUtils.mm */; };
|
B8994E6C263F03E100069589 /* JSIUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = B8994E6B263F03E100069589 /* JSIUtils.mm */; };
|
||||||
B8A751D82609E4B30011C623 /* FrameProcessorRuntimeManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = B8A751D72609E4B30011C623 /* FrameProcessorRuntimeManager.mm */; };
|
B8A751D82609E4B30011C623 /* FrameProcessorRuntimeManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = B8A751D72609E4B30011C623 /* FrameProcessorRuntimeManager.mm */; };
|
||||||
B8CCC5A1266694B200B3916F /* MeasureElapsedTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CCC5A0266694B200B3916F /* MeasureElapsedTime.swift */; };
|
B8CCC5A1266694B200B3916F /* MeasureElapsedTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8CCC5A0266694B200B3916F /* MeasureElapsedTime.swift */; };
|
||||||
@ -128,6 +129,7 @@
|
|||||||
B887518325E0102000DB86D6 /* CameraError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraError.swift; sourceTree = "<group>"; };
|
B887518325E0102000DB86D6 /* CameraError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraError.swift; sourceTree = "<group>"; };
|
||||||
B887518425E0102000DB86D6 /* CameraView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
|
B887518425E0102000DB86D6 /* CameraView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
|
||||||
B88873E5263D46C7008B1D0E /* FrameProcessorPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrameProcessorPlugin.h; sourceTree = "<group>"; };
|
B88873E5263D46C7008B1D0E /* FrameProcessorPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrameProcessorPlugin.h; sourceTree = "<group>"; };
|
||||||
|
B88B47462667C8E00091F538 /* AVCaptureSession+setVideoStabilizationMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVCaptureSession+setVideoStabilizationMode.swift"; sourceTree = "<group>"; };
|
||||||
B8994E6B263F03E100069589 /* JSIUtils.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = JSIUtils.mm; sourceTree = "<group>"; };
|
B8994E6B263F03E100069589 /* JSIUtils.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = JSIUtils.mm; sourceTree = "<group>"; };
|
||||||
B8A751D62609E4980011C623 /* FrameProcessorRuntimeManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrameProcessorRuntimeManager.h; sourceTree = "<group>"; };
|
B8A751D62609E4980011C623 /* FrameProcessorRuntimeManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FrameProcessorRuntimeManager.h; sourceTree = "<group>"; };
|
||||||
B8A751D72609E4B30011C623 /* FrameProcessorRuntimeManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FrameProcessorRuntimeManager.mm; sourceTree = "<group>"; };
|
B8A751D72609E4B30011C623 /* FrameProcessorRuntimeManager.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = FrameProcessorRuntimeManager.mm; sourceTree = "<group>"; };
|
||||||
@ -200,6 +202,7 @@
|
|||||||
B887516825E0102000DB86D6 /* AVCapturePhotoOutput+mirror.swift */,
|
B887516825E0102000DB86D6 /* AVCapturePhotoOutput+mirror.swift */,
|
||||||
B887516925E0102000DB86D6 /* AVCaptureDevice.Format+matchesFilter.swift */,
|
B887516925E0102000DB86D6 /* AVCaptureDevice.Format+matchesFilter.swift */,
|
||||||
B887516A25E0102000DB86D6 /* AVCaptureDevice.Format+toDictionary.swift */,
|
B887516A25E0102000DB86D6 /* AVCaptureDevice.Format+toDictionary.swift */,
|
||||||
|
B88B47462667C8E00091F538 /* AVCaptureSession+setVideoStabilizationMode.swift */,
|
||||||
B887516B25E0102000DB86D6 /* AVCaptureVideoDataOutput+mirror.swift */,
|
B887516B25E0102000DB86D6 /* AVCaptureVideoDataOutput+mirror.swift */,
|
||||||
B887516225E0102000DB86D6 /* Collection+safe.swift */,
|
B887516225E0102000DB86D6 /* Collection+safe.swift */,
|
||||||
);
|
);
|
||||||
@ -427,6 +430,7 @@
|
|||||||
B88751A525E0102000DB86D6 /* CameraView+Focus.swift in Sources */,
|
B88751A525E0102000DB86D6 /* CameraView+Focus.swift in Sources */,
|
||||||
B86DC971260E2D5200FB17B2 /* AVAudioSession+trySetAllowHaptics.swift in Sources */,
|
B86DC971260E2D5200FB17B2 /* AVAudioSession+trySetAllowHaptics.swift in Sources */,
|
||||||
B8805067266798B600EAD7F2 /* JSConsoleHelper.mm in Sources */,
|
B8805067266798B600EAD7F2 /* JSConsoleHelper.mm in Sources */,
|
||||||
|
B88B47472667C8E00091F538 /* AVCaptureSession+setVideoStabilizationMode.swift in Sources */,
|
||||||
B887519E25E0102000DB86D6 /* AVCapturePhotoOutput.QualityPrioritization+descriptor.swift in Sources */,
|
B887519E25E0102000DB86D6 /* AVCapturePhotoOutput.QualityPrioritization+descriptor.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { ViewProps } from 'react-native';
|
import type { ViewProps } from 'react-native';
|
||||||
import type { CameraDevice, CameraDeviceFormat, ColorSpace } from './CameraDevice';
|
import type { CameraDevice, CameraDeviceFormat, ColorSpace, VideoStabilizationMode } from './CameraDevice';
|
||||||
import type { CameraRuntimeError } from './CameraError';
|
import type { CameraRuntimeError } from './CameraError';
|
||||||
import type { CameraPreset } from './CameraPreset';
|
import type { CameraPreset } from './CameraPreset';
|
||||||
import type { Frame } from './Frame';
|
import type { Frame } from './Frame';
|
||||||
@ -94,6 +94,13 @@ export interface CameraProps extends ViewProps {
|
|||||||
* Requires `format` to be set.
|
* Requires `format` to be set.
|
||||||
*/
|
*/
|
||||||
colorSpace?: ColorSpace;
|
colorSpace?: ColorSpace;
|
||||||
|
/**
|
||||||
|
* Specifies the video stabilization mode to use for this camera device. Make sure the given `format` contains the given `videoStabilizationMode`.
|
||||||
|
*
|
||||||
|
* Requires `format` to be set.
|
||||||
|
* @platform iOS
|
||||||
|
*/
|
||||||
|
videoStabilizationMode?: VideoStabilizationMode;
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user