在iOS 5中使用AVFoundation设置最大帧率

18

我相信以前可以使用 captureOutput.minFrameDuration 来完成此操作。然而,在 iOS 5 中已经过时。

相反,我似乎需要使用 AVCaptureConnectionvideo.minFrameDuration。所以我有了输入和输出,我将它们都添加到捕获会话中-我在哪里可以获取捕获连接的访问权限?我认为它是由会话为我创建的,但是在哪里呢?

我可以尝试使用 addInputWithNoConnectionsaddOutputWithNoConnections 添加 I/O ,然后手动创建连接。但这似乎有点麻烦,只是为了设置最大帧率。而且,Xcode 抱怨这些方法不存在。

4个回答

28

Chris,我想我已经解决了这个问题:

(编辑 - 请查看Tomas Camin在下面的评论中有关检查videoMinFrameDuration和videoMaxFrameDuration是否受支持的正确方法,尽管下面的代码在发布时运行良好)

以下代码可访问与AVCaptureVideoDataOutput对象相关联的AVCaptureConnection对象:

AVCaptureConnection *conn = [output connectionWithMediaType:AVMediaTypeVideo];


CMTimeShow(conn.videoMinFrameDuration);
CMTimeShow(conn.videoMaxFrameDuration);

if (conn.isVideoMinFrameDurationSupported)
    conn.videoMinFrameDuration = CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND);
if (conn.isVideoMaxFrameDurationSupported)
    conn.videoMaxFrameDuration = CMTimeMake(1, CAPTURE_FRAMES_PER_SECOND);

CMTimeShow(conn.videoMinFrameDuration);
CMTimeShow(conn.videoMaxFrameDuration);
如果你正在使用(就像我一样),didOutputSampleBuffer代理,你可以确认传递给代理的fromConnectionAVCaptureConnection*值中的视频帧速率已经被正确设置并且被上面的代码“记住”了。
请注意,为了成功地夹住帧速率,您需要同时设置videoMinFrameDurationvideoMaxFrameDuration两个属性的值,并将它们设置为相同的值——只设置最小值在iPhone 4s上测试时似乎不起作用。这似乎没有被记录在文档中。
Josh

太棒了!谢谢Josh。我还发现在iPhone 4和4S上都需要设置videoMinFrameDuration和videoMaxFrameDuration。 - chris838
我真希望能给你10分!旧的弃用方法在4.3中仍然有效,我在找到这个线程之前浪费了很多时间!如果有人想要复制它,我只是一个关于此问题的错误报告:Bug ID#10524664。 - David H
请注意,检查videoMinFrameDurationvideoMaxFrameDuration是否受支持的正确方法是使用[AVCaptureConnection isVideoMinFrameDurationSupported][AVCaptureConnection isVideoMaxFrameDurationSupported] - Tomas Camin
2
我正在使用iOS SDK 5.1:[AVCaptureConnection isVideoMinFrameDurationSupported][AVCaptureConnection isVideoMaxFrameDurationSupported]不存在,而是属性conn.isVideoMinFrameDurationSupportedconn.isVideoMaxFrameDurationSupported - Andrew
还要注意,在将其添加到会话后,必须设置activeVideoMinFrameDurationactiveVideoMaxFrameDuration。请参见https://dev59.com/E5Lea4cB1Zd3GeqP8ORH#34720352。 - Rob

5

AVCaptureConnectionvideoMinFrameDuration已经被废弃。请使用AVCaptureDeviceactiveVideoMinFrameDuration/activeVideoMaxFrameDuration。在AVCaptureDevice类参考中,第一个代码片段回答了这个问题。


AVCaptureConnection的videoMinFrameDuration在OS X 10.9上可以正常工作,没有警告。 - kareman
@KareMorstol 这个问题的标题和标签都是 ios。不是 osx。因此这是一个特定于 ios 的答案。更多信息请参考SO上的这个问题。 - kiranpradeep

2
假设有以下成员。
AVCaptureConnection         *videoConnection;
AVCaptureVideoDataOutput    *videoOutput;
AVCaptureDeviceInput        *videoInput;

那么你需要做类似以下的操作。我没有进行过测试,这只是根据文档的猜测。

AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];   

if ( videoDevice ) {
    NSError *error;
    videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error]; 

    [captureSession addInput:videoInput];   
}

videoOutput = [[AVCaptureVideoDataOutput alloc] init];
//setup video options
if ([captureSession canAddOutput:videoOutput])
    [captureSession addOutput:videoOutput];

videoConnection = [[AVCaptureConnection alloc] initWithInputPorts:captureSession.inputs output:videoOutput];
videoConnection.videoMinFrameDuration = CMTimeMake(1, frameRate);

[captureSession addConnection:videoConnection];

我还没有将自己的代码转换为这种方式。当我完成转换后,我会回复您并提供可运行的代码。如果您在captureSession中添加了多个输入,则可能需要将要使用的输入显式加载到数组中。例如:

ports = [NSArray arrayWithObject:videoInput];

然后将其传递到AVCaptureConnection的初始化程序中。

谢谢Steve,我的编译器在AVCaptureConnection的initWithInputPorts上报错了。 - chris838
我不确定为什么。我正在参考AVCaptureConnection文档。正如我所说,我没有测试过这段代码。我只是通过查看文档来“盲写”的。joshgreifer似乎有一个更简洁的解决方案。AVCaptureVideoDataOutput继承自AVCaptureOutput,后者具有connectionWithMediaType消息。 - Steve McFarlin
1
@chris838 它在抱怨 initWithInputPorts,因为该方法仅适用于 Mac OS X v10.7 及更高版本。 - Tomas Camin

0
如Kiran所提到的,自iOS 7以来,AVCaptureConnection videoMinFrameDuration已被弃用。
更具体地说,是“更新”Apple的示例
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

AVCaptureDeviceInput *input = ... // Following the example

// ** Create and Configure the Video Data Output **
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];

[session addOutput:output];

output.videoSettings = @{
                             (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA)
                             };

device.activeVideoMinFrameDuration = CMTimeMake(1, 15);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接