AVFoundation-高帧率捕捉

以高帧率(FPS)捕捉视频内容带来很多好处

AVCaptureDeviceFormat实例具有 videoSupportedFrameRateRanges 属性,它包含一个AVFrameRateRange对象数组,其中带有格式所支持的最小帧率、最大帧率和时长信息。

确定是否支持高帧率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@implementation AVCaptureDevice (THAdditions)

//是否支持高帧率
- (BOOL)supportsHighFrameRateCapture {
if (![self hasMediaType:AVMediaTypeVideo]) { // 1
return NO;
}
return [self findHighestQualityOfService].isHighFrameRate; // 2
}

//查找设备所支持的帧率等信息
- (THQualityOfService *)findHighestQualityOfService {

AVCaptureDeviceFormat *maxFormat = nil;
AVFrameRateRange *maxFrameRateRange = nil;

for (AVCaptureDeviceFormat *format in self.formats) {

FourCharCode codecType = // 3
CMVideoFormatDescriptionGetCodecType(format.formatDescription);

if (codecType == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) { // 4

NSArray *frameRateRanges = format.videoSupportedFrameRateRanges;

for (AVFrameRateRange *range in frameRateRanges) { // 5
if (range.maxFrameRate > maxFrameRateRange.maxFrameRate) {
maxFormat = format;
maxFrameRateRange = range;
}
}
}
}

return [THQualityOfService qosWithFormat:maxFormat // 6
frameRateRange:maxFrameRateRange];

}
//开启高帧率
- (BOOL)enableMaxFrameRateCapture:(NSError **)error {

THQualityOfService *qos = [self findHighestQualityOfService];

if (!qos.isHighFrameRate) { // 1
if (error) {
NSString *message = @"Device does not support high FPS capture";
NSDictionary *userInfo = @{NSLocalizedDescriptionKey : message};

NSUInteger code = THCameraErrorHighFrameRateCaptureNotSupported;

*error = [NSError errorWithDomain:THCameraErrorDomain
code:code
userInfo:userInfo];
}
return NO;
}


if ([self lockForConfiguration:error]) { // 2

CMTime minFrameDuration = qos.frameRateRange.minFrameDuration;

self.activeFormat = qos.format; // 3
self.activeVideoMinFrameDuration = minFrameDuration; // 4
self.activeVideoMaxFrameDuration = minFrameDuration;

[self unlockForConfiguration];
return YES;
}
return NO;
}


@end

辅助类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@implementation THQualityOfService

+ (instancetype)qosWithFormat:(AVCaptureDeviceFormat *)format
frameRateRange:(AVFrameRateRange *)frameRateRange {

return [[self alloc] initWithFormat:format frameRateRange:frameRateRange];
}

- (instancetype)initWithFormat:(AVCaptureDeviceFormat *)format
frameRateRange:(AVFrameRateRange *)frameRateRange {
self = [super init];
if (self) {
_format = format;
_frameRateRange = frameRateRange;
}
return self;
}
//大于30就看成高帧率
- (BOOL)isHighFrameRate {
return self.frameRateRange.maxFrameRate > 30.0f;
}

@end