2023-10-13 10:33:20 -06:00
|
|
|
//
|
|
|
|
// CameraSession+Focus.swift
|
|
|
|
// VisionCamera
|
|
|
|
//
|
|
|
|
// Created by Marc Rousavy on 11.10.23.
|
|
|
|
// Copyright © 2023 mrousavy. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import AVFoundation
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
extension CameraSession {
|
|
|
|
/**
|
|
|
|
Focuses the Camera to the specified point. The point must be in the Camera coordinate system, so {0...1} on both axis.
|
|
|
|
*/
|
|
|
|
func focus(point: CGPoint) throws {
|
|
|
|
guard let device = videoDeviceInput?.device else {
|
|
|
|
throw CameraError.session(SessionError.cameraNotReady)
|
|
|
|
}
|
|
|
|
if !device.isFocusPointOfInterestSupported {
|
|
|
|
throw CameraError.device(DeviceError.focusNotSupported)
|
|
|
|
}
|
|
|
|
|
2023-11-27 06:43:56 -07:00
|
|
|
ReactLogger.log(level: .info, message: "Focusing (\(point.x), \(point.y))...")
|
|
|
|
|
2023-10-13 10:33:20 -06:00
|
|
|
do {
|
|
|
|
try device.lockForConfiguration()
|
|
|
|
defer {
|
|
|
|
device.unlockForConfiguration()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set Focus
|
|
|
|
if device.isFocusPointOfInterestSupported {
|
|
|
|
device.focusPointOfInterest = point
|
|
|
|
device.focusMode = .autoFocus
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set Exposure
|
|
|
|
if device.isExposurePointOfInterestSupported {
|
|
|
|
device.exposurePointOfInterest = point
|
|
|
|
device.exposureMode = .autoExpose
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove any existing listeners
|
|
|
|
NotificationCenter.default.removeObserver(self,
|
|
|
|
name: NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange,
|
|
|
|
object: nil)
|
|
|
|
|
|
|
|
// Listen for focus completion
|
|
|
|
device.isSubjectAreaChangeMonitoringEnabled = true
|
|
|
|
NotificationCenter.default.addObserver(self,
|
|
|
|
selector: #selector(subjectAreaDidChange),
|
|
|
|
name: NSNotification.Name.AVCaptureDeviceSubjectAreaDidChange,
|
|
|
|
object: nil)
|
|
|
|
} catch {
|
|
|
|
throw CameraError.device(DeviceError.configureError)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@objc
|
|
|
|
func subjectAreaDidChange(notification _: NSNotification) {
|
|
|
|
guard let device = videoDeviceInput?.device else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
try? device.lockForConfiguration()
|
|
|
|
defer {
|
|
|
|
device.unlockForConfiguration()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset Focus to continuous/auto
|
|
|
|
if device.isFocusPointOfInterestSupported {
|
|
|
|
device.focusMode = .continuousAutoFocus
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset Exposure to continuous/auto
|
|
|
|
if device.isExposurePointOfInterestSupported {
|
|
|
|
device.exposureMode = .continuousAutoExposure
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disable listeners
|
|
|
|
device.isSubjectAreaChangeMonitoringEnabled = false
|
|
|
|
}
|
|
|
|
}
|