fix preview and recording orientation fix

- add onCameraConfigurationChanged to CameraSessionDelegate to notify CameraView when configuration changes
- when orientatin change update CameraView.PreviewView.videoPreviewLayer.connection orientation value
This commit is contained in:
Rui Rodrigues 2024-08-02 14:39:23 +01:00
parent 7c162fecb1
commit 3a20c44a31
5 changed files with 56 additions and 22 deletions

View File

@ -304,6 +304,15 @@ public final class CameraView: UIView, CameraSessionDelegate {
onInitialized([:]) onInitialized([:])
} }
func onCameraConfigurationChanged(_ configuration: CameraConfiguration?, _ difference: CameraConfiguration.Difference?) {
guard let configuration, let difference else { return }
if difference.orientationChanged, let connection = previewView.videoPreviewLayer.connection {
let videoPreviewLayer = previewView.videoPreviewLayer
connection.setOrientation(configuration.orientation)
}
}
func onCameraStarted() { func onCameraStarted() {
ReactLogger.log(level: .info, message: "Camera started!") ReactLogger.log(level: .info, message: "Camera started!")
guard let onStarted = onStarted else { guard let onStarted = onStarted else {

View File

@ -195,6 +195,7 @@ class CameraSession: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, AVC
self.delegate?.onSessionInitialized() self.delegate?.onSessionInitialized()
} }
self.delegate?.onCameraConfigurationChanged(config, difference)
// After configuring, set this to the new configuration. // After configuring, set this to the new configuration.
self.configuration = config self.configuration = config
} catch { } catch {

View File

@ -21,6 +21,8 @@ protocol CameraSessionDelegate: AnyObject {
Called when the [CameraSession] successfully initializes Called when the [CameraSession] successfully initializes
*/ */
func onSessionInitialized() func onSessionInitialized()
func onCameraConfigurationChanged(_ configuration: CameraConfiguration?, _ difference: CameraConfiguration.Difference?)
/** /**
Called when the [CameraSession] starts streaming frames. (isActive=true) Called when the [CameraSession] starts streaming frames. (isActive=true)
*/ */

View File

@ -32,6 +32,15 @@ extension AVCaptureOutput {
func setOrientation(_ orientation: Orientation) { func setOrientation(_ orientation: Orientation) {
// Set orientation for each connection // Set orientation for each connection
for connection in connections { for connection in connections {
connection.setOrientation(orientation)
}
}
}
extension AVCaptureConnection {
func setOrientation(_ orientation: Orientation) {
#if swift(>=5.9) #if swift(>=5.9)
if #available(iOS 17.0, *) { if #available(iOS 17.0, *) {
// Camera Sensors are always in landscape rotation (90deg). // Camera Sensors are always in landscape rotation (90deg).
@ -41,19 +50,18 @@ extension AVCaptureOutput {
// TODO: Don't rotate the video output because it adds overhead. Instead just use EXIF flags for the .mp4 file if recording. // TODO: Don't rotate the video output because it adds overhead. Instead just use EXIF flags for the .mp4 file if recording.
// Does that work when we flip the camera? // Does that work when we flip the camera?
if connection.isVideoRotationAngleSupported(degrees) { if isVideoRotationAngleSupported(degrees) {
connection.videoRotationAngle = degrees videoRotationAngle = degrees
} }
} else { } else {
if connection.isVideoOrientationSupported { if isVideoOrientationSupported {
connection.videoOrientation = orientation.toAVCaptureVideoOrientation() videoOrientation = orientation.toAVCaptureVideoOrientation()
} }
} }
#else #else
if connection.isVideoOrientationSupported { if isVideoOrientationSupported {
connection.videoOrientation = orientation.toAVCaptureVideoOrientation() videoOrientation = orientation.toAVCaptureVideoOrientation()
} }
#endif #endif
} }
} }
}

View File

@ -113,5 +113,19 @@ class ViewController: UIViewController {
} }
} }
override func viewWillTransition(to size: CGSize, with coordinator: any UIViewControllerTransitionCoordinator) {
switch UIDevice.current.orientation {
case .landscapeLeft:
cameraView.orientation = "landscape-right"
case .landscapeRight:
cameraView.orientation = "landscape-left"
default:
cameraView.orientation = "portrait"
}
cameraView.didSetProps([])
super.viewWillTransition(to: size, with: coordinator)
}
} }