I have been using AVCaptureDevice
method set activeVideoMinFrameDuration
prior to the new iPhone 11 without any problems however testing the same code with the new iPhone 11 Pro max (Actual device), The app crashes with error message: -
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:-[AVCaptureDevice setActiveVideoMinFrameDuration:] Unsupported frame duration - use -activeFormat.videoSupportedFrameRateRanges to discover valid ranges
The same code works well with older phones. Actually I am using the exact sample code from Apple documentation
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 {
// Handle error.
}
}
}
As I have mentioned above this code works well with older devices but not iPhone 11 series (Tested on 11 Pro max).
Does anyone have a workaround or solution for this issue?
For anyone who will run into the same issue in the future. Here is what I did to fix the issue by following the debug error description.
// Important part: You must get the supported frame duration and use it to set max and min frame durations.
let supportedFrameRanges = device.activeFormat.videoSupportedFrameRateRanges.first
// Then use it, note that only fall back to bestFrameRateRange if supportedFrameRanges is nil.
device.activeVideoMinFrameDuration = supportedFrameRanges?.minFrameDuration ?? bestFrameRateRange.minFrameDuration
device.activeVideoMaxFrameDuration = supportedFrameRanges?.maxFrameDuration ?? bestFrameRateRange.maxFrameDuration