AVCam项目在iPad上崩溃

时间:2016-11-22 01:05:42

标签: objective-c swift ipad avfoundation avcam

Apple的AVCam演示应用程序的演示源代码在这里找到:https://developer.apple.com/library/content/samplecode/AVCam/Introduction/Intro.html在{{1}的行上试图拍照(无论你是构建Objective-C还是Swift版本)时崩溃捕捉照片的(斯威夫特):

AVCamCameraViewController/CameraViewController

或(斯威夫特)

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

崩溃时的错误消息是:

  

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

当我检查闪光模式阵列时,我得到了这个:

  

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

因此,为了添加Flash模式,文档说您必须在self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate) 对象中指定要支持的模式。我用这行代码完成了这个:

AVCapturePhotoSettings

或(斯威夫特)

photoSettings.flashMode = AVCaptureFlashModeAuto;

所以我的预感是,这是一个特别与12.9“iPad Pro和有关的错误我可能需要提交一个雷达,但我想我会问这里,万一有人以前见过它。想法?

更新

我也能够复制其他iPad,所以它似乎不仅仅是12.9“iPad Pro。

10 个答案:

答案 0 :(得分:11)

添加此...

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

就在此之前......

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

那应该解决问题。

答案 1 :(得分:4)

//对于在MacOS上使用Apple提供的AVCam示例代码尝试使用Objective C提供的代码版本时可能遇到此问题的人,只需添加此项(在目标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]

答案 2 :(得分: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]

答案 3 :(得分:1)

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

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

 self.photoOutput?.capturePhoto(with: settings, delegate: self)

答案 4 :(得分:0)

要检查相机是否具有闪光灯,请使用该相机上的api_client = google_build(serviceName=api_name, version=api_version, http=authorized) for i in developments: sample_request = { 'viewId': '6690350', 'pageSize': 100000, 'dateRanges': { 'startDate': datetime.strftime(datetime.now() - timedelta(days = 30),'%Y-%m-%d'), 'endDate': datetime.strftime(datetime.now(),'%Y-%m-%d') }, 'metrics': [{'expression': 'ga:sessions'}], 'orderBys': [ {'fieldName': 'ga:pagePath', 'sortOrder': 'ASCENDING'}, {'fieldName': 'ga:sessions', 'sortOrder': 'DESCENDING'} ], 'dimensions': [{'name': 'ga:pagePath'},{'name': 'ga:city'},{'name': 'ga:latitude'},{'name': 'ga:longitude'}], 'dimensionFilterClauses' : [ { 属性。

当已经有东西可以告诉您是否有闪光灯时,使用后/前位置来猜测这一点并没有多大意义。

答案 5 :(得分:0)

无需检查相机的位置,我们所需要的只是检查相机是否具有不闪光的闪光灯,并据此设置闪光模式。

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

答案 6 :(得分:-1)

在info plist

中写下这一行
Privacy - Camera Usage Description

答案 7 :(得分:-1)

基于Soja的回答,我决定询问supportedFlashModes photoOutput变量提供的AVCapturePhotoOutput数组{/ 1}}。

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模式之前支持 <p:dataTable id="machine-table" value=#{machinePage.machines} var="machine" styleClass="machine-table"> <p:column style="width:16px"> <p:rowToggler rendered="#{machine.projectsInMachine.size() > 0}" /> </p:column> some other machine column here... <p:rowExpansion > <p:dataTable value="#{machine.projectsInMachine}" var="project" styleClass="project-subtable" > some project column here </p:dataTable> </p:rowExpansion> 模式。这里的差异和问题似乎与设备类型,iPhone与iPad有关,因为iPad不像iPhone那样背面有闪光灯。换句话说,它在我的手机上运行良好。

答案 8 :(得分:-1)

Ofir Malachi的回答是有效的。首先确定是否支持闪存。 这是快捷的3代码:

     if capturePhotoOutput.supportedFlashModes.contains(NSNumber.init(value: Int8(AVCaptureFlashMode.on.rawValue))) {
        photoSettings.flashMode = .auto
     }
     else {
        photoSettings.flashMode = .off
     }

答案 9 :(得分:-1)

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

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

没有,需要使用AVCapturePhotoOutput

Swift版本是

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

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