AVCameraInput - 前后摄像头切换导致崩溃

3

我正在使用AV通过我的应用程序录制视频,并且我有一个按钮可以切换摄像机视图为前置或后置,后置是默认值。从后置切换到前置可正常工作,但是从前置切换回后置会导致应用程序崩溃。

- (IBAction)btnSwapCamerasClicked:(id)sender {

//Change camera source
if(session)
{
    //Indicate that some changes will be made to the session
    [session beginConfiguration];

    //Remove existing input
    AVCaptureInput* currentCameraInput = [session.inputs objectAtIndex:0];
    [session removeInput:currentCameraInput];

    //Get new input
    AVCaptureDevice *newCamera = nil;
    if(((AVCaptureDeviceInput*)currentCameraInput).device.position == AVCaptureDevicePositionBack)
    {
        newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];
    }
    else
    {
        newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];
    }

    //Add input to session
    NSError *err = nil;
    AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:newCamera error:&err];
    if(!newVideoInput || err)
    {
        NSLog(@"Error creating capture device input: %@", err.localizedDescription);
    }
    else
    {
          //THIS IS THE SPOT THAT CRASHES.
        [session addInput:newVideoInput];
    }

    //Commit all the configuration changes at once
    [session commitConfiguration];
}

}

在 [session addInput:newVideoInput]; 下崩溃,我收到了以下错误信息:

2015-03-03 11:25:59.566 The SWAT App Beta[1769:365194] * 终止应用程序,原因是未捕获的异常 'NSInvalidArgumentException',原因:'* 不支持多个音频/视频AVCaptureInputs。'   *** 第一个调用堆栈:   (0x185c002d4 0x1975c80e4 0x1843ad39c 0x1843accd4 0x10004ac14 0x18a818fb4 0x18a80201c 0x18a818950 0x18a8185dc 0x18a811a74 0x18a7e57f0 0x18aa85274 0x18a7e3d04 0x185bb8250 0x185bb74f4 0x185bb55a4 0x185ae1404 0x18f4eb6fc 0x18a84a2b4 0x10004bb70 0x197c6ea08)   libc++abi.dylib:终止类型为NSException的未捕获异常

我不确定为什么似乎有多个输入,因为在我列出的代码中,我删除了旧输入,并且它对于前后摄像头都可以正常工作。不知道为什么前后照相会导致应用程序崩溃。

有什么想法吗?


更新--我认为我找到了可能导致问题的原因。当尝试再次从前面到后面时,检查相机位置的if语句不起作用。我重写了if语句,在else条件中添加了“else if cam is front”和第三个else,我的代码通过了第三个else,它不检查任何条件。 - user2616830
更新2:这让我找到了答案。请看下面我使用的解决方案。 - user2616830
2个回答

2

我通过重写摄像头切换的代码来解决了我的问题,我自己编写了一些代码。我创建了一个名为currentCam的NSString,根据当前情况将文本更改为“Back”或“Front”。以下是代码:

- (IBAction)btnSwapCamerasClicked:(id)sender {

[session beginConfiguration];


if ([currentCam isEqualToString:@"Back"])
{
    NSArray *inputs = [session inputs];

    for (AVCaptureInput *input in inputs)
    {
        [session removeInput:input];
    }

    //Video input
    AVCaptureDevice *newCamera = nil;
    newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];

    //Audio input
    AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    AVCaptureDeviceInput * audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];


    NSError *err = nil;
    AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:newCamera error:&err];
    if(!newVideoInput || err)
    {
        NSLog(@"Error creating capture device input: %@", err.localizedDescription);
    }
    else
    {

        [session addInput:newVideoInput];
        [session addInput:audioInput];

        newVideoInput = nil;
        audioInput = nil;
        audioDevice = nil;
        newCamera = nil;
        inputs = nil;


    }

    currentCam = @"Front";


}
else if ([currentCam isEqualToString:@"Front"])
{
    NSArray *inputs = [session inputs];

    for (AVCaptureInput *input in inputs)
    {
        [session removeInput:input];
    }

    //Video input
    AVCaptureDevice *newCamera = nil;
    newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];

    //Audio input
    AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    AVCaptureDeviceInput * audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];


    NSError *err = nil;
    AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:newCamera error:&err];
    if(!newVideoInput || err)
    {
        NSLog(@"Error creating capture device input: %@", err.localizedDescription);
    }
    else
    {

        [session addInput:newVideoInput];
        [session addInput:audioInput];

        newVideoInput = nil;
        audioInput = nil;
        audioDevice = nil;
        newCamera = nil;
        inputs = nil;
    }

    currentCam = @"Back";
}
else
{
    //Camera is some weird third camera that doesn't exist yet! :O
    NSLog(@"wat");
}

[session commitConfiguration];
}

1
只有这些代码才能工作。
- (IBAction)switchCamera:(id)sender {

    [captureSession beginConfiguration];
    NSArray *inputs = [captureSession inputs];

    //Remove all inputs
    for (AVCaptureInput *input in inputs)
    {
        [captureSession removeInput:input];
    }

    //Video input
    AVCaptureDevice *newCamera = nil;
    if ([currentCam isEqualToString:@"Back"]){
        newCamera = [self cameraWithPosition:AVCaptureDevicePositionFront];
           currentCam = @"Front";
    }else{
        newCamera = [self cameraWithPosition:AVCaptureDevicePositionBack];
         currentCam = @"Back";
    }
    //Audio input
    AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
    AVCaptureDeviceInput * audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
    NSError *err = nil;

    AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:newCamera error:&err];
    if(!newVideoInput || err)
    {
        NSLog(@"Error creating capture device input: %@", err.localizedDescription);
    }
    else
    {
        [captureSession addInput:newVideoInput];
        [captureSession addInput:audioInput];
    }
[captureSession commitConfiguration];
}

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