From 9ec31def92b2557b046bad93748b04f77030b9bd Mon Sep 17 00:00:00 2001 From: Michael Wolz Date: Thu, 6 Jun 2024 17:10:53 +0200 Subject: [PATCH] fix(ios): use native camera selection for optimal focus The CameraController now prioritizes `builtInTripleCamera` and similar options to select the best fitting camera. This enhances continuous auto-focus on newer iPhones, especially Pro models. Closes: capacitor-community/camera-preview#324 Addresses: capacitor-community/camera-preview#256 --- ios/Plugin/CameraController.swift | 43 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/ios/Plugin/CameraController.swift b/ios/Plugin/CameraController.swift index a09e72a0..795e5e21 100644 --- a/ios/Plugin/CameraController.swift +++ b/ios/Plugin/CameraController.swift @@ -45,25 +45,29 @@ extension CameraController { } func configureCaptureDevices() throws { - - let session = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .unspecified) - - let cameras = session.devices.compactMap { $0 } - guard !cameras.isEmpty else { throw CameraControllerError.noCamerasAvailable } - - for camera in cameras { - if camera.position == .front { - self.frontCamera = camera - } - - if camera.position == .back { - self.rearCamera = camera - - try camera.lockForConfiguration() - camera.focusMode = .continuousAutoFocus - camera.unlockForConfiguration() - } - } + // For the front camera we are simply using the default one. iOS will automatically provide the best fit here + self.frontCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: AVMediaType.video, position: .front) + + // For the rear camera we'll use a discovery session that will follow the list of "best" cameras to choose from + let deviceTypes: [AVCaptureDevice.DeviceType] = [ + .builtInTripleCamera, + .builtInDualWideCamera, + .builtInDualCamera, + .builtInWideAngleCamera, + ] + + let discoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: deviceTypes, mediaType: AVMediaType.video, position: .back) + + // We then define the first camera as rear camera. The devices are already sorted based on the provided device types + // See: https://developer.apple.com/documentation/avfoundation/capture_setup/choosing_a_capture_device#2958877 + guard let rearCamera = discoverySession.devices.first else { throw CameraControllerError.noCamerasAvailable } + + try rearCamera.lockForConfiguration() + rearCamera.focusMode = .continuousAutoFocus + rearCamera.unlockForConfiguration() + + self.rearCamera = rearCamera + if disableAudio == false { self.audioDevice = AVCaptureDevice.default(for: AVMediaType.audio) } @@ -138,7 +142,6 @@ extension CameraController { try configureDeviceInputs() try configurePhotoOutput() try configureDataOutput() - // try configureVideoOutput() } catch { DispatchQueue.main.async { completionHandler(error)