ios - 使用 avcapturesession 切换摄像头

标签 ios avcapturesession front-camera

在此处使用本教程:http://www.musicalgeometry.com/?p=1297我已经使用 AVCaptureSession 创建了自定义叠加层和图像捕获。

我试图让用户在前置和后置摄像头之间切换。这是我在 CaptureSessionManager 中切换摄像头的代码:

- (void)addVideoInputFrontCamera:(BOOL)front {
    NSArray *devices = [AVCaptureDevice devices];
    AVCaptureDevice *frontCamera;
    AVCaptureDevice *backCamera;

    for (AVCaptureDevice *device in devices) {

        //NSLog(@"Device name: %@", [device localizedName]);

        if ([device hasMediaType:AVMediaTypeVideo]) {

            if ([device position] == AVCaptureDevicePositionBack) {
                //NSLog(@"Device position : back");
                backCamera = device;
            }
            else {
                //NSLog(@"Device position : front");
                frontCamera = device;
            }
        }
    }

    NSError *error = nil;

    if (front) {
        AVCaptureDeviceInput *frontFacingCameraDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:frontCamera error:&error];
        if (!error) {
            if ([[self captureSession] canAddInput:frontFacingCameraDeviceInput]) {
                [[self captureSession] addInput:frontFacingCameraDeviceInput];
            } else {
                NSLog(@"Couldn't add front facing video input");
            }
        }
    } else {
        AVCaptureDeviceInput *backFacingCameraDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&error];
        if (!error) {
            if ([[self captureSession] canAddInput:backFacingCameraDeviceInput]) {
                [[self captureSession] addInput:backFacingCameraDeviceInput];
            } else {
                NSLog(@"Couldn't add back facing video input");
            }
        }
    }
}

现在在我的自定义覆盖 Controller 中,我在 viewDidLoad 中初始化所有内容:

[self setCaptureManager:[[CaptureSessionManager alloc] init]];

[[self captureManager] addVideoInputFrontCamera:NO]; // set to YES for Front Camera, No for Back camera

[[self captureManager] addStillImageOutput];

[[self captureManager] addVideoPreviewLayer];
CGRect layerRect = [[[self view] layer] bounds];
[[[self captureManager] previewLayer] setBounds:layerRect];
[[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];

[[_captureManager captureSession] startRunning];

切换相机按钮连接到名为 switchCamera 的方法。我试过这个:

- (void)switchCameraView:(id)sender {

    [[self captureManager] addVideoInputFrontCamera:YES]; // set to YES for Front Camera, No for Back camera

}

调用它时,我从 CaptureSessionManager 收到错误 NSLog 并且我无法弄清楚原因。在viewDidLoad中,如果我将fontCamera设置为YES,它会显示前置摄像头但不能切换到后置,反之亦然。

关于如何让它正确切换的任何想法?

最佳答案

您首先需要从 AVCaptureSession 中删除现有的 AVCameraInput,然后将新的 AVCameraInput 添加到 AVCaptureSession。以下对我有用(在 ARC 下):

-(IBAction)switchCameraTapped:(id)sender
{
    //Change camera source
    if(_captureSession)
    {
        //Indicate that some changes will be made to the session
        [_captureSession beginConfiguration];

        //Remove existing input
        AVCaptureInput* currentCameraInput = [_captureSession.inputs objectAtIndex:0];
        [_captureSession 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
        {
            [_captureSession addInput:newVideoInput];
        }

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

// Find a camera with the specified AVCaptureDevicePosition, returning nil if one is not found
- (AVCaptureDevice *) cameraWithPosition:(AVCaptureDevicePosition) position
{
    NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *device in devices) 
    {
        if ([device position] == position) return device;
    }
    return nil;
}

关于ios - 使用 avcapturesession 切换摄像头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20864372/

相关文章:

iphone - AVCaptureVideoDataOutput 和设置 kCVPixelBufferWidthKey & kCVPixelBufferHeightKey

objective-c - 运行多个 AVCaptureSession 或添加多个输入

android - 前置摄像头在小 View 中的侧面打开 - Android

iphone - 当 View 不是全屏时,子类化 UIViewController 或创建自定义 NSObject

iphone - 搜索大量数据来自iPhone中的Web服务

ios - 同时播放和录制音频

ios - 如何使用 CIDetector 和 Swift 在图像中裁剪检测到的矩形

ios - 注册类语法 - Swift

android-camera - 如何使前置摄像头捕获的视频不是反Android?