Проект AVCam падает на iPad
Демонстрационный исходный код Apple для демонстрационного приложения AVCam находится здесь: https://developer.apple.com/library/content/samplecode/AVCam/Introduction/Intro.html вылетает при попытке сделать снимок (независимо от того, создаете ли вы Объектив -C или Swift версии) на линии в AVCamCameraViewController/CameraViewController
(Свифт), который захватывает фотографию:
[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 должен быть установлен в значение, присутствующее в SupportFlashModes массив"
И когда я проверяю массив режимов вспышки, я получаю это:
(lldb) po [self.photoOutput supportFlashModes] <__NSSingleObjectArrayI 0x170007c50>(0)
Таким образом, чтобы добавить режим вспышки, в документах говорится, что вы должны указать, какие режимы вы хотите поддерживать в AVCapturePhotoSettings
объект. Я сделал это с помощью этой строки кода:
photoSettings.flashMode = AVCaptureFlashModeAuto;
или (Свифт)
photoSettings.flashMode = .auto
Так что я догадываюсь, что это ошибка, относящаяся конкретно к 12,9" iPad Pro, и мне, вероятно, нужно представить радар, но я подумал, что я хотел бы спросить здесь, если кто-то видел это раньше. Есть идеи?
Обновить
Мне удалось скопировать и другие iPad, так что, похоже, это не только 12,9" iPad Pro.
8 ответов
Добавь это...
let position = self.videoDeviceInput.device.position
photoSettings.flashMode = position == .front || position == .unspecified ? .off : .auto
прямо перед этим...
self.photoOutput.capturePhoto(with: photoSettings, delegate: photoCaptureDelegate)
Это должно решить проблему.
// Также для тех, кто может испытывать эту проблему при попытке использовать предоставленный Apple пример кода AVCam в XCode на MacOS, используя версию кода, предоставленную 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]
Вы должны проверить, поддерживает ли устройство режим "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]
В кратчайшие сроки необходимо проверить, поддерживает ли вообще вывод фотографий режим вспышки.
let settings = AVCapturePhotoSettings()
if photoOutput.supportedFlashModes.contains(.on) {
settings.flashMode = self.flashMode
} else {
settings.flashMode = .off
}
self.photoOutput?.capturePhoto(with: settings, delegate: self)
Чтобы проверить, есть ли у камеры вспышка, используйте AVCaptureDevice.hasFlash
собственность на эту камеру.
На самом деле не имеет смысла использовать заднее / переднее положение, чтобы угадать это, когда уже есть что-то, что просто говорит вам, есть ли у него вспышка.
Нет необходимости проверять положение камеры, все, что нам нужно, это проверить, есть ли у камеры вспышка, и в соответствии с этим мы устанавливаем режим вспышки.
photoSettings.flashMode = AVCaptureDevice.default(for: AVMediaType.video)!.hasFlash ? .on : .off
Ответ Офира Малачи работает. Сначала определите, поддерживается ли флэш-память вообще. Вот быстрый код 3:
if capturePhotoOutput.supportedFlashModes.contains(NSNumber.init(value: Int8(AVCaptureFlashMode.on.rawValue))) {
photoSettings.flashMode = .auto
}
else {
photoSettings.flashMode = .off
}
Решение @RazvanR работает для этого кода Apple AVCamera, но непосредственно перед этим кодом
// NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];
нет, и нужно использовать AVCapturePhotoOutput
Версия Swift
Swift: photoData = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: photoSampleBuffer, previewPhotoSampleBuffer: previewPhotoSampleBuffer)
... но не знаю, что такое версия Objective-C.
Поэтому, основываясь на ответе Соджи, я решил допросить supportedFlashModes
массив, предоставленный photoOutput
переменная, которая является 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. Другими словами, он отлично работает на моем телефоне.
Напишите эту строку в информационном листе
Privacy - Camera Usage Description