This is not true, I have to set the capture session's preset to input priority for the captured device's configuration to take place.Directly configuring a capture device’s activeFormat property changes the capture session’s preset to inputPriority.
Take a look at the following snippet:
Code Block import SwiftUI import AVFoundation struct CustomCameraView: UIViewRepresentable { func makeUIView(context: Context) -> some UIView { let previewView = UIImageView() func configureCameraForHighestFrameRate(device: AVCaptureDevice) { var bestFormat: AVCaptureDevice.Format? var bestFrameRateRange: AVFrameRateRange? for format in device.formats { for range in format.videoSupportedFrameRateRanges { if range.maxFrameRate > bestFrameRateRange?.maxFrameRate ?? 0 { bestFormat = format bestFrameRateRange = range } } } if let bestFormat = bestFormat, let bestFrameRateRange = bestFrameRateRange { do { try device.lockForConfiguration() // Set the device's active format. device.activeFormat = bestFormat // Set the device's min/max frame duration. let duration = bestFrameRateRange.minFrameDuration device.activeVideoMinFrameDuration = duration device.activeVideoMaxFrameDuration = duration device.unlockForConfiguration() } catch { print("error getting max framerate") // Handle error. } } } func setupLivePreview() { videoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession) videoPreviewLayer.videoGravity = .resizeAspect videoPreviewLayer.connection?.videoOrientation = .portrait previewView.layer.addSublayer(videoPreviewLayer) captureSession.commitConfiguration() DispatchQueue.global(qos: .userInitiated).async { captureSession.startRunning() DispatchQueue.main.async { videoPreviewLayer.frame = previewView.bounds } } } var captureSession: AVCaptureSession! // var videoOutput: AVCaptureVideoDataOutput! var videoPreviewLayer: AVCaptureVideoPreviewLayer! captureSession = AVCaptureSession() captureSession.beginConfiguration() captureSession.sessionPreset = .inputPriority guard let backCamera = AVCaptureDevice.default(for: AVMediaType.video) else { print("Unable to access back camera!") return UIImageView() } configureCameraForHighestFrameRate(device: backCamera) do { let input = try AVCaptureDeviceInput(device: backCamera) // videoOutput = AVCaptureVideoDataOutput() print("max frame duration on input", input.device.activeVideoMaxFrameDuration) // if captureSession.canAddInput(input) && captureSession.canAddOutput(videoOutput) { if captureSession.canAddInput(input) { captureSession.addInput(input) setupLivePreview() } } catch let error { print("Error Unable to initialize back camera: \(error.localizedDescription)") } return previewView } func updateUIView(_ uiView: UIViewType, context: Context) { } }
If I don't manually set the captureSession.sessionPreset to .inputPriority, my captured FPS will be the default, and setting device.activeVideoMinFrameDuration and device.activeVideoMaxFrameDuration won't have any effects.
Looks like the documentation on this is wrong.