我正在使用canAddOutput:
确定我是否可以向AVCaptureMovieFileOutput
添加AVCaptureSession
,并且我发现canAddOutput:
有时会返回NO,并且大部分都返回YES 。有没有办法找出NO被归还的原因?或者一种消除导致NO返回的情况的方法?或者我能做的任何事情都会阻止用户看到间歇性故障?
进一步说明:这种情况大约发生在30次通话中。由于我的应用程序尚未启动,因此仅在一台设备上进行了测试:运行7.1.2的iPhone 5
答案 0 :(得分:13)
以下是文档引用(canAddOutput:
)的讨论
You cannot add an output that reads from a track of an asset other than the asset used to initialize the receiver.
对您有帮助的说明(请检查您的代码是否与本指南匹配,如果您做得不好,则不应触发错误,因为基本上canAddOuput:
会检查兼容性)。
<强> AVCaptureSession 强>
用于组织设备输入和输出之间的连接,类似于DShow过滤器的连接。如果可以连接输入和输出,则在启动后,数据将从输入读取到输出。
几个要点:
a)AVCaptureDevice,设备的定义,两个摄像头设备
b)AVCaptureInput
c)AVCaptureOutput
输入和输出不是一对一的,例如视频+音频输入时的视频输出。
切换相机前后:
AVCaptureSession * session = <# A capture session #>;
[session beginConfiguration];
[session removeInput: frontFacingCameraDeviceInput];
[session addInput: backFacingCameraDeviceInput];
[session commitConfiguration];
添加捕获INPUT:
要将捕获设备添加到捕获会话,请使用AVCaptureDeviceInput的实例(具体的
抽象AVCaptureInput类的子类)。捕获设备输入管理设备的端口。
NSError * error = nil;
AVCaptureDeviceInput * input =
[AVCaptureDeviceInput deviceInputWithDevice: device error: & error];
if (input) {
// Handle the error appropriately.
}
添加输出,输出分类:
要从捕获会话获取输出,请添加一个或多个输出。输出是具体的实例
AVCaptureOutput的子类;
你用:
AVCaptureMovieFileOutput 输出到电影文件
AVCaptureVideoDataOutput 如果您想处理正在捕获的视频中的帧
AVCaptureAudioDataOutput 如果您想处理正在捕获的音频数据
AVCaptureStillImageOutput 如果您想捕获带有元数据的静止图像
您可以使用addOutput将输出添加到捕获会话中:
您检查捕获输出是否兼容
使用canAddOutput:
进行现有会话
您可以根据需要添加和删除输出
会话正在运行。
AVCaptureSession * captureSession = <# Get a capture session #>;
AVCaptureMovieFileOutput * movieInput = <# Create and configure a movie output #>;
if ([captureSession canAddOutput: movieInput]) {
[captureSession addOutput: movieInput];
}
else {
// Handle the failure.
}
保存视频文件,添加视频文件输出:
使用AVCaptureMovieFileOutput对象将影片数据保存到文件中。 (AVCaptureMovieFileOutput 是AVCaptureFileOutput的具体子类,它定义了许多基本行为。)您可以配置 电影文件输出的各个方面,例如录制的最长持续时间,或最大文件 尺寸。如果剩余的磁盘空间少于一定数量,您也可以禁止录制。
AVCaptureMovieFileOutput * aMovieFileOutput = [[AVCaptureMovieFileOutput alloc]
init];
CMTime maxDuration = <# Create a CMTime to represent the maximum duration #>;
aMovieFileOutput.maxRecordedDuration = maxDuration;
aMovieFileOutput.minFreeDiskSpaceLimit = <# An appropriate minimum given the quality
of the movie format and the duration #>;
处理预览视频帧数据,每帧取景器数据可用于后续的高级处理,如人脸检测等。
AVCaptureVideoDataOutput对象使用委托来销售视频帧。
您可以使用
设置代理
setSampleBufferDelegate: queue:
。
除了委托之外,还指定了一个串行队列
委托方法被调用。您必须使用串行队列来确保将帧传递给委托
以正确的顺序
您不应该传递dispatch_get_current_queue
返回的队列
无法保证当前队列在哪个线程上运行。您可以使用队列来修改
优先考虑传送和处理视频帧。
对于帧的数据处理,必须对大小(图像大小)和处理时间限制进行限制,如果处理时间过长,底层传感器将不会将数据发送到路由器和回调。
您应该将会话输出设置为应用程序的最低实际分辨率 设置输出 分辨率高于必要的浪费处理周期并且不必要地消耗功率。 你必须确保你的实施 captureOutput:didOutputSampleBuffer:fromConnection:能够处理其中的样本缓冲区 分配给框架的时间量。如果它需要太长时间,你保持视频帧,AVFoundation 将停止提供帧,不仅是您的代表,还有其他输出,如预览图层。
处理捕获过程:
AVCaptureStillImageOutput * stillImageOutput = [[AVCaptureStillImageOutput alloc]
init];
NSDictionary * outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG,
AVVideoCodecKey, nil];
[StillImageOutput setOutputSettings: outputSettings];
能够支持不同的格式也支持直接生成jpg流。 如果要捕获JPEG图像,通常不应指定自己的压缩格式。代替, 你应该让静止图像输出为你做压缩,因为它的压缩是硬件加速的。 如果需要图像的数据表示,可以使用jpegStillImageNSDataRepresentation:to 即使您修改了图像的元数据,也可以在不重新压缩数据的情况下获取NSData对象。
相机预览显示:
您可以使用AVCaptureVideoPreviewLayer为用户提供正在录制内容的预览 宾语。 AVCaptureVideoPreviewLayer是CALayer的子类(参见Core Animation Programming Guide。你不需要任何输出来显示预览。
AVCaptureSession * captureSession = <# Get a capture session #>;
CALayer * viewLayer = <# Get a layer from the view in which you want to present the
The preview #>;
AVCaptureVideoPreviewLayer * captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer
alloc] initWithSession: captureSession];
[viewLayer addSublayer: captureVideoPreviewLayer];
通常,预览图层的行为与渲染树中的任何其他CALayer对象相同(请参阅核心动画 编程指南)。您可以像您一样缩放图像并执行变换,旋转等操作 任何一层。一个区别是您可能需要设置图层的方向属性以指定方式 它应该旋转来自相机的图像。此外,在iPhone 4上,预览层支持镜像 (这是预览前置摄像头时的默认设置。)
答案 1 :(得分:2)
从this answer引用,可能会在后台运行this delegate method,这会导致之前的AVCaptureSession
未正确断开,有时会导致canAddOutput:
有时是NO
。
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
解决方案可能是在上面的委托中使用stopRunning
(当然,在做了必要的操作和条件检查之后,你需要正确完成以前的会话吗?)。
除此之外,如果你提供一些你想要做的代码会更好。
答案 2 :(得分:1)
这可能是这2例中的一个
1)会话正在运行中
2)您已添加输出
您无法添加2个输出或2个输入,也无法创建2个不同的会话
答案 3 :(得分:0)
它可能是:
的组合AVCaptureSession
。您应该尝试只添加一次(我猜canAddOutput:
始终为YES
),然后根据需要暂停/恢复您的会话:
// Stop session if possible
if (_captureSession.running && !_captureInProgress)
{
[_captureSession stopRunning];
NBULogVerbose(@"Capture session: {\n%@} stopped running", _captureSession);
}
你可以看看here。
答案 4 :(得分:0)
我认为这会对你有所帮助 canAddOutput: 返回一个布尔值,指示是否可以将给定输出添加到会话中。
- (BOOL)canAddOutput:(AVCaptureOutput *)output
参数 产量 要添加到会话的输出。 回报价值 如果可以将输出添加到会话中,则为YES,否则为NO。
状况 适用于OS X v10.7及更高版本。
以下是apple doc Click here
的链接