feat: Custom Orientation (#715)

* feat: Custom Orientation

* Update CameraView.swift

* Update CameraView.swift

* Try outputRotation approach

* whoops

* fix: Refactor `VideoCapture` instance

* Update orientation in didSetProps

* Update Orientation in iOS

* expose to objc

* Fix Orientation values

* format
This commit is contained in:
Marc Rousavy
2022-01-04 16:57:40 +01:00
committed by GitHub
parent dbfdf82c67
commit 48da1819fc
10 changed files with 164 additions and 51 deletions

View File

@@ -56,6 +56,7 @@ public final class CameraView: UIView {
@objc var hdr: NSNumber? // nullable bool
@objc var lowLightBoost: NSNumber? // nullable bool
@objc var colorSpace: NSString?
@objc var orientation: NSString?
// other props
@objc var isActive = false
@objc var torch = "off"
@@ -116,15 +117,6 @@ public final class CameraView: UIView {
return captureSession.isRunning
}
/// Returns the current _interface_ orientation of the main window
private var windowInterfaceOrientation: UIInterfaceOrientation {
if #available(iOS 13.0, *) {
return UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .unknown
} else {
return UIApplication.shared.statusBarOrientation
}
}
/// Convenience wrapper to get layer as its statically known type.
var videoPreviewLayer: AVCaptureVideoPreviewLayer {
// swiftlint:disable force_cast
@@ -205,6 +197,7 @@ public final class CameraView: UIView {
let shouldUpdateTorch = willReconfigure || changedProps.contains("torch") || shouldCheckActive
let shouldUpdateZoom = willReconfigure || changedProps.contains("zoom") || shouldCheckActive
let shouldUpdateVideoStabilization = willReconfigure || changedProps.contains("videoStabilizationMode")
let shouldUpdateOrientation = changedProps.contains("orientation")
if shouldReconfigure ||
shouldReconfigureAudioSession ||
@@ -213,7 +206,8 @@ public final class CameraView: UIView {
shouldUpdateZoom ||
shouldReconfigureFormat ||
shouldReconfigureDevice ||
shouldUpdateVideoStabilization {
shouldUpdateVideoStabilization ||
shouldUpdateOrientation {
cameraQueue.async {
if shouldReconfigure {
self.configureCaptureSession()
@@ -246,6 +240,10 @@ public final class CameraView: UIView {
}
}
if shouldUpdateOrientation {
self.updateOrientation()
}
// This is a wack workaround, but if I immediately set torch mode after `startRunning()`, the session isn't quite ready yet and will ignore torch.
if shouldUpdateTorch {
self.cameraQueue.asyncAfter(deadline: .now() + 0.1) {
@@ -316,27 +314,7 @@ public final class CameraView: UIView {
@objc
func onOrientationChanged() {
// Updates the Orientation for all rotable connections (outputs) as well as for the preview layer
DispatchQueue.main.async {
// `windowInterfaceOrientation` and `videoPreviewLayer` should only be accessed from UI thread
let isMirrored = self.videoDeviceInput?.device.position == .front
let orientation = self.windowInterfaceOrientation
self.videoPreviewLayer.connection?.setInterfaceOrientation(orientation)
self.cameraQueue.async {
// Run those updates on cameraQueue since they can be blocking.
self.captureSession.outputs.forEach { output in
output.connections.forEach { connection in
if connection.isVideoMirroringSupported {
connection.automaticallyAdjustsVideoMirroring = false
connection.isVideoMirrored = isMirrored
}
connection.setInterfaceOrientation(orientation)
}
}
}
}
updateOrientation()
}
// pragma MARK: Event Invokers