Все еще и видео получение носителей
Для управления получением от устройства, такого как камера или микрофон Вы собираете объекты представлять вводы и выводы и использовать экземпляр AVCaptureSession
скоординировать поток данных между ними. Минимально Вам нужно:
Экземпляр
AVCaptureDevice
представлять устройство ввода данных, такое как камера или микрофонЭкземпляр конкретного подкласса
AVCaptureInput
сконфигурировать порты от устройства ввода данныхЭкземпляр конкретного подкласса
AVCaptureOutput
управлять выводом к файлу ролика или неподвижному изображениюЭкземпляр
AVCaptureSession
скоординировать поток данных от ввода до вывода
Чтобы показать пользователю предварительный просмотр того, что записывает камера, можно использовать экземпляр AVCaptureVideoPreviewLayer
(подкласс CALayer
).
Можно сконфигурировать многократные вводы и выводы, скоординированные единственным сеансом:
Для многих приложений это - столько подробности, сколько Вам нужно. Для некоторых операций, однако, (если Вы хотите контролировать уровни мощности в звуковом канале, например) необходимо рассмотреть, как различные порты устройства ввода данных представлены и как те порты подключены к выводу.
Соединение между вводом получения и выводом получения в сеансе получения представлено AVCaptureConnection
объект. Вводы получения (экземпляры AVCaptureInput
) имейте один или несколько входных портов (экземпляры AVCaptureInputPort
). Выводы получения (экземпляры AVCaptureOutput
) может принять данные из одного или более источников (например, AVCaptureMovieFileOutput
объект принимает и видеоданные и аудиоданные).
Когда Вы добавляете ввод или вывод к сеансу, соединениям форм сеанса между всеми совместимыми портами вводов получения и получаете выводы. Соединение между вводом получения и выводом получения представлено AVCaptureConnection
объект.
Можно использовать соединение получения, чтобы включить или отключить поток данных от данного ввода или к данному выводу. Можно также использовать соединение для контроля средних и пиковых уровней мощности в звуковом канале.
Используйте сеанс получения для координирования потока данных
AVCaptureSession
объект является центральным объектом координирования, который Вы используете для управления сбором данных. Вы используете экземпляр для координирования потока данных от устройств ввода данных AV до выводов. Вы добавляете устройства захвата изображения и выводы, которые Вы хотите к сеансу, затем запускаете поток данных путем отправки сеанса a startRunning
сообщение и остановка поток данных путем отправки a stopRunning
сообщение.
AVCaptureSession *session = [[AVCaptureSession alloc] init]; |
// Add inputs and outputs. |
[session startRunning]; |
Конфигурирование сеанса
Вы используете предварительную установку на сеансе для указания качества изображения и разрешения, которое Вы хотите. Предварительная установка является константой, идентифицирующей одну из многих возможных конфигураций; в некоторых случаях фактическая конфигурация специфична для устройства:
Символ | Разрешение | Комментарии |
---|---|---|
Высоко | Самое высокое качество записи. Это варьируется для каждого устройства. | |
Носитель | Подходящий для совместного использования Wi-Fi. Фактические значения могут измениться. | |
Низко | Подходящий для совместного использования 3G. Фактические значения могут измениться. | |
640x480 | VGA. | |
1280x720 | HD на 720 пунктов. | |
Фотография | Полное фото разрешение. Это не поддерживается для видеовыхода. |
Если Вы хотите установить носители специфичная для типа телосложения конфигурация, необходимо проверить, поддерживается ли она прежде, чем установить его, следующим образом:
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
) камеры.
Следующий пример кода выполняет итерации по всем доступным устройствам и регистрирует их имя — и для видеоустройств, их позиции — на модуле.
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]; |
} |
Режимы воздействия
Существует два режима воздействия:
AVCaptureExposureModeContinuousAutoExposure: устройство автоматически корректирует уровень воздействия по мере необходимости.
AVCaptureExposureModeLocked
: Уровень воздействия фиксируется на его текущем уровне.
Вы используете 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
свойство.
Режим факела
В режиме факела флэш-память постоянно позволяется в низкой мощности осветить видеосъемку. Существует три режима факела:
AVCaptureTorchModeOff
: Факел всегда выключен.AVCaptureTorchModeOn
: Факел всегда включен.AVCaptureTorchModeAuto
: Факел автоматически включен и выключен по мере необходимости.
Вы используете hasTorch
определить, имеет ли устройство флэш-память. Вы используете isTorchModeSupported:
метод, чтобы определить, поддерживает ли устройство данный режим флэш-памяти, затем установил режим с помощью torchMode
свойство.
Если устройство связано с рабочим сеансом получения, для устройств с факелом факел только включает.
Видео стабилизация
Кинематографическая vdeo стабилизация доступна для соединений, воздействующих на видео, в зависимости от определенного оборудования устройства. Несмотря на это, не все исходные форматы и разрешения видео поддерживаются.
Включение кинематографической видео стабилизации может также ввести дополнительную задержку в конвейер видеосъемки. Для обнаружения, когда видео стабилизация будет использоваться используйте videoStabilizationEnabled
свойство. enablesVideoStabilizationWhenAvailable
свойство позволяет приложению автоматически включать видео стабилизацию, если это поддерживается камерой. Автоматической стабилизацией по умолчанию отключен вследствие вышеупомянутых ограничений.
Баланс белого
Существует два режима баланса белого:
AVCaptureWhiteBalanceModeLocked
: Режим баланса белого фиксируется.AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance
: Камера постоянно корректирует баланс белого по мере необходимости.
Вы используете isWhiteBalanceModeSupported:
метод, чтобы определить, поддерживает ли устройство данный режим баланса белого, затем установил режим с помощью whiteBalanceMode
свойство.
Можно использовать adjustingWhiteBalance
свойство, чтобы определить, изменяет ли устройство в настоящее время свои настройки баланса белого. Можно наблюдать свойство с помощью наблюдения значения ключа, которое будет уведомлено, когда устройство запускает и прекращает изменять свои настройки баланса белого.
Ориентация задающего устройства
Вы устанавливаете желаемую ориентацию на a AVCaptureConnection
указать, как Вы хотите изображения, ориентированные в AVCaptureOutput
(AVCaptureMovieFileOutput
, AVCaptureStillImageOutput
и AVCaptureVideoDataOutput
) для соединения.
Используйте AVCaptureConnection
supportsVideoOrientation
свойство, чтобы определить, ли поддержки устройства, изменяющие ориентацию видео, и 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
. Вы используете:
AVCaptureMovieFileOutput
выводить к файлу роликаAVCaptureVideoDataOutput
если Вы хотите обработать кадры от получаемого видео, например, создать Ваш собственный уровень представленияAVCaptureAudioDataOutput
если Вы хотите обработать получаемые аудиоданныеAVCaptureStillImageOutput
если Вы хотите получить неподвижные изображения с сопроводительными метаданными
Вы добавляете выводы к использованию сеанса получения 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 до выводаНайдите
AVCaptureDevice
объект для входного типа Вы хотитеСоздайте
AVCaptureDeviceInput
объект для устройстваСоздайте
AVCaptureVideoDataOutput
возразите для создания видеокадровРеализуйте делегата к
AVCaptureVideoDataOutput
возразите для обработки видеокадровРеализуйте функцию для преобразования CMSampleBuffer, полученного делегатом в a
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
класс. Этот класс имеет методы, возвращающие поддерживаемые типы среды, частоты кадров, поле зрения, максимум масштабирует фактор, поддерживается ли видео стабилизация и т.д.
Получение поддерживает полные 720 пунктов (1280 x 720 пикселей) разрешение в 60 кадрах в секунду (кадр/с) включая видео стабилизацию, и сбрасываемые P-кадры (функция H264 закодировала фильмы, позволяющие фильмам воспроизводить гладко даже на более медленных и более старых аппаратных средствах.)
Воспроизведение улучшило аудио поддержку медленного и быстрого воспроизведения, позволение подачи времени аудио может быть сохранено в медленнее или более быстрые скорости.
Редактирование имеет полную поддержку масштабированных редактирований в непостоянных составах.
Экспорт предоставляет две возможности при поддержке фильмов на 60 кадр/с. Переменная частота кадров, медленное или быстрое движение, может быть сохранена, или фильм и преобразована в произвольную более медленную частоту кадров, такую как 30 кадров в секунду.
Пример кода SloPoke демонстрирует поддержку Основы AV быстрой видеосъемки, определяя, передают ли видеосъемка высокой частоты кадров поддержки оборудования, воспроизведение с помощью различных уровней и время алгоритмы, и редактируя (включая установку масштабов времени для частей состава).
Воспроизведение
Экземпляр AVPlayer
управляет большей частью скорости воспроизведения автоматически путем установки setRate:
значение метода. Значение используется в качестве множителя для скорости воспроизведения. Значение 1,0 причин, которые нормальное воспроизведение, 0.5 воспроизводит на половине скорости, 5.0, воспроизводит в пять раз быстрее, чем нормальный и т.д.
AVPlayerItem
поддержка объектов audioTimePitchAlgorithm
свойство. Это свойство позволяет Вам указывать, как аудио играется, когда фильм проигрывается в различных частотах кадров с помощью Time Pitch Algorithm Settings
константы.
Следующая таблица показывает поддерживаемые алгоритмы подачи времени, качество, заставляет ли алгоритм аудио хватать к определенным частотам кадров и диапазону частоты кадров, который поддерживает каждый алгоритм.
Алгоритм подачи времени | Качество | Защелки к определенной частоте кадров | Диапазон уровня |
---|---|---|---|
Низкое качество, подходящее для ускоренной перемотки, перемотки или низкокачественной речи. | 0.5, 0.666667, 0.8, 1.0, 1.25, 1.5, 2,0 уровня. | ||
Умеренное качество, менее дорогое в вычислительном отношении, подходящее для речи. | 0.5–2x уровни. | ||
Высшее качество, самое дорогое в вычислительном отношении, сохраняет подачу исходного элемента. | Уровни 1/32–32. | ||
Высококачественное воспроизведение без исправления подачи. | Уровни 1/32–32. |
Редактирование
При редактировании Вы используете AVMutableComposition
класс для создания временных редактирований.
Создайте новое
AVMutableComposition
экземпляр с помощьюcomposition
метод класса.Вставьте свой видео актив с помощью
insertTimeRange:ofAsset:atTime:error:
метод.Установите масштаб времени части использования состава
scaleTimeRange:toDuration:
Экспорт
Экспорт видео на 60 кадр/с использует AVAssetExportSession
класс для экспорта актива. Содержание может быть экспортировано с помощью двух методов:
Используйте
AVAssetExportPresetPassthrough
предварительная установка, чтобы избежать повторно кодировать фильм. Это повторно синхронизирует носители с разделами носителей, тегированных как раздел 60 кадр/с, раздел, замедленный или ускоренный раздел.Используйте постоянный экспорт частоты кадров для максимальной совместимости воспроизведения. Установите
frameDuration
свойство видео состава к 30 кадр/с. Можно также указать подачу времени при помощи установки сеанса экспортаaudioTimePitchAlgorithm
свойство.
Запись
Вы получаете видео высокой частоты кадров использование AVCaptureMovieFileOutput
класс, автоматически поддерживающий запись высокой частоты кадров. Это автоматически выберет корректный уровень тона H264 и скорость передачи.
Чтобы сделать пользовательскую запись, необходимо использовать AVAssetWriter
класс, требующий некоторой дополнительной установки.
assetWriterInput.expectsMediaDataInRealTime=YES; |
Эта установка гарантирует, что получение может не отставать от входящих данных.