【问题标题】:AVCam Project Crashes On iPadAVCam 项目在 iPad 上崩溃
【发布时间】:2016-11-22 01:05:41
【问题描述】:

Apple 的 AVCam 演示应用程序的演示源代码可在此处找到:https://developer.apple.com/library/content/samplecode/AVCam/Introduction/Intro.html 在尝试拍照时崩溃(无论您构建的是 Objective-C 还是 Swift 版本)在线上AVCamCameraViewController/CameraViewController(Swift)拍摄照片:

[self.photoOutput capturePhotoWithSettings:photoSettings delegate:photoCaptureDelegate];

或(斯威夫特)

self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)

崩溃时的错误信息是:

2016-11-21 17:44:31.590070 AVCam[2178:2303627] * 终止应用程序到期 未捕获的异常 'NSInvalidArgumentException',原因:'* -[AVCapturePhotoOutput capturePhotoWithSettings:delegate:] flashMode 必须设置为 supportedFlashModes 数组中存在的值'

当我检查 flash 模式数组时,我得到了这个:

(lldb) po [self.photoOutput supportedFlashModes] <__nssingleobjectarrayi>( 0 )

因此,为了添加 flash 模式,文档说您必须在 AVCapturePhotoSettings 对象中指定要支持的模式。我已经用这行代码做到了:

photoSettings.flashMode = AVCaptureFlashModeAuto;

或(斯威夫特)

photoSettings.flashMode = .auto

所以我的直觉是,这是一个与 12.9 英寸 iPad Pro 相关的错误,并且我可能需要提交雷达,但我想我会在这里问一下,以防有人以前见过。任何想法?

更新

我也可以复制其他 iPad,所以它似乎不仅仅是 12.9 英寸 iPad Pro。

【问题讨论】:

  • 猜我们需要提交雷达。相同的代码库可在所有 iPhone 和 iPad air 上运行,没有任何崩溃。我没有 iPad Pro 来测试它:(
  • 我所做的是确定当前设备是 .front 还是 .back 并且我将 flashMode 设置为 .off 用于 .front 或 .unspecified ,否则设置为 .auto 。我希望这会有所帮助。
  • 这个问题解决了吗?有同样的问题。但无法确认用户拥有的 iPad 版本。 :(
  • 我已经能够解决这个问题,只需重新启动计算机,然后重新启动 Xcode,然后进行干净的构建并在设备上运行。
  • 嗯。有趣的。就我而言,这是生产构建中的一个问题。不确定是否有助于重新启动计算机并生成构建。

标签: objective-c swift ipad avfoundation avcam


【解决方案1】:

添加这个...

let position = self.videoDeviceInput.device.position
photoSettings.flashMode = position == .front || position == .unspecified ? .off : .auto

就在这之前...

self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)

这应该可以解决问题。

【讨论】:

  • @WDyson 我刚刚编辑了问题以改进格式。 Soja给出了答案
  • @soja 您能否详细说明为什么此解决方案可以解决问题?
  • @WDyson 它会检查相机在使用中的位置。如果位置在前面或未指定,则闪光灯模式关闭。否则它在.auto上。我相信 .auto 存在一个错误……Apple 需要在他们的代码中修复它。
  • @Soja 为什么它被接受为正确答案?您只是禁止在某些设备上使用闪光灯作为前置摄像头!
  • 这似乎不起作用。检查 hasFlash 并设置为 .auto 如果 true 是正确的解决方案
【解决方案2】:

// 对于在 MacOS 上尝试在 XCode 中使用 Apple 提供的 AVCam 示例代码时可能遇到此问题的人,使用 Objective C 提供的代码版本,只需添加以下内容(在 Objective C 中):

AVCaptureDevicePosition position = self.videoDeviceInput.device.position;
if (position == AVCaptureDevicePositionFront)
{
   photoSettings.flashMode = AVCaptureFlashModeOff;
}
else
{
   photoSettings.flashMode = AVCaptureFlashModeAuto;
}


//right before:

[self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate]

【讨论】:

  • 另一个“答案”,建议完全禁止前置摄像头的闪光灯模式
【解决方案3】:

您必须检查设备是否支持“Flash”模式 与:

[self.photoOutput.supportedFlashModes containsObject:[NSNumber numberWithInt:AVCaptureFlashModeOn]])

然后使用:

@property (nonatomic) AVCapturePhotoOutput *photoOutput;


AVCapturePhotoSettings *photoSettings = [AVCapturePhotoSettings photoSettings];


  AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        if ([device hasTorch] && [device hasFlash]){
            [device lockForConfiguration:nil];
            if([self.photoOutput.supportedFlashModes containsObject:[NSNumber numberWithInt:AVCaptureFlashModeOn]]){
                [device setFlashMode:AVCaptureFlashModeOn];
                photoSettings.flashMode = AVCaptureFlashModeAuto;
            }
            else{
                photoSettings.flashMode = AVCaptureFlashModeOff;
            }
            [device unlockForConfiguration];
        }
        else{
            photoSettings.flashMode = AVCaptureFlashModeOff;
            [device unlockForConfiguration];
        }

然后

[self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate]

【讨论】:

    【解决方案4】:

    要检查相机是否有闪光灯,请使用该相机的AVCaptureDevice.hasFlash 属性。

    当已经有一些东西可以告诉你它是否有闪光灯时,使用后/前位置来猜测这个真的没有意义。

    【讨论】:

      【解决方案5】:

      在swift中必须检查照片输出是否支持闪光模式。

       let settings = AVCapturePhotoSettings()
       if photoOutput.supportedFlashModes.contains(.on) {
           settings.flashMode = self.flashMode
       } else {
           settings.flashMode = .off
       }
      
       self.photoOutput?.capturePhoto(with: settings, delegate: self)
      

      【讨论】:

        【解决方案6】:

        无需检查摄像头位置,我们只需要检查摄像头是否有闪光灯,并据此设置闪光灯模式。

        photoSettings.flashMode = AVCaptureDevice.default(for: AVMediaType.video)!.hasFlash ? .on : .off
        

        【讨论】:

          【解决方案7】:

          因此,基于 Soja 的回答,我决定询问 photoOutput 变量提供的 supportedFlashModes 数组,这是一个 AVCapturePhotoOutput

          self.inProgressPhotoCaptureDelegates[photoCaptureDelegate.requestedPhotoSettings.uniqueID] = photoCaptureDelegate
          
          if let _ = self.photoOutput.supportedFlashModes.filter({ (mode) -> Bool in
              return mode.intValue == AVCaptureFlashMode.auto.rawValue
          }).last {
              let position = self.videoDeviceInput.device.position
              photoSettings.flashMode = position == .front || position == .unspecified ? .off : .auto
          } else {
              photoSettings.flashMode = .off
          }
          
          self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)
          

          可能有一些更全面的方法可以做到这一点,但这可以确保在尝试使用之前支持.auto 模式。这里的差异和问题似乎与设备类型有关,iPhone 与 iPad,因为 iPad 的背面没有 iPhone 那样的闪光灯。换句话说,它在我的手机上运行良好。

          【讨论】:

            【解决方案8】:

            @RazvanR 解决方案适用于 Apple AVCamera 代码,但就在它之前

            // NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
            

            没有,需要使用 AVCapturePhotoOutput

            Swift 版本是

            Swift: photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer)
            

            ...但不知道 Objective-C 版本是什么。

            【讨论】:

              【解决方案9】:

              在info plist中写下这一行

              Privacy - Camera Usage Description
              

              【讨论】:

              • 感谢您的建议。我已经在 Info.plist 文件中有那个键。仍然崩溃。
              • info.plist 中的这个键与 flash 模式下的崩溃有何关系?
              猜你喜欢
              • 2012-11-26
              • 2011-04-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多