capacitor-community-multilens-camerapreview 7.0.0 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  // Plugin
4
4
  //
5
5
  // Created by Ariel Hernandez Musa on 7/14/19.
6
- // Copyright © 2019 Max Lynch. All rights reserved.
6
+ // Modified by Pete Kraguljac on 11/5/2025
7
7
  //
8
8
 
9
9
  import AVFoundation
@@ -192,10 +192,18 @@ extension CameraController {
192
192
  }
193
193
 
194
194
  func updateVideoOrientation() {
195
- assert(Thread.isMainThread) // UIApplication.statusBarOrientation requires the main thread.
195
+ assert(Thread.isMainThread)
196
+
197
+ // Prefer the interfaceOrientation from the active window scene (iOS 13+)
198
+ let interfaceOrientation: UIInterfaceOrientation = (
199
+ UIApplication.shared.connectedScenes
200
+ .compactMap { $0 as? UIWindowScene }
201
+ .first(where: { $0.activationState == .foregroundActive })?
202
+ .interfaceOrientation
203
+ ) ?? UIApplication.shared.windows.first?.windowScene?.interfaceOrientation ?? .portrait
196
204
 
197
205
  let videoOrientation: AVCaptureVideoOrientation
198
- switch UIApplication.shared.statusBarOrientation {
206
+ switch interfaceOrientation {
199
207
  case .portrait:
200
208
  videoOrientation = .portrait
201
209
  case .landscapeLeft:
@@ -204,9 +212,7 @@ extension CameraController {
204
212
  videoOrientation = .landscapeRight
205
213
  case .portraitUpsideDown:
206
214
  videoOrientation = .portraitUpsideDown
207
- case .unknown:
208
- fallthrough
209
- @unknown default:
215
+ default:
210
216
  videoOrientation = .portrait
211
217
  }
212
218
 
@@ -395,19 +401,22 @@ extension CameraController {
395
401
 
396
402
  }
397
403
  func getSupportedCameras() throws -> [String] {
398
- var supportedCameras: [String] = [];
399
- if let device = AVCaptureDevice.default(.builtInUltraWideCamera, for: AVMediaType.video, position: .back) {
404
+ var supportedCameras: [String] = []
405
+
406
+ if AVCaptureDevice.default(.builtInUltraWideCamera, for: .video, position: .back) != nil {
400
407
  supportedCameras.append("ultra")
401
408
  }
402
- if let device = AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .back) {
409
+ if AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back) != nil {
403
410
  supportedCameras.append("wide")
404
411
  }
405
- if let device = AVCaptureDevice.default(.builtInTelephotoCamera, for: AVMediaType.video, position: .back) {
412
+ if AVCaptureDevice.default(.builtInTelephotoCamera, for: .video, position: .back) != nil {
406
413
  supportedCameras.append("tele")
407
414
  }
408
- return supportedCameras;
415
+
416
+ return supportedCameras
409
417
  }
410
418
 
419
+
411
420
  func setFlashMode(flashMode: AVCaptureDevice.FlashMode) throws {
412
421
  var currentCamera: AVCaptureDevice?
413
422
  switch currentCameraPosition {
@@ -568,17 +577,32 @@ extension CameraController: UIGestureRecognizerDelegate {
568
577
  }
569
578
 
570
579
  extension CameraController: AVCapturePhotoCaptureDelegate {
571
- public func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
572
- resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Swift.Error?) {
573
- if let error = error { self.photoCaptureCompletionBlock?(nil, error) } else if let buffer = photoSampleBuffer, let data = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: buffer, previewPhotoSampleBuffer: nil),
574
- let image = UIImage(data: data) {
580
+
581
+ public func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
582
+ if let error = error {
583
+ self.photoCaptureCompletionBlock?(nil, error)
584
+ return
585
+ }
586
+
587
+ // Prefer modern data extraction
588
+ if let data = photo.fileDataRepresentation(),
589
+ let image = UIImage(data: data) {
575
590
  self.photoCaptureCompletionBlock?(image.fixedOrientation(), nil)
576
- } else {
577
- self.photoCaptureCompletionBlock?(nil, CameraControllerError.unknown)
591
+ return
592
+ }
593
+
594
+ // Fallback to cgImageRepresentation if available
595
+ if let cgImage = photo.cgImageRepresentation() {
596
+ let image = UIImage(cgImage: cgImage)
597
+ self.photoCaptureCompletionBlock?(image.fixedOrientation(), nil)
598
+ return
578
599
  }
600
+
601
+ self.photoCaptureCompletionBlock?(nil, CameraControllerError.unknown)
579
602
  }
580
603
  }
581
604
 
605
+
582
606
  extension CameraController: AVCaptureVideoDataOutputSampleBufferDelegate {
583
607
  func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
584
608
  guard let completion = sampleBufferCaptureCompletionBlock else { return }
@@ -697,12 +721,14 @@ extension UIImage {
697
721
  // Flip image one more time if needed to, this is to prevent flipped image
698
722
  switch imageOrientation {
699
723
  case .upMirrored, .downMirrored:
700
- transform.translatedBy(x: size.width, y: 0)
701
- transform.scaledBy(x: -1, y: 1)
724
+ transform = transform.translatedBy(x: size.width, y: 0)
725
+ transform = transform.scaledBy(x: -1, y: 1)
726
+ transform = transform.scaledBy(x: -1, y: 1)
702
727
  break
703
728
  case .leftMirrored, .rightMirrored:
704
- transform.translatedBy(x: size.height, y: 0)
705
- transform.scaledBy(x: -1, y: 1)
729
+ transform = transform.translatedBy(x: size.height, y: 0)
730
+ transform = transform.scaledBy(x: -1, y: 1)
731
+ transform = transform.scaledBy(x: -1, y: 1)
706
732
  case .up, .down, .left, .right:
707
733
  break
708
734
  }
@@ -730,3 +756,4 @@ extension CameraController: AVCaptureFileOutputRecordingDelegate {
730
756
  }*/
731
757
  }
732
758
  }
759
+
@@ -24,15 +24,40 @@ public class CameraPreviewMultiLens: CAPPlugin {
24
24
  var disableAudio: Bool = false
25
25
  var zoomFactor = String()
26
26
 
27
+ private func currentInterfaceOrientation() -> UIInterfaceOrientation? {
28
+ if let window = self.webView?.window ?? self.bridge?.viewController?.view.window {
29
+ return window.windowScene?.interfaceOrientation
30
+ }
31
+ // Fallback to device orientation mapping
32
+ let deviceOrientation = UIDevice.current.orientation
33
+ switch deviceOrientation {
34
+ case .landscapeLeft: return .landscapeRight // device vs interface are mirrored
35
+ case .landscapeRight: return .landscapeLeft
36
+ case .portrait: return .portrait
37
+ case .portraitUpsideDown: return .portraitUpsideDown
38
+ default: return nil
39
+ }
40
+ }
41
+
27
42
  @objc func rotated() {
28
43
  let height = self.paddingBottom != nil ? self.height! - self.paddingBottom!: self.height!
29
44
 
30
- if UIApplication.shared.statusBarOrientation.isLandscape {
45
+ // Determine orientation without using deprecated statusBarOrientation and without relying on missing viewController
46
+ let orientation = self.currentInterfaceOrientation()
47
+ let isLandscape: Bool
48
+ if let orientation = orientation {
49
+ isLandscape = orientation.isLandscape
50
+ } else {
51
+ // Default to portrait when unknown
52
+ isLandscape = false
53
+ }
54
+
55
+ if isLandscape {
31
56
  self.previewView.frame = CGRect(x: self.y!, y: self.x!, width: max(height, self.width!), height: min(height, self.width!))
32
57
  self.cameraController.previewLayer?.frame = self.previewView.frame
33
58
  }
34
59
 
35
- if UIApplication.shared.statusBarOrientation.isPortrait {
60
+ if !isLandscape {
36
61
  if self.previewView != nil && self.x != nil && self.y != nil && self.width != nil && self.height != nil {
37
62
  self.previewView.frame = CGRect(x: self.x!, y: self.y!, width: min(height, self.width!), height: max(height, self.width!))
38
63
  }
@@ -102,6 +127,10 @@ public class CameraPreviewMultiLens: CAPPlugin {
102
127
 
103
128
  if self.rotateWhenOrientationChanged == true {
104
129
  NotificationCenter.default.addObserver(self, selector: #selector(CameraPreviewMultiLens.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
130
+ if let scene = self.webView?.window?.windowScene ?? self.bridge?.viewController?.view.window?.windowScene {
131
+ NotificationCenter.default.addObserver(self, selector: #selector(CameraPreviewMultiLens.rotated), name: UIWindowScene.willEnterForegroundNotification, object: scene)
132
+ NotificationCenter.default.addObserver(self, selector: #selector(CameraPreviewMultiLens.rotated), name: UIWindowScene.didActivateNotification, object: scene)
133
+ }
105
134
  }
106
135
 
107
136
  call.resolve()
@@ -197,7 +226,7 @@ public class CameraPreviewMultiLens: CAPPlugin {
197
226
  }
198
227
 
199
228
  let imageData: Data?
200
- if self.cameraPosition == "front" {
229
+ if self.cameraController.currentCameraPosition == .front {
201
230
  let flippedImage = image.withHorizontallyFlippedOrientation()
202
231
  imageData = flippedImage.jpegData(compressionQuality: CGFloat(quality!/100))
203
232
  } else {
@@ -278,7 +307,7 @@ public class CameraPreviewMultiLens: CAPPlugin {
278
307
  @objc func startRecordVideo(_ call: CAPPluginCall) {
279
308
  DispatchQueue.main.async {
280
309
 
281
- let quality: Int? = call.getInt("quality", 85)
310
+ let _ = call.getInt("quality", 85)
282
311
 
283
312
  self.cameraController.captureVideo { (image, error) in
284
313
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-community-multilens-camerapreview",
3
- "version": "7.0.0",
3
+ "version": "7.1.0",
4
4
  "description": "fork of capacitor community camera preview with support for switchting lenses",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",