Using the QTKit Framework

OSXDEV

Jump to: navigation, 찾기

QuickTime의 심장은 그 저변에 자리잡은 강력하고, 확장가능하며, 유연한 종합 프레임워크에 있다. 이 프레임워크는 200종이 넘는 미디어 타입을 디스플레이하고, 임포트, 익스포트, 변형 그리고 캡처하는 기능을 개발자들에게 제공한다. 그러나 최근까지, 코코아 어플리케이션에서 이 힘을 쓰는 것은 그다지 쉽지만은 않았다. Mac OS X Tiger가 발표되기 이전에는, QuickTime 파일의 디스플레이와 재생외의 모든 작업은 대부분의 코코아 개발자들에게 아주 생소한 Carbon API 세트를 사용해야만 했다.

그 모든 것이 완전히 바뀌었다. 재디자인된 코어 아키텍처와 현대적인 코코아 인터페이스를 제공하는 QTKit이라는 인터페이스를 가진 QuickTime 7이 Mac OS X Tiger와 함께 발표되었기 때문이다. QTKit은 코코아 개발자들에게 QuickTime의 기능에 대한 유용한 서브세트를 제공한다. 단지 QuickTime 무비를 재생시키는 것만이 아니라, 편집하고, 자르고, 연결하고 또 압축 방식을 바꿀 수도 있다. 그리고 QTKit이 제공하는 기능 이상이 필요하면, 하부의 QuickTime 프리미티브들을 쉽게 얻을 수 있게 해주며 QuickTime 프로시저 API에 있는 2500개가 넘는 함수들을 직접 쓸 수 있게 해 준다.

본질적으로, QTKit은 QuickTime을 Mac OS X가 제공하는 최고의 프로그래밍 환경으로의 깊은 차원의 통합을 가져온다.

이 글은 QTKit 프레임워크가 어떻게 구성되는 지를 알려주고 시작하기 위해 이해해야 할 핵심적인 개념들을 소개한다. 먼저, QuickTime이 왜 그렇게 중요한지와 개발자들에게 무엇을 제공하는 지를 살펴보자.

목차

[편집] 퀵타임의 이점

QuickTime은 애플의 최신 멀티미디어 플랫폼이다. 이것은 high-definition 비디오와 오디오를 재생하는 것부터, immersive한 환경을 만들어내는 것까지 모든 것을 가능하게 한다. QuickTime은 현존하는 최고의 파워풀하고 방대한 디지털 미디어 프레임워크이다. iTunes, iMovie 그리고 파이널 컷 프로외에도 써드파티에서 만든 수천가지 프로그램에 힘을 준다. 15년전 출시한 오리지널 QuickTime 파일에서부터 최근의 H.264, MPEG4 그리고 3G파일들에까지, 수많은 테스트를 거쳤다. 그리고, 당신의 어플리케이션에 통합할 수 있다.

QuickTime을 사용하는 이점은 굉장히 많지만, 개발자들을 위한 가장 파워풀한 이점만 다음의 짧은 리스트에 담았다.

  • 최신의 H.264비디오와 AAC오디오 스펙을 지원한다.
  • ISO를 따르는 MPEG-4파일을 만들고 재생할 수 있다.
  • 모바일 멀티미디어를 위한 3GPP와 3GPP2파일을 만들고 재생할 수 있다.
  • 정지 화상, 스트리밍 프로토콜, SMPTE 효과외에 수 많은 다른 산업용 포맷들을 지원한다.
  • 디지털 미디어를 위한 시작부터 끝까지의 솔루션이다.
  • 퍼포먼스 향상을 위해 Tiger에서는 Core Image와 Core Video를 활용한다.

이 기능들과 함께, 당신의 어플리케이션에 QuickTime을 포함시켜야 할 이유는 아주 많다.

이제, QTKit API를 고급차원에서 살펴보자.

[편집] QTKit API 개요

QTKit 프레임워크는 QuickTime의 핵심 기능으로의 직접적인 엑세스를 제공한다. 여기에는 5개의 클래스와, 두개의 데이타 구조체 그리고 많은 유용한 메소드들과, 함수, 프로토콜이 있다. API의 기본 구조는 다음 그림과 같다.

그림:a_qt_usingqtkit_Api.jpg

QTKit에 있는 두개의 기본적인 클래스는 QTMovie와 QTMovieView이다. 클래스의 이름에서 예상할 수 있듯이, QTMovie는 QuickTime 무비의 코코아 오브젝트 리프리젠테이션을 제공한다. QTMovie 인스턴스는 파일, URLs 혹은 메모리내에 있는 데이타를 참조할 수 있다. NSView의 서브클래스인 QTMovieView는 스크린에 QTMovie인스턴스를 디스플레이 하기 위해 사용된다. 사용자가 직접 무비의 재생을 제어할 수 있도록 컨트롤 바도 옵션으로 제공한다. 커스텀 컨트롤러를 사용하길 원한다면, QTMovieView 클래스가 play, pause, stop 등 재생을 제어할 수 있는 완전한 보완 메소드를 제공한다.

QuickTime 파일 포맷. QuickTime을 특별하게 만드는 것은 그 파일 포맷이 미디어를 어떻게 인코딩했는지를 설명하지 않는 다는 것이다. 그대신, QuickTime 파일 포맷은 오디오, 비디오, 매크로미디어 플래시, 사진등의 다양한 미디어 타입을 담을 수 있는 확장 가능한 컨테이너 개념을 가진다.

QuickTime 파일포맷의 유연성은 그 가치를 인정받아 세계 디지털 미디어의 표준으로 자리잡게 되었다. 현재 MPEG-4, 3GPP, 그리고 3GPP2 스펙의 기반으로 사용되며, Apple과 표준 커뮤니티들이 새롭게 알려지는 미디어 기술을 쉽게 추가할 수 있도록 해 준다.

QTMovie와 QTMovieView 클래스는 코코아에 있는 예전의 NSMovie와 NSMovieView 클래스를 완전히 대체한다. 새 클래스들이 무비의 어트리뷰트를 좀 더 폭 넓고 다양하게 엑세스 하고 설정할 수 있는 만큼 무비 디스플레이와 재생을 더 심도깊게 제어할 수 있도록 해준다. 게다가 코코아 바인딩의 사용이나 NSError 클래스를 이용한 에러 핸들링과 같은 최신 코코아 프로그래밍 방식을 더 충실히 지원한다.

다른 세개의 클래스인 QTrack, QTMedia,QTDataReference와 데이타 스트럭처 QTTime, QTTimeRange 는 QuickTime 무비의 다양한 컴포넌트를 엑세스 할 수 있게 해준다. QTMovie는 QTTrack 오브젝트 세트를 가지며 각각의 QTTrack 오브젝트는 QTMedia 오브젝트에 대한 참조이다. 이 클래스들이 가지고 있는 기능들만도 엄청나게 많아서 몇개의 글을 쓸 수 있을 정도이다. 하지만 내용을 벗어나진 말자. 지금은 QTKit이 어떻게 구성되어 있는지에 대해 고급레벨에서 살피는 중이므로, 코코아 어플리케이션에서 QTKit을 시작하는 것이 얼마나 쉬운지를 살피는 데에 주의를 집중하자.

[편집] 무비 디스플레이 하기 : 단계별 접근

어플리케이션 내에서 무비를 디스플레이 하기 위해서는, QTMovieView를 가져다 놓아야 한다. NSView의 다른 서브클래스들 처럼, QTMovieView를 사용하는 가장 쉬운 방법은 유저 인터페이스의 레이아웃에 인터페이스빌더를 이용하고 그것이 어플리케이션의 로직과 어떻게 연결되는지를 정의하는 것이다. 연결은 전통적인 코코아의 아울렛과 액션을 이용해도 되고 코코아 바인딩 기술을 이용해도 된다. QuickTime 무비를 디스플레이하기 위해 QTMovieView를 사용하는 법에 대한 느낌을 알려주기 위해, 무비 플레이어 기능을 만들어 내는 단계별 속성 가이드를 제공하려한다. 컴퓨터에 있는 Xcode를 이용해 차근차근 따라와도 좋고, 그냥 읽어내려가도 좋다.

1단계: 프로젝트 셋업하기 시작하려면, Xcode를 띄우고 새로운 도큐먼트 기반의 코코아 어플리케이션을 만든다. 어플리케이션은 QuickTime 무비를 열수 있어야 하므로, 어플리케이션의 타겟에 대한 Info window를 열어, mov를 도큐먼트 타입 확장자로 설정하고 "Viewer"로서 동작하도록 한다. 다음 그림과 같이 설정한다.

그림:a_qt_usingqtkit_Documentprops.jpg

다음으로, 빌드된 어플리케이션이 링크할 수 있도록 QTKit 프레임워크를 프로젝트에 더해야 한다. Project > Add to Project 메뉴를 선택하고 /System/Library/Frameworks/QTKit.framework를 찾아가 Add 버튼을 누른다. 더해졌으면, 프로젝트의 윈도우에 나타날 것이다.

그림:a_qt_usingqtkit_Addframework.jpg

2 단계: 사용자 인터페이스에 QTMovieView 더하기 이제 준비는 끝났으니 유저 인터페이스를 레이아웃하자. 프로젝트에 있는 MyDocument.nib파일을 더블클릭하여 인터페이스 빌더에서 연다. 인터페이스 빌더가 열리면, QTKit 팔레트를 로드해야 할 것이다. 다음 그림과 같이 /Developer/Extras/Palettes 폴더에서 이 팔레트를 찾을 수 있다.

그림:a_qt_usingqtkit_Palette.jpg

파인더에서 이 팔레트를 더블클릭하거나 인터페이스 빌더의 프레퍼런스 윈도우에 있는 팔레트 탭을 통해 인스톨 할 수 있다. /Developer/Palettes 폴더로 드래그 해도 된다. 어떤 방법으로든 QuickTime 팔레트를 인터페이스 빌더로 인스톨 했으면, QTMovieView를 사용하는 것은 다른 보통의 뷰를 사용하는 것처럼 쉽다. 인터페이스 빌더 안에서 자리잡고, 크기조절하고 어트리뷰트를 설정할 수 있다. 무비 뷰를 윈도우로 드래그해 꺼낸다.

그림:a_qt_usingqtkit_Dragqtmovieview.jpg

필요한 만큼 QTMovieView의 크기를 조절한다.

그림:a_qt_usingqtkit_Resize.jpg

아마 인스펙터의 Size패널에서 뷰의 자동크기조절을 설정하려 할 것이다. 그건 당신에게 맡긴다.

3단계: 바인딩 셋업하기 QTMovieView를 디스플레이 할 QuickTime무비로 연결 시키기 위해, 코코아 바인딩을 이용해 QTMovieView의 movie 매개변수를 File's Owner 오브젝트안의 movie라는 이름의 모델 키로 정의할 것이다. 이 바인딩을 만들기 위해:

  1. QTMovieView 인스펙터에서 (QTMovieView를 선택하고 커맨드-쉬프트-I)맨 위의 풀 다운 메뉴를 이용해 Bindnigs 패널을 선택한다
  2. Bindings 패널의 Parameters 섹션에서, movie 매개변수 옆의 디스클로저 삼각형을 클릭하여 매개변수의 정보를 연다.
  3. Bind to: 풀다운 메뉴에서 "File's Owner"를 선택한다.
  4. Model Key Path: 필드에 movie를 타입한다.
  5. Bind 체크박스가 클릭된 것을 확인한다.

그림:a_qt_usingqtkit_Bind.jpg‎

코코아 바인딩에 익숙치 않거나, 아직 코코아를 공부하는 중이라면, 방금 한 것에 대해 완전히 이해해야 할 필요는 없다. 위의 바인딩을 정의함으로서, 코코아에게 런 타임시에 유저인터페이스를 로드한 오브젝트인 File's Owner오브젝트와 QTMovieView 오브젝트 간의 연결을 형성하라고 지시한 것이다. 이 연결은 QTMovieView에게 디스플레이 될 QuickTime무비의 레퍼런스를 함께 제공한다. 이제, 연결을 마무리 지을 것이다. 그러나 그전에, 인터페이스 빌더에서 유저 인터페이스를 저장하는 것을 잊지 말도록.

바인딩을 이용하면 쉽다. 요점이 무엇일지 궁금해 하면서 읽어왔을 것이다. 마지막까지, 여기에는 코드가 별로 없다. 다행히, 우리가 공간상의 문제로 생략하는 건 없다. 지금 한 것이 무비와 무비 뷰 사이를 접속하여 정상적으로 작동하는 샘플 어플리케이션을 만들기 위한 작업의 전부이다. 코코아 바인딩이 그 작업을 이렇게 쉽게 만든다. 코코아 바인딩이 뭘까? Model-View-Controller (MVC) 어플리케이션의 기반구조를 만드는 데 필요한 여러 조각들을 이어 붙이는 일을 대신해 주는 아주 멋진 새 기술이다. 그 기능은 여기에 나온 수준을 훨씬 뛰어넘어 당신이 코딩을 거의 하지 않고도 어플리케이션의 다양한 파트에 있는 여러 값들을 동기화 시키는 기능까지 가진다. 그리고, 알다시피 "꿀꿀이"코드를 최소화해 주므로 어플리케이션에서 정말 중요한 코드를 작성하는 데 더 많은 시간을 할애할 수 있다. 이 글 아래에 나열되어있는 ADC 리소스에서 코코아 바인딩에 대한 좀 더 자세한 내용을 볼 수 있다.

4단계: 바인딩 마무리 짓기 Xcode로 돌아가자. 바인딩을 마무리 하기 위해서, movie 인스턴스 변수를 NSDocument의 서브클래스인 MyDocument에 넣어야 한다. 이것은 우리가 QTMovieView의 movie 매개변수를 바인딩한 movie 모델 키와 같은 역할을 한다. MyDocument.h를 열고 (classes폴더에 있음) QTKit 프레임워크를 임포트 하면서 movie 인스턴스 변수를 더한다.

#import <Cocoa/Cocoa.h>
#import <QTKit/QTKit.h>

@interface MyDocument : NSDocument
{
   QTMovie *movie;
}
@end

보는대로 아주 단순하다. 이것이 유저 인터페이스에 있는 QTMovieView와의 바인딩을 완성하기 위한 전부다. 다음으로, 디스플레이 되어야 할 데이타다 있다는 것을 확인해야 한다.

5단계: 퀵타임 무비 데이타 로드하기 도큐먼트가 열렸을때 QuickTime무비를 로드해 오기 위해서는, 먼저 Implementation Files 폴더에 있는 MyDocument.m 파일을 연다. 이제 loadDataRepresentation:ofType: 메소드를 다음과 같이 수정한다.

- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
   movie = [QTMovie movieWithData:data error:nil];
   return YES;
}

빌드하고 실행하기 이제, 어플리케이션을 빌드하고 실행할 준비가 되었다. 실행해 보면, 파일 시스템으로부터 무비를 로드하고 플레이 할수 있을 것이다. .mov파일을 하드디스크에 두고, 어플리케이션의 File>Open을 이용해 그것을 연다.

그림:a_qt_usingqtkit_Runningmovie.jpg

여기까지 따라와서 이 간단한 어플리케이션을 당신의 시스템에서 실행시키고 샘플 무비를 열었다면, 이 프로그램이 완벽하지 않다는 것을 알아챘을 것이다. QuickTime 무비의 종횡비가 QTMovieView의 종횡비로 조정이 되어버릴 것이다. 로직을 조금만 더하면, 우리의 뷰어가 디스플레이 되는 무비의 종횡비에 맞게 그 자신을 크기조정하도록 하는 기능을 넣을 수 있다. 하지만 이 로직이 동작하도록 하기 위해서는, 무비의 어트리뷰트를 다루는 법을 봐야한다.

[편집] 무비 어트리뷰트 사용하기

QTMovie 오브젝트의 흥미있는 데이타의 대부분은 어트리뷰트의 형태로 저장되어 있으며, 어트리뷰트 키를 이용해 엑세스 가능하다. 어떤 종류의 데이타가 어트리뷰트로서 내장되어 있는지에 대해 알려주기 위해, 다음 표에서 어트리뷰트 키에 대한 몇개의 예를 제공한다 :

Attribute Description
QTMovieCopyrightAttribute 무비에 대한 저작권 문자열을 가진다.
QTMovieEditableAttribute 무비가 편집 가능한지를 가리킨다.
QTMovieHasAudioAttribute 무비가 오디오 트랙을 가지고 있는지를 가리킨다.
QTMovieIsSteppableAttribute 무비가 프레임 사이로 step할 수 있는지를 가리킨다.
QTMovieNaturalSizeAttribute 최고 해상도로 디스플레이 되었을 때 무비의 사이즈를 준다.
QTMovieSelectionAttribute 무비의 선택된 영역
QTMovieTimeScaleAttribute 무비의 타임 스케일

모든 다양한 어트리뷰트 키에 대한 전체 문서는 QTMovie API 도큐멘트에 있다. 다음 코드는 무비의 저작권 어트리뷰트로의 엑세스를 보여준다.

[movie attributeForKey:QTMovieCopyrightAttribute];

실행되면, 위의 메소드는 다음과 같은 내용을 제공할 것이다. ?2006 Apple, Inc. All Rights Reserved

위에 있는 우리의 샘플 뷰어에 적용 가능한 것으로, QTMovieNaturalSizeAttribute를 이용해 플레이 되고 있는 무비의 사이즈를 구할 수 있다.

NSValue *value = [movie attributeForKey:QTMovieNaturalSizeAttribute];
NSSize size = [value sizeValue];

이 코드로부터, 디스플레이 되고 있는 QuickTime무비의 종횡비를 반영하여 윈도우의 크기를 조정할 수 있다. 윈도우 관리 토픽쪽을 헤메어 다니지 말고, 우리의 QTKit에 대한 오버뷰를 계속하자.

[편집] 편집하기

지금까지, QTMovieView에서 무비를 재생시키는 방법과 QTMovie로부터 데이타를 얻어내는 방법을 봤다. 조금 더 나아가서 실제로 QuickTime 무비를 편집하는 법을 알아보자. 적당한 예제로, 긴 QuickTime 무비로부터 10초짜리 프리뷰를 얻어내고 그것을 새로운 무비로 저장하는 코드를 보자.

우리의 코드에 처음으로 필요한 것은 오리지널 무비를 참조할 QTMovie 오브젝트를 만드는 것이다.

NSError *error;
NSString *path = @"/path/to/movie.mov"
QTMovie *movie = [QTMovie movieWithFile:path error:&error];

이제, 이 무비에 손을 대기 위해서, 무비가 사용하는 타임 스케일을 알아야 한다. 이것은 어트리뷰트로 엑세스 된다.

NSNumber *scale = [movie attributeForKey:QTMovieTimeScaleAttribute];

퀵타임이 시간을 측정하는 방법 서로 다른 미디어 포맷들은 서로 다른 방식으로 시간을 유지한다. 예를 들어, 극장 영화는 초당 24프레임으로 영사된다. 텔레비젼은 초당 30프레임으로 상영된다. 융통성을 가지기 위해서, QuickTime은 타임 스케일에 적합한지에 상관없이 기반 미디어 포맷마다 시간을 정의하도록 해서 그 미디어 데이타를 정확히 재생시킬 수 있도록 했다. 위의 우리 예제에서, QTMovieTimeScaleAttribute를 사용해서 10초안에 무비의 타임 스케일 기준으로 얼마나 많은 유니트들이 있는지를 알아낸다.

다음으로 우리가 할 일은 무비의 첫 10초의 범위를 결정하는 것이다. 이것을 위해, QTKit API에서 그냥 시간 값이나 시간값의 범위를 가지는 QTTime과 QTTimeRange 데이타 타입을 사용하려 한다.

QTTime start = QTMakeTime(0, [scale longValue]);
QTTime cut = QTMakeTime(10 * [scale longValue], [scale longValue]);
QTTimeRange range = QTMakeTimeRange(start, cut);

이제, 우리의 10초 QTTimeRange를 사용하면, 오리지널 무비로부터 새로운 QTMovie 오브젝트를 만들 수 있다.

QTMovie *newMovie = [[QTMovie alloc] initWithMovie:movie timeRange:range error:&error];

이제 남은 건 새로운 작은 프리뷰 무비를 저장하는 것이다

NSMutableDictionary *savedMovieAttributes = [NSDictionary dictionaryWithObject:[NSNumbernumberWithBool:YES] forKey:QTMovieFlatten];
[movie writeToFile:@"/small/files/movie-preview.mov" withAttributes:savedMovieAttributes]; 

이 코드로 무비를 편집하기 위해 GUI 어플리케이션을 작성할 필요는 없다. 커맨드라인 매개변수를 처리하는 코드와 몇개의 오리지널 무비 파일을 반복하는 코드만 더해주면, 방대한 QuickTime 무비의 컬렉션을 위해 자동으로 프리뷰를 만들어주는 커맨드라인 툴을 만들 수 있다.

[편집] 이전 API로 내려가기

처음 시작할 때 말한 것 처럼, QTKit는 전체 프로시저 QuickTime API를 복사하진 않았다. 몇가지 QuickTime 동작을 위해서는, 기어를 바꿔서 직접 기반에 깔린 QuickTime API를 사용해야 한다. 그러나, 당신의 코드를 고철덩어리로 만들고 처음부터 다시 시작해야 할 필요는 없다. QTKit이 필요로 하는 QuickTime 프리미티브의 해당 클래스로의 엑세스를 가능하게 해 준다. 그 프리미티브에 QuickTime 함수를 사용하면 되는 것이다.

다음의 메소드는 QTMovie 인스턴스로부터 Movie 프리미티브로의 접근법을 제공한다,

Movie moviePrimitive = [movie quickTimeMovie];

프리미티브를 얻으면, 매개변수로 Movie 데이타 타입을 받는 어떤 QuickTime 함수에게든 이것을 보낼 수 있다. 그리고 더 좋은 점은, QTMovieView를 이용해 무비를 디스플레이 하는 방식이라던지, QTKit을 사용해 작성한 다른 어떤 부분이라도 변경할 필요가 없다는 것이다. 이 현대적인 코코아 기반의 QTKit를 QuickTime과 당신의 코코아 기반의 어플리케이션의 통합을 위해 사용하고, 언제든 필요하면 프로시저 API로 내려갈 수 있다.

[편집] QTKit으로 무엇을 할 수 있을까?

우리가 지금까지 살펴본 QTKit에 대한 오버뷰에서, QTKit가 QuickTime의 엄청난 능력에 엑세스 할 수 있게 하고, 당신의 어플리케이션에 직선적인 방식으로 합쳐질 수 있다는 것을 알 수 있다. 이제 이 지식을 가지고 무엇을 할 것인가? 방대한 컬렉션의 QuickTime 무비에 대해 다양한 종류의 메타데이타를 모두 사용자가 관리할 수 있도록 하는 미디어 브라우저를 만들 수 있을 것이다.무비의 세트에서 몇 몇 프레임을 잡아내어 사용자가 컬레션을 원격에서 브라우징 해서 다운로드 하고 싶은 무비를 선택할 수 있도록 웹 페이지를 만드는 커맨드라인 툴을 만들 수 도 있을 것이다. 혹은 당신 내부적인 워크 플로우에 적합하게 커스터마이즈된 비디오 편집 툴을 만들 수도 있을 것이다. 한계는 없다. QTKit은 지난 15년간의 QuickTime 플랫폼 하에서의 경험상 전례 없이 쉬운 개발방법을 가져다 준다. 이는 최고의 어플리케이션 제작 플랫폼에 최고의 멀티미디어 플랫폼을 가져왔다.

QTKit에 대한 부가정보 이 문서를 발판삼아, 코드에 좀 더 깊이 뛰어들고, 도큐먼트의 도움을 받아 당신의QuickTime기반 어플리케이션을 만들어 보라. 그 길에서, 다음 리소스들로부터 유용한 것을 얻을 수 있을 것이다.

- [퀵타임 개요]

- [ADC Home / Reference Library / Documentation / QuickTime / Cocoa]

- [퀵타임 샘플 코드]

For More Information on Cocoa binding

- [코코아로 환경설정 바인딩하기]

- [빠르고 쉬운 제품개발: 딜리셔스 라이브러리는 코코아 바인딩을 이용했다]

- ADC Reference Library 의 [Cocoa Bindings Programming Topics] 아래에도 많은 정보가 있다.