Compare commits
	
		
			5 Commits
		
	
	
		
			ivan/fix-a
			...
			695e317a77
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 695e317a77 | ||
|  | 5e8f7055e2 | ||
|  | 031aa9d43a | ||
| fcf5fe70f3 | |||
|  | 3a20c44a31 | 
| @@ -16,7 +16,7 @@ buildscript { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   dependencies { |   dependencies { | ||||||
|     classpath "com.android.tools.build:gradle:7.4.2" |     classpath "com.android.tools.build:gradle:8.5.2" | ||||||
|     classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |     classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||||||
|   } |   } | ||||||
| } | } | ||||||
| @@ -133,8 +133,8 @@ android { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   compileOptions { |   compileOptions { | ||||||
|     sourceCompatibility JavaVersion.VERSION_1_8 |     sourceCompatibility JavaVersion.VERSION_17 | ||||||
|     targetCompatibility JavaVersion.VERSION_1_8 |     targetCompatibility JavaVersion.VERSION_17 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   externalNativeBuild { |   externalNativeBuild { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android" | <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||||||
|           package="com.mrousavy.camera"> |  | ||||||
|  |  | ||||||
| </manifest> | </manifest> | ||||||
|   | |||||||
| @@ -7,12 +7,14 @@ import com.facebook.jni.HybridData | |||||||
| import com.facebook.proguard.annotations.DoNotStrip | import com.facebook.proguard.annotations.DoNotStrip | ||||||
| import com.facebook.react.bridge.ReactApplicationContext | import com.facebook.react.bridge.ReactApplicationContext | ||||||
| import com.facebook.react.bridge.UiThreadUtil | import com.facebook.react.bridge.UiThreadUtil | ||||||
|  | import com.facebook.react.common.annotations.FrameworkAPI | ||||||
| import com.facebook.react.turbomodule.core.CallInvokerHolderImpl | import com.facebook.react.turbomodule.core.CallInvokerHolderImpl | ||||||
| import com.facebook.react.uimanager.UIManagerHelper | import com.facebook.react.uimanager.UIManagerHelper | ||||||
| import com.mrousavy.camera.CameraView | import com.mrousavy.camera.CameraView | ||||||
| import com.mrousavy.camera.core.ViewNotFoundError | import com.mrousavy.camera.core.ViewNotFoundError | ||||||
| import java.lang.ref.WeakReference | import java.lang.ref.WeakReference | ||||||
|  |  | ||||||
|  | @OptIn(FrameworkAPI::class) | ||||||
| @Suppress("KotlinJniMissingFunction") // we use fbjni. | @Suppress("KotlinJniMissingFunction") // we use fbjni. | ||||||
| class VisionCameraProxy(private val reactContext: ReactApplicationContext) { | class VisionCameraProxy(private val reactContext: ReactApplicationContext) { | ||||||
|   companion object { |   companion object { | ||||||
|   | |||||||
| @@ -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 { | ||||||
|   | |||||||
| @@ -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 { | ||||||
|   | |||||||
| @@ -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) | ||||||
|    */ |    */ | ||||||
|   | |||||||
| @@ -32,28 +32,36 @@ 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 { | ||||||
|       #if swift(>=5.9) |       connection.setOrientation(orientation) | ||||||
|         if #available(iOS 17.0, *) { |  | ||||||
|           // Camera Sensors are always in landscape rotation (90deg). |  | ||||||
|           // We are setting the target rotation here, so we need to rotate by landscape once. |  | ||||||
|           let cameraOrientation = orientation.rotateBy(orientation: .landscapeLeft) |  | ||||||
|           let degrees = cameraOrientation.toDegrees() |  | ||||||
|  |  | ||||||
|           // 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? |  | ||||||
|           if connection.isVideoRotationAngleSupported(degrees) { |  | ||||||
|             connection.videoRotationAngle = degrees |  | ||||||
|           } |  | ||||||
|         } else { |  | ||||||
|           if connection.isVideoOrientationSupported { |  | ||||||
|             connection.videoOrientation = orientation.toAVCaptureVideoOrientation() |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       #else |  | ||||||
|         if connection.isVideoOrientationSupported { |  | ||||||
|           connection.videoOrientation = orientation.toAVCaptureVideoOrientation() |  | ||||||
|         } |  | ||||||
|       #endif |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | extension AVCaptureConnection { | ||||||
|  |   func setOrientation(_ orientation: Orientation) { | ||||||
|  |     #if swift(>=5.9) | ||||||
|  |       if #available(iOS 17.0, *) { | ||||||
|  |         // Camera Sensors are always in landscape rotation (90deg). | ||||||
|  |         // We are setting the target rotation here, so we need to rotate by landscape once. | ||||||
|  |         let cameraOrientation = orientation.rotateBy(orientation: .landscapeLeft) | ||||||
|  |         let degrees = cameraOrientation.toDegrees() | ||||||
|  |  | ||||||
|  |         // 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? | ||||||
|  |         if isVideoRotationAngleSupported(degrees) { | ||||||
|  |           videoRotationAngle = degrees | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         if isVideoOrientationSupported { | ||||||
|  |           videoOrientation = orientation.toAVCaptureVideoOrientation() | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     #else | ||||||
|  |       if isVideoOrientationSupported { | ||||||
|  |         videoOrientation = orientation.toAVCaptureVideoOrientation() | ||||||
|  |       } | ||||||
|  |     #endif | ||||||
|  |   } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -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) | ||||||
|  |   } | ||||||
|  |    | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user