12

Apple 的 AVCam 演示应用程序的演示源代码可在此处找到:https ://developer.apple.com/library/content/samplecode/AVCam/Introduction/Intro.html在尝试拍照时崩溃(无论您是否构建了目标-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 必须设置为支持的FlashModes 中存在的值大批'

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

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

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

photoSettings.flashMode = AVCaptureFlashModeAuto;

或(斯威夫特)

photoSettings.flashMode = .auto

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

更新

我也能够复制其他 iPad,因此它似乎不仅仅是 12.9 英寸 iPad Pro。

4

9 回答 9

11

添加这个...

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

就在这之前……

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

那应该可以解决问题。

于 2017-01-22T19:02:46.477 回答
3

// 对于在 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]
于 2017-02-25T00:44:27.610 回答
1

您必须检查设备是否支持“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]
于 2017-04-26T11:45:45.153 回答
1

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

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

于 2018-08-21T10:32:24.433 回答
1

必须快速检查照片输出是否完全支持闪光模式。

 let settings = AVCapturePhotoSettings()
 if photoOutput.supportedFlashModes.contains(.on) {
     settings.flashMode = self.flashMode
 } else {
     settings.flashMode = .off
 }

 self.photoOutput?.capturePhoto(with: settings, delegate: self)
于 2020-02-05T08:54:12.100 回答
0

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

photoSettings.flashMode = AVCaptureDevice.default(for: AVMediaType.video)!.hasFlash ? .on : .off
于 2020-09-10T10:17:14.577 回答
-1

因此,基于 Soja 的回答,我决定询问supportedFlashModesphotoOutput变量提供的数组,即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 那样的闪光灯。换句话说,它在我的手机上运行良好。

于 2017-02-03T02:51:25.993 回答
-1

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

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

没有,需要使用 AVCapturePhotoOutput

斯威夫特版本是

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

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

于 2018-05-16T08:07:50.793 回答
-2

在 info plist 中写下这一行

Privacy - Camera Usage Description
于 2016-11-23T11:10:49.677 回答