In this page - https://developer.apple.com/documentation/avfoundation/avcapturedevice at the note at the bottom of the page it says:
Directly configuring a capture device’s activeFormat property changes the capture session’s preset to inputPriority. 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.
Take a look at the following snippet:
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.
Post
Replies
Boosts
Views
Activity
This seems to be a pretty weird issue. I'm following along with a SpriteKit tutorial, and while I can build my project and run it on my phone, I keep getting this error in the IDE: Cannot load underlying module for SpriteKit
It says it cannot load the module but that's weird because SpriteKit should be a native framework that must've been installed with my XCode.
It is pretty annoying because XCode is not context-aware, and code completion doesn't work for any object that's derived from SpriteKit.
Here's my system info: XCode version: Version 12.0 (12A7209)
MacOS version: MacOS Catalina 10.15.7 (19H2)
Is this a bug in XCode?