Reputation: 11
I'm working on an iOS app using AVFoundation to handle real time video capture and object detection. However, I’ve encountered a frustrating issue when switching between the Wide and Ultra Wide cameras while the torch is ON.
Issue:
Current Code (Torch + Camera Switch)
@IBAction func ultrawideCameraTapped(_ sender: Any?) {
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else { return }
let isSwitchingToUltraWide = !self.isUsingFisheyeCamera
let cameraType: AVCaptureDevice.DeviceType = isSwitchingToUltraWide ? .builtInUltraWideCamera : .builtInWideAngleCamera
let cameraName = isSwitchingToUltraWide ? "Ultra Wide" : "Wide"
guard let selectedCamera = AVCaptureDevice.default(cameraType, for: .video, position: .back) else {
DispatchQueue.main.async {
self.showAlert(title: "Camera Error", message: "\(cameraName) camera is not available on this device.")
}
return
}
do {
let currentInput = self.videoCapture.captureSession.inputs.first as? AVCaptureDeviceInput
self.videoCapture.captureSession.beginConfiguration()
// If switching to Ultra-Wide with Torch ON, attempt workaround
if isSwitchingToUltraWide && self.isFlashlightOn {
self.forceEnableTorchThroughWide()
}
if let currentInput = currentInput {
self.videoCapture.captureSession.removeInput(currentInput)
}
let videoInput = try AVCaptureDeviceInput(device: selectedCamera)
self.videoCapture.captureSession.addInput(videoInput)
self.videoCapture.captureSession.commitConfiguration()
self.videoCapture.updateVideoOrientation()
DispatchQueue.main.async {
if let barButton = sender as? UIBarButtonItem {
barButton.title = isSwitchingToUltraWide ? "Wide" : "Ultra Wide"
barButton.tintColor = isSwitchingToUltraWide ? UIColor.systemGreen : UIColor.white
}
print("Switched to \(cameraName) camera.")
}
self.isUsingFisheyeCamera.toggle()
} catch {
DispatchQueue.main.async {
self.showAlert(title: "Camera Error", message: "Failed to switch to \(cameraName) camera: \(error.localizedDescription)")
}
}
}
}
func forceEnableTorchThroughWide() {
DispatchQueue.global(qos: .userInitiated).async {
guard let wideCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, position: .back), wideCamera.hasTorch else {
DispatchQueue.main.async {
self.showAlert(title: "Torch Error", message: "Torch is not available on this device.")
}
return
}
do {
try wideCamera.lockForConfiguration()
wideCamera.torchMode = .on
self.isFlashlightOn = true
wideCamera.unlockForConfiguration()
} catch {
DispatchQueue.main.async {
self.showAlert(title: "Torch Error", message: "Error while forcing torch through Wide Camera: \(error.localizedDescription)")
}
}
}
}
Upvotes: 1
Views: 50