2013-02-15 100 views
2

我的问题相机冻结在切换到前置摄像头

我使用AVFoundation捕捉每5秒的视频输出的帧。当用户点击一个按钮时,输入摄像机应该从前一个切换到后一个,而相反。问题是,每次我的相机背面切换到前置摄像头冻结时间(奇怪的是,它的工作原理周围的其他方法 - 这意味着,前置摄像头后置摄像头)!

我用

要将摄像头之间切换的代码,我使用苹果的AVCam sample code变量名的轻微变化采取的(所以它会匹配我的代码)的确切代码:

- (BOOL)toggleCamera 
{ 
    BOOL success = NO; 

    if ([self cameraCount] > 1) { 
     NSError *error; 
     AVCaptureDeviceInput *newVideoInput; 
     AVCaptureDevicePosition position = [[self.videoInput device] position]; 

     if (position == AVCaptureDevicePositionBack) 
      newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self frontFacingCamera] error:&error]; 

     else if (position == AVCaptureDevicePositionFront) 
      newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self backFacingCamera] error:&error]; 

     else 
      goto bail; 

     if (newVideoInput != nil) { 

      // Start configuring the session. 
      [[self captureSession] beginConfiguration]; 

      // Remove the current video input device. 
      [[self captureSession] removeInput:[self videoInput]]; 

      if ([[self captureSession] canAddInput:newVideoInput]) { 
       [[self captureSession] addInput:newVideoInput]; 
       [self setVideoInput:newVideoInput]; 
      } 

      else { 
       [[self captureSession] addInput:[self videoInput]]; 
      } 

      [[self captureSession] commitConfiguration]; 

      success = YES; 
      [newVideoInput release]; 
     } 

     else if (error) { 
      NSLog(@"PICTURE TAKER: Failed to toggle cameras." 
        @"\nError: %@", error.localizedDescription); 
     } 
    } 

bail: 
    return success; 
} 

而设置的AVCaptureSession,再次,我用的是确切相同的代码从AVCam sample code,在增加产量略有变化,(符合我的NE编辑):

- (BOOL) setupSession 
{ 
    BOOL success = NO; 

    // Set torch and flash mode to auto 
    if ([[self backFacingCamera] hasFlash]) { 
     if ([[self backFacingCamera] lockForConfiguration:nil]) { 
      if ([[self backFacingCamera] isFlashModeSupported:AVCaptureFlashModeAuto]) { 
       [[self backFacingCamera] setFlashMode:AVCaptureFlashModeAuto]; 
      } 
      [[self backFacingCamera] unlockForConfiguration]; 
     } 
    } 
    if ([[self backFacingCamera] hasTorch]) { 
     if ([[self backFacingCamera] lockForConfiguration:nil]) { 
      if ([[self backFacingCamera] isTorchModeSupported:AVCaptureTorchModeAuto]) { 
       [[self backFacingCamera] setTorchMode:AVCaptureTorchModeAuto]; 
      } 
      [[self backFacingCamera] unlockForConfiguration]; 
     } 
    } 

    // Init the device inputs 
    AVCaptureDeviceInput *newVideoInput = [[AVCaptureDeviceInput alloc] initWithDevice:[self frontFacingCamera] error:nil]; 

    // Create a video output & configure it. 
    AVCaptureVideoDataOutput *newVideoDataOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    newVideoDataOutput.videoSettings = @{(NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA)}; 

    // Set the output's delegate. 
    dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL); 
    [newVideoDataOutput setSampleBufferDelegate:self queue:queue]; 
    dispatch_release(queue); 

    // Create session (use default AVCaptureSessionPresetHigh) 
    AVCaptureSession *newCaptureSession = [[AVCaptureSession alloc] init]; 

    // Add inputs and output to the capture session 
    if ([newCaptureSession canAddInput:newVideoInput]) { 
     [newCaptureSession addInput:newVideoInput]; 
    } 

    if ([newCaptureSession canAddOutput:newVideoDataOutput]) { 
     [newCaptureSession addOutput:newVideoDataOutput]; 
    } 

    [self setVideoOutput:newVideoDataOutput]; 
    [self setVideoInput:newVideoInput]; 
    [self setCaptureSession:newCaptureSession]; 

    [newVideoDataOutput release]; 
    [newVideoInput release]; 
    [newCaptureSession release]; 

    // Get our view's layer. 
    CALayer *viewLayer = self.view.layer; 

    // Add the the session's preview layer. 
    AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession]; 
    captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; 
    captureVideoPreviewLayer.frame = self.view.bounds; 
    [viewLayer insertSublayer:captureVideoPreviewLayer below:self.imageViewOverlay.layer]; 
    [captureVideoPreviewLayer release]; 

    success = YES; 

    return success; 
} 

* 重要提示:摄像头调用输出的委托后立即冻结。

谁能帮我解决这个问题?似乎我已经尝试了几乎所有的东西!

更新#1

按照要求,自指的是介绍了这届的预览层,管理与相机有关的一切事物的视图控制器。此外,我张贴的代码来自苹果AVCam sample code采取的句柄frontFacingCamera的一部分,这是(就像所有的,我迄今发布的代码中):

// Find a camera with the specificed 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; 
} 

// Find a front facing camera, returning nil if one is not found 
- (AVCaptureDevice *) frontFacingCamera 
{ 
    return [self cameraWithPosition:AVCaptureDevicePositionFront]; 
} 
+0

我们可以得到一些更多的代码,特别是围绕“frontFacingCamera”您连接到视频输入setUpSession的设置?以及什么是“自我”指的是? – Spectravideo328 2013-02-15 20:16:24

+0

@ Spectravideo328按照您的要求我已经更新的问题,感谢您的关注! – Itamar 2013-02-17 07:58:38

回答

6
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; 
} 

回答here

编辑:这从广场凸轮苹果的示例代码。工作正常。也测试过。 http://developer.apple.com/library/ios/#samplecode/SquareCam/Listings/SquareCam_SqareCamViewController_m.html

//使用前/后摄像头

- (IBAction)switchCameras:(id)sender 

{ 

AVCaptureDevicePosition desiredPosition; 

if (isUsingFrontFacingCamera) 

    desiredPosition = AVCaptureDevicePositionBack; 

else 

    desiredPosition = AVCaptureDevicePositionFront; 



for (AVCaptureDevice *d in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) { 

    if ([d position] == desiredPosition) { 

     [[previewLayer session] beginConfiguration]; 

     AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:d error:nil]; 

     for (AVCaptureInput *oldInput in [[previewLayer session] inputs]) { 

      [[previewLayer session] removeInput:oldInput]; 

     } 

     [[previewLayer session] addInput:input]; 

     [[previewLayer session] commitConfiguration]; 

     break; 

    } 

} 

isUsingFrontFacingCamera = !isUsingFrontFacingCamera; 

} 
+0

我会检查出来,并将其标记为答案,如果它的工作,谢谢! – Itamar 2013-03-10 08:50:55

+0

好吧,我检查你的代码,它像交换在应由话又说回来,正如我在摄像头,可以互换面对一个正面后冻结的问题进行说明。 – Itamar 2013-03-10 08:57:40

+0

我编辑了答案。经过测试,工作正常。 – 2013-03-10 09:20:32

相关问题