Управление QTCompressionOptions - обзор выборки QTCompressionOptionsWindow
Этот Technote описывает некоторые методы, используемые в создании примера кода QTCompressionOptionsWindow. Особенно, выборка демонстрирует исключительный метод для управления конфигурируемыми пользователем настройками сжатия при использовании методов получения и классов, доступных в платформе Набора QuickTime (QTKit.framework).
Загрузите пример кода QTCompressionOptionsWindow для следования вперед.
Введение
Если Вы будете QuickTime или разработчиком Какао, работающим с аудио и видеосъемкой, то Вы захотите использовать в своих интересах новые классы получения и методы, внедренные в Mac OS X v10.5 и последний выпуск QuickTime. Существует теперь 15 новых классов получения, доступных в платформе QTKit, которые разработаны для расширения, диапазон разработчиков мультимедийных служб может соединиться в их мультимедийные приложения.
Эти новые классы получения и методы предоставляют Вашему приложению прокласс, точное кадром получение аудио и видео носителей из одного или более внешних источников. Ваши полученные носители могут быть рекордными к фильму в формате QuickTime (.mov) файл или выведенный на экран в представлении Cocoa и могут также быть сжаты с помощью единого набора форматов сжатия. Можно также непосредственно получить доступ к распакованным накопительным буферам для пользовательской обработки.
Этот Technote описывает функции сжатия Получения QTKit с помощью примера кода QTCompressionOptionsWindow, демонстрирующего, как получить видео носители к файлу ролика с помощью методов, доступных в классах получения QTKit, также позволяя пользователю выбрать, как будет сжато то видео.
После быстрого чтения Руководства по программированию Получения QTKit задача может казаться очень простой сделать, требуя использования только нескольких классов получения; QTCaptureDevice, QTCaptureDeviceInput, QTCaptureSession, QTCaptureView и QTCaptureMovieFileOutput. Экземпляры этих объектов, все совмещают как ряд lego части, создающие «График Получения», выполняющий работу.
Однако что, если Вы не только хотите указать метод сжатия для получаемых носителей, но также и хотеть управлять списком настроек сжатия через пользовательский интерфейс. Как могут быть выполнены те задачи?
Пример кода QTCompressionOptionsWindow демонстрирует метод, который можно использовать для управления настройками сжатия. Это достигается при помощи автономного допускающего повторное использование класса, обеспечивающего пользовательский интерфейс для выбора различных настроек сжатия через Окно Опций Сжатия Носителей, как показано на рисунке 1.
Можно выполнить это меньше чем с 30 строками кода Objective C путем использования в своих интересах привязки Какао. Загрузите выборку QTCompressionOptionsWindow и следуйте вперед.
Выборка содержит три файла, обсужденные в этом Technote:
Заголовочный файл класса -
QTCompressionOptionsWindow.hФайл реализации класса -
QTCompressionOptionsWindow.mКласс файл NIB -
QTCompressionOptionsWindow.nib

Класс QTCompressionOptions
Настройки сжатия представлены в Платформе Получения QTKit QTCompressionOptions класс. QTCompressionOptions объекты представляют ряд настроек сжатия для определенного типа носителей; QTMediaTypeVideo или QTMediaTypeSound. Каждый экземпляр QTCompressionOptions используется для описания единственной установки сжатия и создаются с помощью ряда предварительных установок, включенных именованным идентификатором сжатия.
Создать a QTCompressionOptions объект, описывающий сжатие H.264 с максимальным размером 320x240, Вы используете NSString идентификатор QTCompressionOptions240SizeH264Video с методом класса compressionOptionsWithIdentifier: (Перечисление 1).
Перечисление 1 Создает настройки сжатия, описывающие H.264 320x240.
QTCompressionOptions *myCompressionOptions;
myCompressionOptions = [QTCompressionOptions compressionOptionsWithIdentifier:
QTCompressionOptions240SizeH264Video];
[mCaptureMovieFileOutput setCompressionOptions:myCompressionOptions
forConnection:mVideoConnection]; |
В то время как это очень просто сделать, настройки сжатия являются hardcoded и поэтому ограниченными практическими применениями. Для представления пользовательского интерфейса необходимо динамично создать список всех опций сжатия, в настоящее время доступных для данного типа среды, и вывести на экран их соответственно.
QTCompressionOptions метод класса compressionOptionsIdentifiersForMediaType: идеально, так как это возвращает массив идентификаторов сжатия, которые могут использоваться для создания QTCompressionOptions экземпляры. Только идентификаторы, которые допустимы на существующей системе, будут возвращены, например если Промежуточный Кодек Apple не будет доступен на существующей системе QTCompressionOptionsLosslessAppleIntermediateVideo идентификатор не будет возвращен в массиве.
Интерфейс класса QTCompressionOptionsWindow
Теперь, когда у Вас есть идея того, как Получение QTKit управляет настройками сжатия и как создать эти объекты настроек динамично, можно определить простой класс, управляющий обоими произвольное число QTCompressionOptions экземпляры и Окно.
@interface QTCompressionOptionsWindow : NSWindowController {
@private
IBOutlet NSArrayController *mOptionsArray;
NSString *mMediaType;
IBOutlet id delegate;
}
// designated initializer
- (id)initWithMediaType:(NSString *)inMediaType;
// compression options of this media type are being managed by the controller
- (NSString *)mediaType;
// manage compression options for the media type passed in, should only be
// QTMediaTypeVideo or QTMediaTypeSound, nil is equivalent to QTMediaTypeVideo
- (OSStatus)setMediaType:(NSString *)inMediaType;
// returns the selected QTCompressionOptions instance
// that may be used with -setCompressionOptions:forConnection:
- (QTCompressionOptions *)compressionOptions;
// closes the window and notifies the client of the class via delegation
- (IBAction)closeWindow:(id)sender;
// manages controller delegate
- (id)delegate;
- (void)setDelegate:(id)value;
@end
// a client of this class should implement this delegate method
// which is called when the compression options window is closed
// the client may ask the sender for the selected QTCompressionOptions instance
@interface NSObject (QTCompressionOptionsWindowDelegate)
- (void)compressionOptionsWindowDidClose:(id)sender;
@end |
С тех пор NSWindowController может управлять окном, сохраненным в файле пера, и будет заботиться о загрузке и отображении окна, закрывая его когда надлежащее размещение Окна обработки и т.д., QTCompressionOptionsWindow класс будет подклассом NSWindowController и получите всю эту функциональность бесплатно.
NSArrayController ссылаемый mOptionsArray будет использоваться для управления набором QTCompressionOptions объекты. NSArrayController привязка совместимый класс, управляющий набором объектов. Путем использования в своих интересах привязки Вы в состоянии посредничать между моделью (т.е. массив QTCompressionOptions объекты) и пользовательский интерфейс, не имея необходимость писать любой код.
Так как класс управляет массивом QTCompressionOptions возражает определенный для типа среды (также QTMediaTypeVideo или QTMediaTypeSound), класс отслеживает эту строку типа среды в mMediaType.
Наконец, id требуется для объекта делегата. Делегат является объектом, действующим от имени, или при взаимодействии с, другой объект, когда тот объект встречается с событием. В нашем случае, когда Окно Опций Сжатия Носителей закрывается, a compressionOptionsWindowDidClose: сообщение отправляется в объект, зарегистрированный как делегат. Это сообщение позволяет делегату просить и использовать выбранную установку сжатия специализированным способом.
Пользовательский интерфейс QTCompressionOptionsWindow
Теперь, когда класс Objective C определяется, Вы используете Интерфейсного Разработчика для создания пользовательского интерфейса как показано на рисунке 2.

Все интерфейсные элементы на рисунке 2 распространены и должны легко быть распознаны. Основные элементы; NSPopUpButton, используемый для перечисления локализованных имен дисплея для каждого выбора сжатия и a NSTextView используемый для отображения локализованного сводного текста опций сжатия для в настоящее время выбираемой опции сжатия. NSButton используется для отклонения Окна, сохраняющего выбранную опцию сжатия.
NSArrayController в пере вызывается «Контроллером массива CompressionOptions» и объект, который будет управлять набором QTCompressionOptions экземпляры для нас и промежуточный между этим набором и нашими элементами пользовательского интерфейса. Когда файл пера будет загружен, он будет автоматически подключен с mOptionsArray выход.
Владелец файла
Отметьте класс объекта Владельца Файла на рисунке 3. Это было установлено отразить, что это будет представлять экземпляр QTCompressionOptionsWindow класс.
Владелец Файла действует как заполнитель для объекта, который будет управлять содержанием файла пера после того, как это будет загружено. Наш файл пера содержит два объекта, которые должны именоваться экземплярами QTCompressionOptionsWindow; NSWindow названный «Окно CompressionOptions» и NSArrayController названный «Контроллер массива CompressionOptions».
Объект Владельца Файла обеспечивает способ сделать соединения с объектами в файле пера как NSArrayController и QTCompressionOptionsWindow класс. Когда файл пера будет загружен, Владелец Файла будет установлен быть экземпляром QTCompressionOptionsWindow.
Рисунок 3 показывает, что поле Класса было изменено на «QTCompressionOptionsWindow» как владелец Файла Класс Идентити.

Как только Владелец Файла сконфигурирован, соединения могут быть сделаны между выходами (IBOutlet) в классе и объектах в файле пера. Рисунок 4 показывает соединения для NSArrayController который подключен с mArrayController как упомянуто ранее и NSWindow который подключен с window.
То, когда файл пера загружается, возражает в файле пера, создаются, инициализируются и соединяются должным образом.

Реализация класса QTCompressionOptionsWindow
Если Вы берете быстрый тур по методам, используемым для работы с QTCompressionOptionsWindow экземпляры (код в QTCompressionOptions.m), Вы будете видеть, как это реализовано.
initWithMediaType: метод используется для инициализации QTCompressionOptionsWindow объект. Этот метод принимает любого QTMediaTypeVideo или QTMediaTypeSound идентификатор типа среды в зависимости от списка настроек сжатия Вы хотите, чтобы Окно Опций Сжатия Носителей представило пользователю.
Перечисление 2 initWithMediaType: метод.
// designated initializer
// call with QTMediaTypeVideo or QTMediaTypeSound to initalize
- (id)initWithMediaType:(NSString *)inMediaType
{
// call NSWindowController designated initializer
if (self = [super initWithWindow:nil]) {
// inappropriate media types will bail on init
if ([self setMediaType:inMediaType]) {
[self release];
return nil;
}
}
return self;
} |
setMediaType: метод вызывается во время объектной инициализации (и может также использоваться после инициализации для изменения типов среды). Этот метод выполняет большую часть работы в этом классе. Это принимает идентификатор типа среды, выполняет некоторые основные проверки, чтобы удостовериться, что тип среды допустим, и файл пера загружается, тогда спрашивает QTCompressionOptions класс для всех доступных идентификаторов типов сжатия для указанного типа среды. Путем итерации, хотя возвращенный массив идентификаторов опции сжатия метод создает экземпляры QTCompressionOptions для каждого идентификатора и просто заполняет NSArrayController.
Перечисление 3 setMediaType: метод.
// set the media type of the compression options you want managed
- (OSStatus)setMediaType:(NSString *)inMediaType
{
// accept nil as a request for the default - the more common vide options
if (nil == inMediaType) inMediaType = QTMediaTypeVideo;
// only accept Video or Audio since they are the only valid compression option media types at this time
if ((NO == [inMediaType isEqualToString:QTMediaTypeVideo])
&& (NO == [inMediaType isEqualToString:QTMediaTypeSound])) return invalidMedia;
// only do the set up if the media type has changed
if ([mMediaType isEqualToString:inMediaType]) return noErr;
[mMediaType release];
mMediaType = [inMediaType retain];
// make sure the nib is actually loaded at this time,
// required for our connections to the array controller and so on
if (![self isWindowLoaded]) { [self window]; }
// make sure the array controller is empty
[mOptionsArray removeObjects:[mOptionsArray arrangedObjects]];
// load it up with the currently chosen compression options objects
NSArray *optionsIdentifiers = [QTCompressionOptions
compressionOptionsIdentifiersForMediaType:inMediaType];
NSEnumerator *enumerator = [optionsIdentifiers objectEnumerator];
UInt8 index;
UInt8 count = [optionsIdentifiers count];
for (index = 0; index < count; index++) {
QTCompressionOptions *options = [QTCompressionOptions
compressionOptionsWithIdentifier:[enumerator nextObject]];
[mOptionsArray addObject:options];
}
[mOptionsArray setSelectionIndex:0];
return noErr;
} |
setDelegate: метод используется для регистрации класса контроллера как делегата. Когда Окно Опций Сжатия Носителей закроется, делегата вызовут.
Перечисление 4 setDelegate метод.
- (void)setDelegate:(id)inDelegate { delegate = inDelegate; } |
showWindow: метод, наследованный от NSWindowController клиент этого класса вызовет для отображения Окна Опций Сжатия Носителей. Это позволяет пользователю выбирать сжатие, сходящее с раскрывающегося списка. Никакой код, необходимый здесь.
closeWindow: действие автоматически отправляется в QTCompressionOptionsWindow экземпляр через обязательный механизм (см. ниже), когда нажата кнопка 'OK'. Окно Опций Сжатия Носителей тогда закрывается, сохраняя выбранную установку сжатия пользователей.
Перечисление 5 closeWindow действие.
- (IBAction)closeWindow:(id)sender { [self close]; } |
После того, как окно закрывается a compressionOptionsWindowDidClose: сообщение отправляется в объект, зарегистрированный как делегат. Перечисление 6.
Отправка перечисления 6 compressionOptionsWindowDidClose: делегату.
// inform the client of this class that the window has been closed
// the client will then be able to ask for the currently selected
// compression options object
- (void)close
{
[super close];
if (nil != delegate && [delegate respondsToSelector:@selector(compressionOptionsWindowDidClose:)] ) {
[delegate compressionOptionsWindowDidClose:self];
}
} |
Делегат может тогда получить в настоящее время выбираемые настройки сжатия путем отправки a compressionOptions: обменивайтесь сообщениями к отправителю.
Рисунок 5 является визуальным представлением типичной вызывающей последовательности при использовании QTCompressionOptionsWindow класс.

Используя привязку какао
Привязка является способом подключить элементы пользовательского интерфейса к их базовым данным, не пишущий много из (или никто) код связующего звена для синхронизации двух.
Для реализации пользовательского интерфейса соединение, названное привязкой, создается между NSArrayController (который управляет набором QTCompressionOptions объекты) и элементы пользовательского интерфейса (NSPopUpButton и NSTextView) где мы хотим информацию, возвращенную каждым QTCompressionOptions экземпляр выведен на экран.
QTCompressionOptions имеет два метода, возвращающиеся, строки раньше заполняли и раскрывающееся и текстовое представление.
Перечисление 7 QTCompressionOptions методы дисплея.
- (NSString *)localizedDisplayName; - (NSString *)localizedCompressionOptionsSummary; |
Содержание раскрывающегося предоставлено путем отправки localizedDisplayName обменивайтесь сообщениями каждому QTCompressionOptions экземпляр в массиве, которым управляют NSArrayController. Когда элемент выбран, localizedCompressionOptionsSummary сообщение отправляется в выбранный QTCompressionOptions экземпляр и возвращенный NSString выведен на экран в текстовом представлении. Это посредничество между пользовательским интерфейсом и содержанием массива выполняется автоматически для нас NSArrayController.
Вот то, как это устанавливается в Интерфейсном Разработчике:
NSPopUpButton
Значения содержания
В разделе Value Selection Инспектора Привязки для NSPopUpButton, свяжите Значения Содержания с NSArrayController. Это сделано путем проверки, «Связывают с»: флажок и выбор «CompressionOptions Array Controller» из списка.
Значения содержания являются массивами строк, выведенных на экран как элементы в NSPopUpButton.
Ключ Контроллера устанавливается к arrangedObjects который возвращает массив из контроллера, и Ключевой Путь Модели localizedDisplayName.
Установление этой привязки в Интерфейсном Разработчике эквивалентно программно отправке localizedDisplayName передайте каждый из управляемых QTCompressionOptions экземпляры и заполнят раскрывающееся со значениями возвращаемой строки.


Выбранный индекс
В разделе Value Selection Инспектора Привязки для NSPopUpButton, свяжите Выбрал Index к NSArrayController. Это сделано путем проверки, «Связывают с»: флажок и выбор «CompressionOptions Array Controller» из списка.
Выбрал Index, целочисленное значение, указывающее индекс выбранного пункта в NSPopUpButton. Когда выбор изменяется в NSPopUpButton, это значение обновляется с индексом недавно выбранный пункт.
Ключ Контроллера устанавливается к selectionIndex который возвращает индексное значение первого объекта в выборе.


NSTextView
Значение
В разделе Value Selection Инспектора Привязки для NSTextView, свяжите Значение с NSArrayController. Это сделано путем проверки, «Связывают с»: флажок и выбор «CompressionOptions Array Controller» из списка.
Значение NSString это выведено на экран как содержание NSTextView.
Ключ Контроллера устанавливается к selection который возвращает в настоящее время выбранный объект, и Ключевой Путь Модели localizedCompressionOptionsSummary.
Установление этой привязки в Интерфейсном Разработчике эквивалентно программно отправке localizedCompressionOptionsSummary обменивайтесь сообщениями к в настоящее время выбираемый QTCompressionOptions экземпляр и отображение возвращаемой строки в текстовом представлении. Мы знаем то, что индекс для в настоящее время выбранный пункт из-за вышеупомянутой Выбранной Индексной привязки.


NSButton
Target
В разделе Target Инспектора Привязки для NSButton, свяжите Target с Владельцем Файла (помните, что Владелец Файла представляет QTCompressionOptionsWindow). Это сделано путем проверки, «Связывают с»: флажок и выбор «File's Owner» из списка.
Target является объектом, получающим сообщение, соответствующее селекторному имени когда NSButton щелкается.
Ключевой Путь Модели self и Селекторное Имя closeWindow:.
Установление этой привязки в Интерфейсном Разработчике эквивалентно программно отправке closeWindow: обменивайтесь сообщениями к экземпляру QTCompressionOptionsWindow когда нажата кнопка 'OK'.


Используя QTCompressionOptionsWindow в Вашем приложении
Используя QTCompressionOptionsWindow берет очень мало кода. Вот пример некоторого типичного кода, который может использоваться, чтобы создать и использовать экземпляр QTCompressionOptionsWindow.
Объявите ссылку на a QTCompressionOptionsWindow экземпляр в Вашем классе контроллера.
Перечисление 8 MyController.h.
#import <QTCompressionOptionsWindow.h> @interface MyController : NSObject { ... // the Compression Options Window QTCompressionOptionsWindow *mCompressionOptionsWindow; } ... |
Выделите экземпляр QTCompressionOptionsWindow и инициализируйте его с типом среды в этом случае QTMediaTypeVideo. Тогда установите делегата (наиболее вероятно Ваш пользовательский контроллер, т.е. self).
Перечисление 9 MyController.m awakeFromNib .
- (void)awakeFromNib
{
// code to initialize capture objects
...
// ******** Compression Options Window *****
// create our window with the media type and set ourselves as the delagate
// you could also instantiate the window directly in the nib and hook up the deleate
// then simply call showWindow or setMediaType if you want to change the list of compression options shown
mCompressionOptionsWindow = [[QTCompressionOptionsWindow alloc] initWithMediaType:QTMediaTypeVideo];
if (nil == mCompressionOptionsWindow) {
NSLog(@"Compression Options Window did not load!\n");
return;
}
[mCompressionOptionsWindow setDelegate:self];
...
} |
Выведите на экран окно в некоторое будущее время как требуется.
Перечисление 10 MyController.m showCompressionOptionsWindow: .
- (IBAction)showCompressionOptionsWindow:(id)sender { [mCompressionOptionsWindow showWindow:sender]; } |
Реализуйте вызванный метод делегата compressionOptionsWindowDidClose: когда Окно Опций Сжатия Носителей закрывается, который вызывают.
Этот метод делегата может получить настройки сжатия, выбранные из раскрывающегося списка путем отправки сообщения compressionOptions к sender( QTCompressionOptionsWindow экземпляр), который возвратится QTCompressionOptions экземпляр выбран в раскрывающемся. Это возвратилось QTCompressionOptions экземпляр тогда используется для установки желаемых настроек сжатия для носителей, сохраняемых к файлу.
Отправьте QTCaptureFileOutput экземпляр a setCompressionOptions:forConnection: сообщение и передача это возвращенный QTCompressionOptions экземпляр для надлежащего соединения, таким образом устанавливая пользователя выбранные настройки сжатия для того мультимедийного потока.
Перечисление 11 метод делегата MyController.m.
// when the options window is closed this delegate method gets called
// ask for the chosen QTCompressionOptions object and configure the file output
// object accordingly
- (void)compressionOptionsWindowDidClose:(id)sender
{
// get the selected compression setting
QTCompressionOptions *myCompressionOptions = [sender compressionOptions];
if (nil != myCompressionOptions) {
[mCaptureSession stopRunning];
// configure the file output to compress this connection using the chosen
// compression settings
[mCaptureMovieFileOutput setCompressionOptions:myCompressionOptions
forConnection:[[mCaptureMovieFileOutput connections] lastObject]];
[mCaptureSession startRunning];
// update the UI so it displays the chosen compression type
self.displayName = [myCompressionOptions localizedDisplayName];
NSLog(@"%@\n", [myCompressionOptions localizedDisplayName]);
} else {
NSLog(@"Bad Compression Options Object Returned!\n");
}
} |
Заключение
Путем использования в своих интересах привязки Какао и стандартных элементов пользовательского интерфейса, Вы видели, как создать пользовательский интерфейс для использования с платформой Получения QTKit меньше чем с 30 строками кода Objective C. Это, конечно, просто царапает поверхность того, что может быть сделано с QTKit и Какао.
Эксперимент с кодом, подробно остановитесь на нем, сделайте его уникальным для Вашего приложения и больше всего, весело проведите время.
Ссылки
История версии документа
| Дата | Примечания |
|---|---|
| 11.03.2008 | Передовая статья |
| 04.03.2008 | Новый документ, что вводный обзор выборки QTCompressionOptionsWindow демонстрация одного способа управлять объектами QTCompressionOptions. |