Проект 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
Другие вопросы по тегам