Все еще и видео получение носителей

Для управления получением от устройства, такого как камера или микрофон Вы собираете объекты представлять вводы и выводы и использовать экземпляр AVCaptureSession скоординировать поток данных между ними. Минимально Вам нужно:

Чтобы показать пользователю предварительный просмотр того, что записывает камера, можно использовать экземпляр AVCaptureVideoPreviewLayer (подкласс CALayer).

Можно сконфигурировать многократные вводы и выводы, скоординированные единственным сеансом:

../Art/captureoverview_2x.png

Для многих приложений это - столько подробности, сколько Вам нужно. Для некоторых операций, однако, (если Вы хотите контролировать уровни мощности в звуковом канале, например) необходимо рассмотреть, как различные порты устройства ввода данных представлены и как те порты подключены к выводу.

Соединение между вводом получения и выводом получения в сеансе получения представлено AVCaptureConnection объект. Вводы получения (экземпляры AVCaptureInput) имейте один или несколько входных портов (экземпляры AVCaptureInputPort). Выводы получения (экземпляры AVCaptureOutput) может принять данные из одного или более источников (например, AVCaptureMovieFileOutput объект принимает и видеоданные и аудиоданные).

Когда Вы добавляете ввод или вывод к сеансу, соединениям форм сеанса между всеми совместимыми портами вводов получения и получаете выводы. Соединение между вводом получения и выводом получения представлено AVCaptureConnection объект.

../Art/captureDetail_2x.png

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

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

AVCaptureSession объект является центральным объектом координирования, который Вы используете для управления сбором данных. Вы используете экземпляр для координирования потока данных от устройств ввода данных AV до выводов. Вы добавляете устройства захвата изображения и выводы, которые Вы хотите к сеансу, затем запускаете поток данных путем отправки сеанса a startRunning сообщение и остановка поток данных путем отправки a stopRunning сообщение.

AVCaptureSession *session = [[AVCaptureSession alloc] init];
// Add inputs and outputs.
[session startRunning];

Конфигурирование сеанса

Вы используете предварительную установку на сеансе для указания качества изображения и разрешения, которое Вы хотите. Предварительная установка является константой, идентифицирующей одну из многих возможных конфигураций; в некоторых случаях фактическая конфигурация специфична для устройства:

Символ

Разрешение

Комментарии

AVCaptureSessionPresetHigh

Высоко

Самое высокое качество записи.

Это варьируется для каждого устройства.

AVCaptureSessionPresetMedium

Носитель

Подходящий для совместного использования Wi-Fi.

Фактические значения могут измениться.

AVCaptureSessionPresetLow

Низко

Подходящий для совместного использования 3G.

Фактические значения могут измениться.

AVCaptureSessionPreset640x480

640x480

VGA.

AVCaptureSessionPreset1280x720

1280x720

HD на 720 пунктов.

AVCaptureSessionPresetPhoto

Фотография

Полное фото разрешение.

Это не поддерживается для видеовыхода.

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

if ([session canSetSessionPreset:AVCaptureSessionPreset1280x720]) {
    session.sessionPreset = AVCaptureSessionPreset1280x720;
}
else {
    // Handle the failure.
}

Если бы необходимо скорректировать параметры сеанса на более гранулированном уровне, чем возможно с предварительной установкой, или требуется внести изменения в рабочий сеанс, Вы окружаете свои изменения beginConfiguration и commitConfiguration методы. beginConfiguration и commitConfiguration методы гарантируют, чтобы изменения устройств произошли как группа, минимизировав видимость или несоответствие состояния. После вызова beginConfiguration, можно добавить или удалить выводы, измениться sessionPreset свойство, или конфигурируют свойства ввода или вывода получения частного лица. Никакие изменения фактически не внесены, пока Вы не вызываете commitConfiguration, в котором времени они применяются вместе.

[session beginConfiguration];
// Remove an existing capture device.
// Add a new capture device.
// Reset the preset.
[session commitConfiguration];

Контроль состояния сеанса получения

Сеанс получения отправляет уведомления, которые можно наблюдать, чтобы быть уведомленными, например, когда он запускает или прекращает работать, или когда он прерван. Можно зарегистрироваться для получения AVCaptureSessionRuntimeErrorNotification если происходит ошибка периода выполнения. Можно также опросить сеанс running свойство, чтобы узнать, работает ли это, и interrupted свойство, чтобы узнать, прервано ли это. Кроме того, оба running и interrupted свойства являются значением ключа, наблюдающим совместимый, и уведомления отправляются на основном потоке.

Объект AVCaptureDevice представляет устройство ввода данных

AVCaptureDevice объектные краткие обзоры физическое устройство захвата изображения, предоставляющее входные данные (такие как аудио или видео) к AVCaptureSession объект. Существует один объект для каждого устройства ввода данных, например, двух видеовходов — один для обращенного к передней стороне камера, один для обращенной к задней стороне камеры — и одного аудиовхода для микрофона.

Можно узнать, какие устройства захвата изображения являются в настоящее время доступным использованием AVCaptureDevice методы класса devices и devicesWithMediaType:. И, при необходимости, можно узнать, какие функции iPhone, iPad или предложения iPod (см. Настройки Получения Устройства). Список доступных устройств может измениться, все же. Текущие устройства ввода данных могут стать недоступными (если они используются другим приложением), и новые устройства ввода данных могут стать доступными, (если они оставлены другим приложением). Необходимо зарегистрироваться для получения AVCaptureDeviceWasConnectedNotification и AVCaptureDeviceWasDisconnectedNotification уведомления быть предупрежденным когда список доступных изменений устройств.

Вы добавляете устройство ввода данных к сеансу получения с помощью ввода получения (см. Вводы Получения Использования для Добавления Устройства захвата изображения к Сеансу).

Характеристики устройства

Можно спросить устройство о его различных характеристиках. Можно также протестировать, обеспечивает ли это определенный тип среды или поддерживает данное предварительно установленное использование сеанса получения hasMediaType: и supportsAVCaptureSessionPreset: соответственно. Для предоставления информации пользователю можно узнать позицию устройства захвата изображения (является ли это на передней стороне или задней части протестированного модуля), и его локализованное имя. Если Вы хотите представить список устройств захвата изображения, чтобы позволить пользователю выбирать то, это может быть полезно.

Рисунок 4-1 показывает позиции обращенного к задней стороне (AVCaptureDevicePositionBack) и обращенный к передней стороне (AVCaptureDevicePositionFront) камеры.

  Передняя сторона устройства на iOS рисунка 4-1 и положения камеры обратной обточки

Следующий пример кода выполняет итерации по всем доступным устройствам и регистрирует их имя — и для видеоустройств, их позиции — на модуле.

NSArray *devices = [AVCaptureDevice devices];
 
for (AVCaptureDevice *device in devices) {
 
    NSLog(@"Device name: %@", [device localizedName]);
 
    if ([device hasMediaType:AVMediaTypeVideo]) {
 
        if ([device position] == AVCaptureDevicePositionBack) {
            NSLog(@"Device position : back");
        }
        else {
            NSLog(@"Device position : front");
        }
    }
}

Кроме того, можно узнать ID устройства модели и его уникальный идентификатор.

Настройки получения устройства

Различные устройства имеют различные возможности; например, некоторые могут поддерживать различный фокус или высветить режимы; некоторые могут поддерживать внимание на интересное место.

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

NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
NSMutableArray *torchDevices = [[NSMutableArray alloc] init];
 
for (AVCaptureDevice *device in devices) {
    [if ([device hasTorch] &&
         [device supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]) {
        [torchDevices addObject:device];
    }
}

Если Вы находите многократные устройства, удовлетворяющие Ваши критерии, Вы могли бы позволить пользователю выбрать, какой они хотят использовать. Для отображения описания устройства пользователю можно использовать localizedName свойство.

Вы используете всевозможные функции похожими способами. Существуют константы для указания определенного режима, и можно спросить устройство, поддерживает ли это определенный режим. В нескольких случаях можно наблюдать, что свойство уведомляется, когда изменяется функция. Во всех случаях необходимо заблокировать устройство прежде, чем изменить режим определенной функции, как описано в Конфигурировании Устройства.

Режимы фокуса

Существует три режима фокуса:

  • AVCaptureFocusModeLocked: Фокальная позиция фиксируется.

    Это полезно, когда Вы хотите позволить пользователю сочинять, сцена тогда блокируют фокус.

  • AVCaptureFocusModeAutoFocus: Камера делает единственный фокус сканирования, тогда возвращается к заблокированному.

    Это подходит для ситуации, где Вы хотите выбрать определенный элемент, на котором можно фокусировать и затем уделить внимание тому элементу, даже если это не центр сцены.

  • AVCaptureFocusModeContinuousAutoFocus: Камера постоянно автофокусируется по мере необходимости.

Вы используете isFocusModeSupported: метод, чтобы определить, поддерживает ли устройство данный режим фокуса, затем установил режим с помощью focusMode свойство.

Кроме того, устройство может поддерживать фокус интереса. Вы тестируете на использование поддержки focusPointOfInterestSupported. Если это поддерживается, Вы устанавливаете использование фокуса focusPointOfInterest. Вы передаете a CGPoint где {0,0} представляет верхнюю левую из области изображения, и {1,1} представляет нижнее правое в альбомном режиме с кнопкой «Домой» справа — это применяется, даже если устройство находится в режиме портрета.

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

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

if ([currentDevice isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
    CGPoint autofocusPoint = CGPointMake(0.5f, 0.5f);
    [currentDevice setFocusPointOfInterest:autofocusPoint];
    [currentDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
}

Режимы воздействия

Существует два режима воздействия:

Вы используете isExposureModeSupported: метод, чтобы определить, поддерживает ли устройство данный режим воздействия, затем установил режим с помощью exposureMode свойство.

Кроме того, устройство может поддерживать интересное место воздействия. Вы тестируете на использование поддержки exposurePointOfInterestSupported. Если это поддерживается, Вы устанавливаете использование точки воздействия exposurePointOfInterest. Вы передаете a CGPoint где {0,0} представляет верхнюю левую из области изображения, и {1,1} представляет нижнее правое в альбомном режиме с кнопкой «Домой» справа — это применяется, даже если устройство находится в режиме портрета.

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

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

if ([currentDevice isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
    CGPoint exposurePoint = CGPointMake(0.5f, 0.5f);
    [currentDevice setExposurePointOfInterest:exposurePoint];
    [currentDevice setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
}

Режимы Flash

Существует три режима флэш-памяти:

  • AVCaptureFlashModeOff: Флэш-память никогда не будет стрелять.

  • AVCaptureFlashModeOn: Флэш-память будет всегда стрелять.

  • AVCaptureFlashModeAuto: Флэш-память будет стрелять зависящий от условий окружающего света.

Вы используете hasFlash определить, имеет ли устройство флэш-память. Если возвращается тот метод YES, Вы тогда используете isFlashModeSupported: метод, передавая желаемый режим, чтобы определить, поддерживает ли устройство данный режим флэш-памяти, затем установил режим с помощью flashMode свойство.

Режим факела

В режиме факела флэш-память постоянно позволяется в низкой мощности осветить видеосъемку. Существует три режима факела:

Вы используете hasTorch определить, имеет ли устройство флэш-память. Вы используете isTorchModeSupported: метод, чтобы определить, поддерживает ли устройство данный режим флэш-памяти, затем установил режим с помощью torchMode свойство.

Если устройство связано с рабочим сеансом получения, для устройств с факелом факел только включает.

Видео стабилизация

Кинематографическая vdeo стабилизация доступна для соединений, воздействующих на видео, в зависимости от определенного оборудования устройства. Несмотря на это, не все исходные форматы и разрешения видео поддерживаются.

Включение кинематографической видео стабилизации может также ввести дополнительную задержку в конвейер видеосъемки. Для обнаружения, когда видео стабилизация будет использоваться используйте videoStabilizationEnabled свойство. enablesVideoStabilizationWhenAvailable свойство позволяет приложению автоматически включать видео стабилизацию, если это поддерживается камерой. Автоматической стабилизацией по умолчанию отключен вследствие вышеупомянутых ограничений.

Баланс белого

Существует два режима баланса белого:

Вы используете isWhiteBalanceModeSupported: метод, чтобы определить, поддерживает ли устройство данный режим баланса белого, затем установил режим с помощью whiteBalanceMode свойство.

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

Ориентация задающего устройства

Вы устанавливаете желаемую ориентацию на a AVCaptureConnection указать, как Вы хотите изображения, ориентированные в AVCaptureOutput (AVCaptureMovieFileOutput, AVCaptureStillImageOutput и AVCaptureVideoDataOutput) для соединения.

Используйте AVCaptureConnectionsupportsVideoOrientation свойство, чтобы определить, ли поддержки устройства, изменяющие ориентацию видео, и videoOrientation свойство, чтобы указать, как Вы хотите изображения, ориентированные в выходном порту. Перечисление 4-1 показывает, как установить ориентацию для a AVCaptureConnection к AVCaptureVideoOrientationLandscapeLeft:

Перечисление 4-1  , Устанавливающее ориентацию соединения получения

AVCaptureConnection *captureConnection = <#A capture connection#>;
if ([captureConnection isVideoOrientationSupported])
{
    AVCaptureVideoOrientation orientation = AVCaptureVideoOrientationLandscapeLeft;
    [captureConnection setVideoOrientation:orientation];
}

Конфигурирование устройства

Для установки свойств получения на устройстве необходимо сначала получить блокировку на использовании устройства lockForConfiguration:. Это избегает вносить изменения, которые могут быть несовместимыми с настройками в других приложениях. Следующий фрагмент кода иллюстрирует, как приблизиться к изменению режима фокуса на устройстве первым определением, поддерживается ли режим, затем пытаясь заблокировать устройство для реконфигурирования. Режим фокуса изменяется, только если блокировка получена, и блокировка выпущена сразу позже.

if ([device isFocusModeSupported:AVCaptureFocusModeLocked]) {
    NSError *error = nil;
    if ([device lockForConfiguration:&error]) {
        device.focusMode = AVCaptureFocusModeLocked;
        [device unlockForConfiguration];
    }
    else {
        // Respond to the failure as appropriate.

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

Переключение между устройствами

Иногда можно хотеть позволить пользователям переключаться между устройствами ввода данных — например, переключаясь от использования обращенного к передней стороне к к обращенной к задней стороне камере. Для предотвращения пауз или заикания можно реконфигурировать сеанс, в то время как оно работает, однако необходимо использовать beginConfiguration и commitConfiguration заключить в скобки Ваши изменения конфигурации:

AVCaptureSession *session = <#A capture session#>;
[session beginConfiguration];
 
[session removeInput:frontFacingCameraDeviceInput];
[session addInput:backFacingCameraDeviceInput];
 
[session commitConfiguration];

Когда наиболее удаленное commitConfiguration вызывается, все изменения внесены вместе. Это гарантирует плавный переход.

Используйте вводы получения для добавления устройства захвата изображения к сеансу

Для добавления устройства захвата изображения к сеансу получения Вы используете экземпляр AVCaptureDeviceInput (конкретный подкласс краткого обзора AVCaptureInput класс). Ввод устройства захвата изображения управляет портами устройства.

NSError *error;
AVCaptureDeviceInput *input =
        [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
    // Handle the error appropriately.
}

Вы добавляете вводы к использованию сеанса addInput:. При необходимости можно проверить, совместим ли ввод получения с существующим использованием сеанса canAddInput:.

AVCaptureSession *captureSession = <#Get a capture session#>;
AVCaptureDeviceInput *captureDeviceInput = <#Get a capture device input#>;
if ([captureSession canAddInput:captureDeviceInput]) {
    [captureSession addInput:captureDeviceInput];
}
else {
    // Handle the failure.
}

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

AVCaptureInput продает один или несколько потоков данных носителей. Например, устройства ввода данных могут обеспечить и аудиоданные и видеоданные. Каждый мультимедийный поток, предоставленный вводом, представлен AVCaptureInputPort объект. Сеанс получения использует AVCaptureConnection объект определить отображение между рядом AVCaptureInputPort объекты и сингл AVCaptureOutput.

Используйте выводы получения, которые будут выведены от сеанса

Чтобы быть выведенными от сеанса получения, Вы добавляете один или несколько выводов. Вывод является экземпляром конкретного подкласса AVCaptureOutput. Вы используете:

Вы добавляете выводы к использованию сеанса получения addOutput:. Вы проверяете, совместим ли вывод получения с существующим использованием сеанса canAddOutput:. В то время как сеанс работает, можно добавить и удалить выводы как требуется.

AVCaptureSession *captureSession = <#Get a capture session#>;
AVCaptureMovieFileOutput *movieOutput = <#Create and configure a movie output#>;
if ([captureSession canAddOutput:movieOutput]) {
    [captureSession addOutput:movieOutput];
}
else {
    // Handle the failure.
}

Сохранение к файлу ролика

Вы сохраняете данные фильма к файлу с помощью AVCaptureMovieFileOutput объект. (AVCaptureMovieFileOutput конкретный подкласс AVCaptureFileOutput, который определяет большую часть основного поведения.) Можно сконфигурировать различные аспекты вывода файла ролика, такие как максимальная продолжительность записи или ее максимальный размер файла. Если существуют меньше, чем данная сумма оставленного дискового пространства, можно также запретить запись.

AVCaptureMovieFileOutput *aMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
CMTime maxDuration = <#Create a CMTime to represent the maximum duration#>;
aMovieFileOutput.maxRecordedDuration = maxDuration;
aMovieFileOutput.minFreeDiskSpaceLimit = <#An appropriate minimum given the quality of the movie format and the duration#>;

Разрешение и скорость передачи для вывода зависят от сеанса получения sessionPreset. Видео кодированием обычно является H.264, и аудиокодированием обычно является AAC. Фактические значения варьируются устройством.

Запуск записи

Вы начинаете записывать использование фильма в формате QuickTime startRecordingToOutputFileURL:recordingDelegate:. Необходимо предоставить основанный на файле URL и делегата. URL не должен идентифицировать существующий файл, потому что вывод файла ролика не перезаписывает существующие ресурсы. У Вас должно также быть разрешение записать в указанное расположение. Делегат должен соответствовать AVCaptureFileOutputRecordingDelegate протокол, и должен реализовать captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error: метод.

AVCaptureMovieFileOutput *aMovieFileOutput = <#Get a movie file output#>;
NSURL *fileURL = <#A file URL that identifies the output location#>;
[aMovieFileOutput startRecordingToOutputFileURL:fileURL recordingDelegate:<#The delegate#>];

В реализации captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error:, делегат мог бы записать получающийся фильм в альбом Рулона Камеры. Это должно также проверить на любые ошибки, которые, возможно, произошли.

Обеспечение, что файл был записан успешно

Определить, был ли файл сохранен успешно в реализации captureOutput:didFinishRecordingToOutputFileAtURL:fromConnections:error: Вы проверяете не только ошибку, но также и значение AVErrorRecordingSuccessfullyFinishedKey в пользовательском информационном словаре ошибки:

- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
        didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
        fromConnections:(NSArray *)connections
        error:(NSError *)error {
 
    BOOL recordedSuccessfully = YES;
    if ([error code] != noErr) {
        // A problem occurred: Find out if the recording was successful.
        id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey];
        if (value) {
            recordedSuccessfully = [value boolValue];
        }
    }
    // Continue as appropriate...

Необходимо проверить значение AVErrorRecordingSuccessfullyFinishedKeyвведите пользовательский информационный словарь ошибки, потому что файл, возможно, был сохранен успешно, даже при том, что Вы получили ошибку. Ошибка могла бы указать, что одно из Ваших ограничений записи было достигнуто — например, AVErrorMaximumDurationReached или AVErrorMaximumFileSizeReached. Другие причины, которые могла бы остановить запись:

  • Диск полон —AVErrorDiskFull

  • Регистрирующее устройство было разъединено —AVErrorDeviceWasDisconnected

  • Сеанс был прерван (например, телефонный вызов был принят) —AVErrorSessionWasInterrupted

Добавление метаданных к файлу

Можно установить метаданные для файла ролика в любое время, даже при записи. Это полезно для ситуаций, где информация не доступна, когда запись запускается, как может иметь место с информацией о расположении. Метаданные для вывода файла представлены массивом AVMetadataItem объекты; Вы используете экземпляр его непостоянного подкласса, AVMutableMetadataItem, создать собственные метаданные.

AVCaptureMovieFileOutput *aMovieFileOutput = <#Get a movie file output#>;
NSArray *existingMetadataArray = aMovieFileOutput.metadata;
NSMutableArray *newMetadataArray = nil;
if (existingMetadataArray) {
    newMetadataArray = [existingMetadataArray mutableCopy];
}
else {
    newMetadataArray = [[NSMutableArray alloc] init];
}
 
AVMutableMetadataItem *item = [[AVMutableMetadataItem alloc] init];
item.keySpace = AVMetadataKeySpaceCommon;
item.key = AVMetadataCommonKeyLocation;
 
CLLocation *location - <#The location to set#>;
item.value = [NSString stringWithFormat:@"%+08.4lf%+09.4lf/"
    location.coordinate.latitude, location.coordinate.longitude];
 
[newMetadataArray addObject:item];
 
aMovieFileOutput.metadata = newMetadataArray;

Обработка кадров видео

AVCaptureVideoDataOutput возразите делегации использования для продажи видеокадров. Вы устанавливаете делегата, использующего setSampleBufferDelegate:queue:. В дополнение к установке делегата Вы указываете последовательную очередь, на которую они вызываются методы делегата. Необходимо использовать последовательную очередь, чтобы гарантировать, что кадры поставлены делегату в надлежащем порядке. Можно использовать очередь для изменения приоритета, отданного поставке и обработке видеокадров. Посмотрите SquareCam для демонстрационной реализации.

Кадры представлены в методе делегата, captureOutput:didOutputSampleBuffer:fromConnection:, как экземпляры CMSampleBufferRef непрозрачный тип (см. Представления Носителей). По умолчанию буферы испускаются в самом эффективном формате камеры. Можно использовать videoSettings свойство для указания пользовательского выходного формата. Свойство параметров видео является словарем; в настоящее время единственный поддерживаемый ключ kCVPixelBufferPixelFormatTypeKey. Рекомендуемые форматы пикселя возвращаются availableVideoCVPixelFormatTypes свойство, и availableVideoCodecTypes свойство возвращает поддерживаемые значения. И Базовая Графика и OpenGL работают хорошо с BGRA формат:

AVCaptureVideoDataOutput *videoDataOutput = [AVCaptureVideoDataOutput new];
NSDictionary *newSettings =
                @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
videoDataOutput.videoSettings = newSettings;
 
 // discard if the data output queue is blocked (as we process the still image
[videoDataOutput setAlwaysDiscardsLateVideoFrames:YES];)
 
// create a serial dispatch queue used for the sample buffer delegate as well as when a still image is captured
// a serial dispatch queue must be used to guarantee that video frames will be delivered in order
// see the header doc for setSampleBufferDelegate:queue: for more information
videoDataOutputQueue = dispatch_queue_create("VideoDataOutputQueue", DISPATCH_QUEUE_SERIAL);
[videoDataOutput setSampleBufferDelegate:self queue:videoDataOutputQueue];
 
AVCaptureSession *captureSession = <#The Capture Session#>;
 
if ( [captureSession canAddOutput:videoDataOutput] )
     [captureSession addOutput:videoDataOutput];
 

Соображения производительности для обработки видео

Необходимо установить вывод сеанса в самое низкое практическое разрешение для приложения. Установка вывода к более высокому разрешению, чем необходимые отходы, обрабатывающие циклы и напрасно, использует питание.

Необходимо гарантировать что реализация captureOutput:didOutputSampleBuffer:fromConnection: в состоянии обработать демонстрационный буфер в количестве времени, выделенном кадру. Если это берет слишком долго, и Вы содержите на видеокадры, Основа AV прекращает поставлять кадры, не только Вашему делегату, но также и к другим выводам, таким как уровень предварительного просмотра.

Можно использовать вывод видеоданных получения minFrameDuration свойство, чтобы быть уверенными у Вас есть достаточно времени для обработки кадра — за счет наличия более низкой частоты кадров, чем иначе имел бы место. Вы могли бы также удостовериться что alwaysDiscardsLateVideoFrames свойство установлено в YES (значение по умолчанию). Это гарантирует, что любые последние видеокадры отброшены, а не вручены Вам для обработки. Также, если Вы записываете, и не имеет значения, если бы выходная известность является немного поздней, и Вы предпочли бы получать всех их, можно установить значение свойства в NO. Это не означает, что кадры не будут отброшены (т.е. кадры могут все еще быть отброшены), но что они не могут быть отброшены как рано, или как эффективно.

Получение неподвижных изображений

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

Форматы пикселя и форматы кодировки

Различные устройства поддерживают различные форматы изображения. Можно узнать, какой пиксель и типы кодека поддерживаются использованием устройства availableImageDataCVPixelFormatTypes и availableImageDataCodecTypes соответственно. Каждый метод возвращает массив поддерживаемых значений для определенного устройства. Вы устанавливаете outputSettings словарь для указания формата изображения Вы хотите, например:

AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = @{ AVVideoCodecKey : AVVideoCodecJPEG};
[stillImageOutput setOutputSettings:outputSettings];

Если Вы хотите получить изображение JPEG, Вы не должны обычно указывать свой собственный формат сжатия. Вместо этого необходимо позволить выводу неподвижного изображения сделать сжатие для Вас, так как аппаратно ускорено его сжатие. При необходимости в представлении данных изображения можно использовать jpegStillImageNSDataRepresentation: добираться NSData объект, не повторно сжимая данные, даже если Вы изменяете метаданные изображения.

Получение изображения

Когда Вы хотите получить изображение, Вы отправляете вывод a captureStillImageAsynchronouslyFromConnection:completionHandler: сообщение. Первым параметром является соединение, которое Вы хотите использовать для получения. Необходимо искать соединение, входной порт которого собирает видео:

AVCaptureConnection *videoConnection = nil;
for (AVCaptureConnection *connection in stillImageOutput.connections) {
    for (AVCaptureInputPort *port in [connection inputPorts]) {
        if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
            videoConnection = connection;
            break;
        }
    }
    if (videoConnection) { break; }
}

Второй параметр captureStillImageAsynchronouslyFromConnection:completionHandler: блок, берущий два параметра: a CMSampleBuffer непрозрачный тип, содержащий данные изображения и ошибку. Сам демонстрационный буфер может содержать метаданные, такие как словарь EXIF, как присоединение. Если Вы хотите, но отмечаете оптимизацию изображениями JPEG, обсужденными в Форматах пикселя и Форматах кодировки, можно изменить присоединения.

[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:
    ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
        CFDictionaryRef exifAttachments =
            CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
        if (exifAttachments) {
            // Do something with the attachments.
        }
        // Continue as appropriate.
    }];

Показ пользователя, что зарегистрировано

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

Предварительный просмотр видео

Можно предоставить пользователю предварительный просмотр того, что зарегистрировано с помощью AVCaptureVideoPreviewLayer объект. AVCaptureVideoPreviewLayer подклассCALayer (см. Базовое Руководство по программированию Анимации. Вам не нужны никакие выводы для показа предварительного просмотра.

Используя AVCaptureVideoDataOutput класс предоставляет клиентскому приложению возможность получить доступ к видео пикселям, прежде чем они будут представлены пользователю.

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

AVCaptureSession *captureSession = <#Get a capture session#>;
CALayer *viewLayer = <#Get a layer from the view in which you want to present the preview#>;
 
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:captureSession];
[viewLayer addSublayer:captureVideoPreviewLayer];

В целом уровень предварительного просмотра ведет себя как любой другой CALayer объект в дереве рендеринга (см. Базовое Руководство по программированию Анимации). Можно масштабировать изображение и выполнить трансформации, вращения, и т.д. так же, как Вы были бы любой уровень. Одно различие - то, что Вы, возможно, должны установить уровень orientation свойство, чтобы указать, как это должно повернуть изображения, прибывающие из камеры. Кроме того, можно протестировать на поддержку устройства зеркального отражения видео путем запросов supportsVideoMirroring свойство. Можно установить videoMirrored свойство как требуется, несмотря на то, что, когда automaticallyAdjustsVideoMirroring свойство установлено в YES (значение по умолчанию), значение зеркального отражения автоматически установлено на основе конфигурации сеанса.

Видео режимы силы тяжести

Уровень предварительного просмотра поддерживает три режима силы тяжести, что Вы устанавливаете использование videoGravity:

  • AVLayerVideoGravityResizeAspect: Это сохраняет форматное соотношение, оставляя черные полосы, где видео не заполняет доступную экранную область.

  • AVLayerVideoGravityResizeAspectFill: Это сохраняет форматное соотношение, но заполняет доступную экранную область, обрезая видео при необходимости.

  • AVLayerVideoGravityResize: Даже если выполнение так искажает изображение, это просто расширяет видео для заполнения доступной экранной области.

Используя “Касание для фокусирований” с предварительным просмотром

Необходимо заботиться при реализации касания к фокусу в сочетании с уровнем предварительного просмотра. Необходимо составить ориентацию предварительного просмотра и серьезность уровня, и для возможности, что может быть зеркально отражен предварительный просмотр. См. проект примера кода AVCam для iOS для реализации этой функциональности.

Показ уровней звука

Для контроля средних и пиковых уровней мощности в звуковом канале в соединении получения Вы используете AVCaptureAudioChannel объект. Уровни звука не являются заметным значением ключа, таким образом, необходимо опрашивать относительно обновленных уровней так часто, как Вы хотите обновить свой пользовательский интерфейс (например, 10 раз в секунду).

AVCaptureAudioDataOutput *audioDataOutput = <#Get the audio data output#>;
NSArray *connections = audioDataOutput.connections;
if ([connections count] > 0) {
    // There should be only one connection to an AVCaptureAudioDataOutput.
    AVCaptureConnection *connection = [connections objectAtIndex:0];
 
    NSArray *audioChannels = connection.audioChannels;
 
    for (AVCaptureAudioChannel *channel in audioChannels) {
        float avg = channel.averagePowerLevel;
        float peak = channel.peakHoldLevel;
        // Update the level meter user interface.
    }
}

Соединение всего этого: получение видеокадров как объекты UIImage

Этот краткий пример кода к иллюстрирует, как можно получить видео и преобразовать кадры, до которых Вы добираетесь UIImage объекты. Это показывает Вам как:

Создайте и сконфигурируйте сеанс получения

Вы используете AVCaptureSession возразите для координирования потока данных от устройства ввода данных AV до вывода. Создайте сеанс и сконфигурируйте его для создания видеокадров среднего разрешения.

AVCaptureSession *session = [[AVCaptureSession alloc] init];
session.sessionPreset = AVCaptureSessionPresetMedium;

Создайте и сконфигурируйте ввод устройства и устройства

Устройства захвата изображения представлены AVCaptureDevice объекты; класс обеспечивает методы для получения объекта для входного типа, который Вы хотите. Устройство имеет один или несколько портов, сконфигурированное использование AVCaptureInput объект. Как правило, Вы используете ввод получения в его конфигурации по умолчанию.

Найдите устройство видеосъемки, затем создайте ввод устройства с устройством и добавьте его к сеансу. Если надлежащее устройство не может быть расположено, то deviceInputWithDevice:error: метод возвратит ошибку ссылкой.

AVCaptureDevice *device =
        [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
 
NSError *error = nil;
AVCaptureDeviceInput *input =
        [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
if (!input) {
    // Handle the error appropriately.
}
[session addInput:input];

Создайте и сконфигурируйте вывод видеоданных

Вы используете AVCaptureVideoDataOutput объект обработать несжатые кадры от получаемого видео. Вы обычно конфигурируете несколько аспектов вывода. Для видео, например, можно указать формат пикселя с помощью videoSettings свойство и прописная буква частота кадров путем установки minFrameDuration свойство.

Создайте и сконфигурируйте вывод для видеоданных и добавьте его к сеансу; ограничьте частоту кадров к 15 кадр/с путем установки minFrameDuration свойство к 1/15 секунде:

AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[session addOutput:output];
output.videoSettings =
                @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_32BGRA) };
output.minFrameDuration = CMTimeMake(1, 15);

Объект вывода данных использует делегацию для продажи видеокадров. Делегат должен принять AVCaptureVideoDataOutputSampleBufferDelegate протокол. При установке делегата вывода данных необходимо также предоставить очереди, на которую должны быть вызваны обратные вызовы.

dispatch_queue_t queue = dispatch_queue_create("MyQueue", NULL);
[output setSampleBufferDelegate:self queue:queue];
dispatch_release(queue);

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

Реализуйте демонстрационный буферный метод делегата

В классе делегата реализуйте метод (captureOutput:didOutputSampleBuffer:fromConnection:) когда демонстрационный буфер записан, это вызывают. Выходной объект видеоданных поставляет кадры как CMSampleBuffer непрозрачные типы, таким образом, необходимо преобразовать из CMSampleBuffer непрозрачный тип к a UIImage объект. Функция для этой работы показана в Преобразовании CMSampleBuffer к Объекту UIImage.

- (void)captureOutput:(AVCaptureOutput *)captureOutput
         didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
         fromConnection:(AVCaptureConnection *)connection {
 
    UIImage *image = imageFromSampleBuffer(sampleBuffer);
    // Add your code here that uses the image.
}

Помните, что метод делегата вызывается на очередь, в которой Вы указали setSampleBufferDelegate:queue:; если Вы хотите обновить пользовательский интерфейс, необходимо вызвать любой соответствующий код основного потока.

Запуск и остановка записи

После конфигурирования сеанса получения необходимо гарантировать, что камера имеет разрешение записать согласно предпочтениям пользователя.

NSString *mediaType = AVMediaTypeVideo;
 
[AVCaptureDevice requestAccessForMediaType:mediaType completionHandler:^(BOOL granted) {
    if (granted)
    {
        //Granted access to mediaType
        [self setDeviceAuthorized:YES];
    }
    else
    {
        //Not granted access to mediaType
        dispatch_async(dispatch_get_main_queue(), ^{
        [[[UIAlertView alloc] initWithTitle:@"AVCam!"
                                    message:@"AVCam doesn't have permission to use Camera, please change privacy settings"
                                   delegate:self
                          cancelButtonTitle:@"OK"
                          otherButtonTitles:nil] show];
                [self setDeviceAuthorized:NO];
        });
    }
}];

Если сеанс камеры сконфигурирован, и пользователь утвердил доступ к камере (и при необходимости, микрофон), отправьте a startRunning обменивайтесь сообщениями для запуска записи.

[session startRunning];

Чтобы прекратить записывать, Вы отправляете сеанс a stopRunning сообщение.

Видеосъемка высокой частоты кадров

iOS 7.0 представляет поддержку видеосъемки высокой частоты кадров (также называемый видео «SloMo») на выбранных аппаратных средствах. Полное содержание высокой частоты кадров поддержки платформы Основы AV.

Вы определяете возможности получения устройства с помощью AVCaptureDeviceFormat класс. Этот класс имеет методы, возвращающие поддерживаемые типы среды, частоты кадров, поле зрения, максимум масштабирует фактор, поддерживается ли видео стабилизация и т.д.

Пример кода SloPoke демонстрирует поддержку Основы AV быстрой видеосъемки, определяя, передают ли видеосъемка высокой частоты кадров поддержки оборудования, воспроизведение с помощью различных уровней и время алгоритмы, и редактируя (включая установку масштабов времени для частей состава).

Воспроизведение

Экземпляр AVPlayer управляет большей частью скорости воспроизведения автоматически путем установки setRate: значение метода. Значение используется в качестве множителя для скорости воспроизведения. Значение 1,0 причин, которые нормальное воспроизведение, 0.5 воспроизводит на половине скорости, 5.0, воспроизводит в пять раз быстрее, чем нормальный и т.д.

AVPlayerItem поддержка объектов audioTimePitchAlgorithm свойство. Это свойство позволяет Вам указывать, как аудио играется, когда фильм проигрывается в различных частотах кадров с помощью Time Pitch Algorithm Settings константы.

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

Алгоритм подачи времени

Качество

Защелки к определенной частоте кадров

Диапазон уровня

AVAudioTimePitchAlgorithmLowQualityZeroLatency

Низкое качество, подходящее для ускоренной перемотки, перемотки или низкокачественной речи.

ДА

0.5, 0.666667, 0.8, 1.0, 1.25, 1.5, 2,0 уровня.

AVAudioTimePitchAlgorithmTimeDomain

Умеренное качество, менее дорогое в вычислительном отношении, подходящее для речи.

НЕТ

0.5–2x уровни.

AVAudioTimePitchAlgorithmSpectral

Высшее качество, самое дорогое в вычислительном отношении, сохраняет подачу исходного элемента.

НЕТ

Уровни 1/32–32.

AVAudioTimePitchAlgorithmVarispeed

Высококачественное воспроизведение без исправления подачи.

НЕТ

Уровни 1/32–32.

Редактирование

При редактировании Вы используете AVMutableComposition класс для создания временных редактирований.

Экспорт

Экспорт видео на 60 кадр/с использует AVAssetExportSession класс для экспорта актива. Содержание может быть экспортировано с помощью двух методов:

  • Используйте AVAssetExportPresetPassthrough предварительная установка, чтобы избежать повторно кодировать фильм. Это повторно синхронизирует носители с разделами носителей, тегированных как раздел 60 кадр/с, раздел, замедленный или ускоренный раздел.

  • Используйте постоянный экспорт частоты кадров для максимальной совместимости воспроизведения. Установите frameDuration свойство видео состава к 30 кадр/с. Можно также указать подачу времени при помощи установки сеанса экспорта audioTimePitchAlgorithm свойство.

Запись

Вы получаете видео высокой частоты кадров использование AVCaptureMovieFileOutput класс, автоматически поддерживающий запись высокой частоты кадров. Это автоматически выберет корректный уровень тона H264 и скорость передачи.

Чтобы сделать пользовательскую запись, необходимо использовать AVAssetWriter класс, требующий некоторой дополнительной установки.

assetWriterInput.expectsMediaDataInRealTime=YES;

Эта установка гарантирует, что получение может не отставать от входящих данных.