我正在实施一项功能,该功能将解析AVCaptureDeviceFormat
类型AVCaptureDevice
中所有可用的AVMediaTypeVideo
个对象。
代码的作用是查看每种格式的最大帧速率使用帧速率的字符串版本作为字典的键。例如,在iPhone 5s上,我最终会得到一个带有键的字典" 30"," 60"和" 120"。这些密钥的对象是AVCaptureDevice格式,它们对应于每个帧速率,并且对于每个帧速率具有最佳分辨率。
这是执行此操作的代码:
for (AVCaptureDeviceFormat *format in self.videoDevice.formats) {
CMFormatDescriptionRef formatDescription = format.formatDescription;
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);
FourCharCode mediaSubType = CMFormatDescriptionGetMediaSubType(formatDescription);
BOOL fullRange = NO;
/// We want only the formats with full range, so we use a bool to select for those.
switch (mediaSubType) {
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
fullRange = NO;
break;
case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
fullRange = YES;
break;
default:
NSLog(@"Unknown media subtype encountered in format: %@", format);
break;
}
for (AVFrameRateRange *range in format.videoSupportedFrameRateRanges) {
NSUInteger maxFrameRate = (NSUInteger)range.maxFrameRate;
NSString *maxFrameRateAsString = [NSString stringWithFormat:@"%lu", (unsigned long)maxFrameRate];
if (![self.fpsOptions objectForKey:maxFrameRateAsString]) {
[self.fpsOptions setObject:format forKey: maxFrameRateAsString];
} else {
AVCaptureDeviceFormat *bestFormatForCurrentFrameRate = [self.fpsOptions objectForKey:maxFrameRateAsString];
CMFormatDescriptionRef bestFDR = bestFormatForCurrentFrameRate.formatDescription;
CMVideoDimensions bestDimensions = CMVideoFormatDescriptionGetDimensions(bestFDR);
/// We need to stop the 30 FPS setting from going above 1080 or app crashes when trying to save
/// the video. Despite indications to the contrary, 2k+ resolutions are not valid video formats
/// at least on an iPhone 5s.
if (dimensions.height > bestDimensions.height && dimensions.height <= 1080 && fullRange == YES) {
bestFormatForCurrentFrameRate = format;
[self.fpsOptions setObject:bestFormatForCurrentFrameRate forKey:maxFrameRateAsString];
/// The following lines are necessary because in 240 fps capable devices, there isn't a dedicated 120 fps format. Per Apple's documentation, to record at 120, use a 240 fps format and manually set the frame duration (this is done in the changeFPS method).
if (maxFrameRate == 240) {
[self.fpsOptions setObject:bestFormatForCurrentFrameRate forKey:@"120"];
}
}
}
}
}
问题:混合使用视频格式是伪装的照片格式。例如,在我的iPhone 5s上,阵列中包含的格式列出30 fps作为最大帧速率,分辨率为2592x1936。如果我尝试使用这种格式来录制视频,应用程序会崩溃,因为[我认为]这些格式实际上是用于在录制视频时捕获高分辨率静止图像(内置摄像头应用程序中的功能)。
问题在于没有明显的方法来区分这些照片格式和实际的视频格式(据我所知)。因此,如果查看上面的代码,我只需将有效分辨率限制为1080。
到目前为止,我发现的唯一可行的是
- isVideoStabilizationModeSupported:
返回的值。并测试几种不同的稳定模式。这甚至是一种可靠的方法吗?有没有更好的方法呢?目标是使该代码尽可能动态,以便让用户能够访问其设备能够的所有可用视频帧速率并以每个帧速率组内的最佳分辨率进行记录。