我制作了一款具有拍摄和保存视频功能的应用。 我已经使用了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之前停止会话:[[[self.videoViewController captureManager] session] stopRunning];
[self.videoViewController.view removeFromSuperview];
self.videoViewController = nil;
谢谢W Dyson。
答案 0 :(得分:9)
试试这个 - 它对我来说就像一个冠军:
BOOL isUsingFrontFacingCamera;
- (BOOL) swapCameras
{
if ([self cameraCount] > 1) {
AVCaptureDevicePosition desiredPosition;
if (isUsingFrontFacingCamera) {
desiredPosition = AVCaptureDevicePositionBack;
} else {
desiredPosition = AVCaptureDevicePositionFront;
}
for (AVCaptureDevice *d in [AVCaptureDevice devicesWithMediaType: AVMediaTypeVideo]) {
if ([d position] == desiredPosition) {
[[self session] beginConfiguration];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:d error:nil];
for (AVCaptureInput *oldInput in [[self session] inputs]) {
[[self session] removeInput:oldInput];
}
[[self session] addInput:input];
[[self session] commitConfiguration];
break;
}
}
isUsingFrontFacingCamera = !isUsingFrontFacingCamera;
return YES;
}
return NO;
}
您应该可以删除此代码以替换 VideoRecorderCaptureManager.m
中的原始 swapCameras原产地:Apple的SquareCam示例代码。
答案 1 :(得分:3)
您收到错误日志了吗?如果没有,您需要修复上面的代码,看看他们说了什么。 您使用的是什么版本的AVCam?他们最近将项目更新到版本1.2,这样效率更高,使用块。
根据我的经验,您不应该创建和重新创建会话,您可以将其保留。也许你需要以不同的方式构建你的应用程序。你的应用到底是什么?也许我们可以帮助你。如果您的应用程序以相机为中心,则会更容易离开会话,如果您只是采用模式进行视频,那么可能使用AVCam是过度的。
对我来说,你的实际问题听起来像AVCaptureDeviceInput。下载原始AVCam软件包,看看您是否更改了任何保留计数或安全if语句。如果还有其他代码,请发帖。
更新:你能改变吗?
} else if (error) {
NSLog(@"%@",[error localizedDescription]);
}
到
} if (error) {
NSLog(@"%@",[error localizedDescription]);
}
并告诉我是否有错误?
此外,在释放拥有会话的视图控制器之前,请确保停止会话并将捕获管理器设置为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;
}