Зная разрешение пресетов сессий AVCaptureSession - PullRequest
13 голосов
/ 17 октября 2011

Я получаю доступ к камере в iOS и использую предустановки сессий следующим образом:

captureSession.sessionPreset = AVCaptureSessionPresetMedium;

Довольно стандартные вещи.Тем не менее, я хотел бы знать заранее, какое разрешение видео я получу из-за этой предустановки (особенно потому, что в зависимости от устройства оно будет другим).Я знаю, что в Интернете есть таблицы, с которыми можно ознакомиться (например, здесь: http://cmgresearch.blogspot.com/2010/10/augmented-reality-on-iphone-with-ios40.html).Но я хотел бы иметь возможность получить это программно, чтобы я не полагался только на магические числа.

Итак, что-то вроде этого (теоретически):

[captureSession resolutionForPreset:AVCaptureSessionPresetMedium];

, что можетвернуть CGSize {ширина: 360, высота: 480}.Я не смог найти ни одного такого API, поэтому мне пришлось ждать, пока я получу свое первое захваченное изображение, и затем запросить его (что по другим причинам в моем программном потоке не очень хорошо).

Ответы [ 8 ]

22 голосов
/ 17 октября 2011

Я не профессионал AVFoundation, но я думаю, что путь:

captureSession.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureInput *input = [captureSession.inputs objectAtIndex:0]; // maybe search the input in array
AVCaptureInputPort *port = [input.ports objectAtIndex:0];
CMFormatDescriptionRef formatDescription = port.formatDescription;
CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription);

Я не уверен насчет последнего шага и сам не пробовал. Просто нашел, что в документации и думаю, что это должно работать.

Ища CMVideoDimensions в Xcode, вы найдете пример проекта RosyWriter. Посмотрите на этот код (у меня сейчас нет времени на это).

7 голосов
/ 07 марта 2013

К вашему сведению, прилагаю официальный ответ от Apple.


Это продолжение идентификатора ошибки # 13201137.

Инжиниринг установил, что эта проблема ведет себя как задумано, основываясь на следующей информации:

Есть несколько проблем с включенным кодом:

1) AVCaptureSession не имеет входов. 2) AVCaptureSession не имеет выходов.

Без хотя бы одного входа (добавленного в сеанс с помощью [AVCaptureSession addInput:]) и совместимого вывода (добавленного с помощью [AVCaptureSession addOutput:]) активных подключений не будет, поэтому сеанс фактически не запустится в устройстве ввода. В этом нет необходимости - нет выходов, на которые можно доставлять данные с камеры.

3) Класс JAViewController предполагает, что свойство -formatDescription видеопорта станет ненулевым, как только вернется [AVCaptureSession startRunning].

Нет гарантии, что описание формата будет обновлено в соответствии с новым форматом камеры, как только startRunning вернется. -startRunning запускает камеру и возвращается, когда она полностью запущена и работает, но не ожидает, когда видеокадры будут активно проходить через конвейер захвата, то есть когда будет обновлено описание формата.

Вы просто слишком быстро запрашиваете. Если бы вы подождали еще несколько миллисекунд, это было бы там. Но правильный способ сделать это - прослушать AVCaptureInputPortFormatDescriptionDidChangeNotification.

4) Ваш класс JAViewController создает объект PVCameraInfo в retrieveCameraInfo: и задает ему вопрос, затем позволяет ему выпасть из области видимости, где он освобождается и освобождается.

Следовательно, сеанс не может быть достаточно длинным для выполнения вашего запроса измерений. Вы слишком быстро останавливаете камеру.

Мы считаем эту проблему закрытой. Если у вас есть какие-либо вопросы или сомнения по поводу этой проблемы, обновите отчет напрямую (http://bugreport.apple.com).

Спасибо, что нашли время сообщить нам об этой проблеме.

С наилучшими пожеланиями,

Команда разработчиков отчетов об ошибках Отношения Apple с разработчиками по всему миру

5 голосов
/ 18 февраля 2016

Вы можете программно получить разрешение от activeFormat до начала захвата, но не до добавления входов и выходов: https://developer.apple.com/library/ios/documentation/AVFoundation/Reference/AVCaptureDevice_Class/index.html#//apple_ref/occ/instp/AVCaptureDevice/activeFormat

private func getCaptureResolution() -> CGSize {
    // Define default resolution
    var resolution = CGSize(width: 0, height: 0)

    // Get cur video device
    let curVideoDevice = useBackCamera ? backCameraDevice : frontCameraDevice

    // Set if video portrait orientation
    let portraitOrientation = orientation == .Portrait || orientation == .PortraitUpsideDown

    // Get video dimensions
    if let formatDescription = curVideoDevice?.activeFormat.formatDescription {
        let dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription)
        resolution = CGSize(width: CGFloat(dimensions.width), height: CGFloat(dimensions.height))
        if (portraitOrientation) {
            resolution = CGSize(width: resolution.height, height: resolution.width)
        }
    }

    // Return resolution
    return resolution
}
3 голосов
/ 07 декабря 2011

Может быть, вы можете предоставить список всех возможных предустановленных разрешений для каждой модели iPhone и проверить, на какой модели устройства работает приложение? - используя что-то вроде этого ...

[[UIDevice currentDevice] platformType]   // ex: UIDevice4GiPhone
[[UIDevice currentDevice] platformString] // ex: @"iPhone 4G"

Однако вы должны обновить список для каждой новой модели устройства. Надеюсь, это поможет:)

2 голосов
/ 17 октября 2011

Согласно Apple , для этого нет API. Это отстой, у меня была такая же проблема.

0 голосов
/ 31 октября 2018

Лучший способ сделать то, что вы хотите (получить известный формат видео или изображения), - это установить формат устройства захвата.

Сначала найдите устройство захвата, которое вы хотите использовать:

       if #available(iOS 10.0, *) {
        captureDevice = defaultCamera()
    } else {
        let devices = AVCaptureDevice.devices()
        // Loop through all the capture devices on this phone
        for device in devices {
            // Make sure this particular device supports video
            if ((device as AnyObject).hasMediaType(AVMediaType.video)) {
                // Finally check the position and confirm we've got the back camera
                if((device as AnyObject).position == AVCaptureDevice.Position.back) {
                    captureDevice = device as AVCaptureDevice
                }
            }
        }
    }
    self.autoLevelWindowCenter = ALCWindow.frame
    if captureDevice != nil && currentUser != nil {
        beginSession()
    }
}




    func defaultCamera() -> AVCaptureDevice? {
    if #available(iOS 10.0, *) { // only use the wide angle camera never dual camera
        if let device = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera,
                                                             for: AVMediaType.video,
                                                             position: .back) {
            return device
        } else {
            return nil
        }
    } else {
        return nil
    }
}

Затем найдите форматы, которые может использовать это устройство:

        let options = captureDevice!.formats
    var supportable = options.first as! AVCaptureDevice.Format
    for format in options {
        let testFormat = format 
        let description = testFormat.description
        if (description.contains("60 fps") && description.contains("1280x 720")){
            supportable = testFormat
        }
    }

Вы можете выполнить более сложный анализформатов, но вам может быть все равно.

Затем просто установите устройство в этот формат:

do {
    try captureDevice?.lockForConfiguration()
    captureDevice!.activeFormat = supportable
    // setup other capture device stuff like autofocus, frame rate, ISO, shutter speed, etc.
    try captureSession.addInput(AVCaptureDeviceInput(device: captureDevice!))
    // add the device to an active CaptureSession
}

Возможно, вы захотите взглянуть на документы AVFoundation и учебное пособие по AVCaptureSession, так какмного чего можно сделать с выходом.Например, вы можете преобразовать результат в .mp4 с помощью AVAssetExportSession, чтобы вы могли опубликовать его на YouTube и т. Д.

Надеюсь, это поможет

0 голосов
/ 02 сентября 2018

, если для предустановки установлено значение .photo, возвращаемый размер соответствует размеру фотографии, а не для предварительного просмотра.

, если для предустановки задано значение не .photo, размер возврата соответствует размеру видео, а не для размера снятой фотографии.

if self.session.sessionPreset != .photo {
    // return video size, not captured photo size
    let format = videoDevice.activeFormat
    let formatDescription = format.formatDescription
    let dimensions = CMVideoFormatDescriptionGetDimensions(formatDescription) 
} else {
    // other way to get video size
}

Ответ @Christian Beer - хороший способ для заданной предустановки.Мой способ хорош для активной предустановки.

0 голосов
/ 09 августа 2017

Apple использует соотношение 4: 3 для камеры iPhone.

Вы можете использовать это соотношение, чтобы получить размер кадра захваченного видео, установив ограничение ширины или высоты AVCaptureVideoPreviewLayer и установив аспектограничение соотношения 4: 3.

4:3 Ratio

На левом изображении ширина была установлена ​​на 300 пикселей, а высота была получена путем установки 4: 3соотношение было 400px.

На правом изображении высота была установлена ​​на 300px, а ширина была получена путем установки соотношения 3: 4, и это было 225px.

...