我制作了一个具有捕获和保存视频功能的应用。
我为此使用了AVFoundation,而Apple's AVCam一直是我的指南。
我希望我能说清楚:
在我第一次发布处理AVCamCaptureManager的videoViewController之前,一切工作正常(在AVCam中为AVCamViewController)。之后,当我再次创建它时,视频在切换摄像机后立即卡住。即使重新运行也无济于事,也不会清理或重置设备。 (有时候,其中一件事情是有帮助的,但这不是规则)。
当不需要节省内存时,我释放了videoViewController。
切换摄像机的代码与AVCam中的代码基本相同:
NSError *error;
AVCaptureDeviceInput *newVideoInput;
AVCaptureDevicePosition position = currentVideoInput.device.position;
if (position == AVCaptureDevicePositionBack)
newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:frontFacingCamera error:&error];
else if (position == AVCaptureDevicePositionFront)
newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:backFacingCamera error:&error];
if (newVideoInput != nil) {
[session beginConfiguration];
[session removeInput:currentVideoInput];
if ([session canAddInput:newVideoInput]) {
[session addInput:newVideoInput];
[self setVideoInput:newVideoInput];
} else {
[session addInput:currentVideoInput];
}
[session commitConfiguration];
[newVideoInput release];
} else if (error) {
NSLog(@"%@",[error localizedDescription]);
}
我关闭videoView的代码
[self.videoViewController.view removeFromSuperview];
self.videoViewController = nil;
我当前的“解决方法”是简单地保留它,即使我不需要它。
有人可以解释为什么会这样以及如何解决。
编辑:解决
正如W Dyson在回应中指出的那样,我应该在释放videoViewController之前停止 session ,如下所示:
[[[self.videoViewController captureManager] session] stopRunning];
[self.videoViewController.view removeFromSuperview];
self.videoViewController = nil;
谢谢戴森(W Dyson)。
最佳答案
您是否收到错误日志?如果不是,则需要修复上面的代码,然后看看他们怎么说。
您正在使用哪个版本的AVCam?他们最近将项目更新到了1.2版,该版本效率更高并且使用了块。
根据我的经验,您不应该创建和重新创建 session ,您可以直接打开它。也许您需要以稍微不同的方式来构建您的应用程序。您的应用程序到底是关于什么的?也许我们可以为您提供帮助。如果您的应用程序以相机为中心,那么保持 session 状态更容易,如果只是以模态方式拍摄视频,则使用AVCam可能会显得过大。
对我来说,您的实际问题听起来像是AVCaptureDeviceInput。下载原始的AVCam软件包,然后查看是否更改了保留计数或if语句的安全性。如果还有其他代码,请发布。
更新:您可以更改
} else if (error) {
NSLog(@"%@",[error localizedDescription]);
}
至
} if (error) {
NSLog(@"%@",[error localizedDescription]);
}
告诉我是否有错误?
另外,在释放拥有该 session 的 View Controller 之前,请确保停止该 session 并将捕获管理器设置为nil。
更新2:尝试此切换代码。这就是我一直在使用的。 AVCamMirringMode是一个结构,如下所示:
enum {
AVCamMirroringOff = 1,
AVCamMirroringOn = 2,
AVCamMirroringAuto = 3
};
typedef NSInteger AVCamMirroringMode;
- (BOOL) toggleCamera
{
BOOL success = NO;
if ([self cameraCount] > 1) {
NSError *error;
AVCaptureDeviceInput *newVideoInput;
AVCaptureDevicePosition position = [[videoInput device] position];
BOOL mirror;
if (position == AVCaptureDevicePositionBack){
newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self frontFacingCamera] error:&error];
switch ([self mirroringMode]) {
case AVCamMirroringOff:
mirror = NO;
break;
case AVCamMirroringOn:
mirror = YES;
break;
case AVCamMirroringAuto:
default:
mirror = YES;
break;
}
}
else if (position == AVCaptureDevicePositionFront){
newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backFacingCamera] error:&error];
switch ([self mirroringMode]) {
case AVCamMirroringOff:
mirror = NO;
break;
case AVCamMirroringOn:
mirror = YES;
break;
case AVCamMirroringAuto:
default:
mirror = NO;
break;
}
}
else
goto bail;
if (newVideoInput != nil) {
[[self session] beginConfiguration];
[[self session] removeInput:[self videoInput]];
if ([[self session] canAddInput:newVideoInput]) {
[[self session] addInput:newVideoInput];
AVCaptureConnection *connection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self stillImageOutput] connections]];
if ([connection isVideoMirroringSupported]) {
[connection setVideoMirrored:mirror];
}
[self setVideoInput:newVideoInput];
} else {
[[self session] addInput:[self videoInput]];
}
[[self session] commitConfiguration];
success = YES;
[newVideoInput release];
} else if (error) {
if ([[self delegate] respondsToSelector:@selector(captureManager:didFailWithError:)]) {
[[self delegate] captureManager:self didFailWithError:error];
}
}
}
bail:
return success;
}