Integrating QuickTime with Cocoa
by Douglas Welton08/15/2003
This is the first in a series of articles about integrating QuickTime technology into your Cocoa applications. My intent with this series is to provide the introductory steps for those of you who are new to QuickTime, to cover many of the common tasks and issues that may crop up during your development cycle, and to share my experience so that, hopefully, you can avoid some of the mistakes I've made along the way.
I'll start out by providing an overview of QuickTime, then some insight into the interfaces between Cocoa and QuickTime, and finish up with an example of a "simple" QuickTime Movie Player that you can include in your own applications.
What is QuickTime?
In the early 1990s, Apple introduced QuickTime, a collection of application programmer interfaces (APIs) and components that support the creation, manipulation, and playback of multimedia and interactive content. Using the QuickTime API, programmers can work with media types such as video, images, and audio, as well as vector-based graphics and animation, 3D modeling data, panoramic objects, MIDI-formatted music, and user-defined media types. QuickTime components provide access to variety of services, such as image compression/decompression, video digitizing, and pre-defined effects that can be performed on one or more media types.
|
Related Reading
|
The movie is used as a metaphor to describe any time-based sequence of data that can be manipulated by QuickTime. The data can be a sequence of images (like a cinematic movie), or audio samples, or stock quotes, or any type of data that varies over time. A typical movie might contain several streams of data, called tracks. For example, a .mov file might contain a movie with two streams, a video track and a sound track.
The QuickTime API is quite extensive and beyond the scope of this article. So I would suggest that before you begin a project of your own that you spend some time with the QuickTime documentation available at the Apple developer web site.
QuickTime Comes to Cocoa
During the 1990s, QuickTime had helped Apple become successfully positioned as a leader in multimedia and interactive technology. So, when Apple bought NeXT in the late 1990s, the challenge facing Apple was how to integrate one of its homegrown key technologies with Cocoa, the new development environment acquired from NeXT. QuickTime did not have an object-oriented interface and was based on QuickDraw, Apple's pre-Mac-OS-X imaging architecture. Cocoa, on the other hand, was defined by the objects in Foundation and AppKit. Cocoa's image architecture was also based on Quartz, the PDF-based graphical system that Apple had chosen as its go-forward technology.
The solution was to introduce two new objects into Cocoa's AppKit. The
NSMovie object was provided to encapsulate the QuickTime
movie metaphor, and NSMovieView provided insulation from
the differences in the underlying image architectures.
All of QuickTime in One Object?
Let's take a look at the NSMovie object. This object fits
my notion of a shallow encapsulation. The NSMovie class
contains only a few methods, which provide you with access to the QuickTime
Movie data type, but does not allow you to directly modify
the movie's data. In other words, using NSMovie, you can
get a pointer to the movie for display purposes, but you can't use NSMovie
itself to change a movie's playback attributes or contents.
The NSMovie class contains methods that allow you to do
three basic things:
- Initialize a new
NSMovieobject. - Filter the file types used for initialization.
- Return basic info about the QuickTime
Moviepointer being encapsulated.
First, NSMovie objects can be initialized from a URL, a
pasteboard, or an existing QuickTime Movie pointer. NSMovie
can be initialized with any type of data that QuickTime will accept
using the methods -initWithURL:byReference, -initWithPasteboard,
or -initWithMovie. This includes video, audio, and still
images. Also, you may need to use a URL for initialization from HTTP
and RSTP resources.
The following example shows how to initialize an instance of NSMovie
using a sample movie contained in an application's bundle:
NSString *Example_Path;
NSURL *Example_URL;
NSMovie *Example_Movie;
//+
// Load the movie from within the current Bundle
//-
Example_Path = [[NSBundle mainBundle] pathForResource: @"Sample_Movie"
ofType: @"mov"];
Example_URL = [NSURL fileURLWithPath: Example_Path];
Example_Movie = [[NSMovie alloc] initWithURL: Example_URL byReference: YES];
Second, NSMovie provides methods to help you filter file
types and pasteboards that can be used to initialize an object instance.
Using -canInitWithPasteboard and -movieUnfilteredPasteboardTypes,
you can test the suitability for initialization using a particular pasteboard
or retrieve a list of pasteboard types that will be accepted. Additionally,
you may also find it useful to use -movieUnfilteredFileTypes
to restrict the choices a user has when selecting files.
The following is an example of how you might use NSMovie
to filter the file types that will be selectable from an NSOpenPanel.
//+
// Create and display an open panel with only movie types selectable
//-
Add_Video_Panel = [NSOpenPanel openPanel];
Button_Clicked = [Add_Video_Panel runModalForDirectory: NSHomeDirectory()
file: nil types: [NSMovie movieUnfilteredFileTypes]];
Finally, NSMovie can be used to return information about
the QuickTime movie that it has encapsulated. The method -QTMovie
returns the QuickTime Movie pointer that is the source
for the NSMovie object. This is the key ingredient for
extending the value of NSMovie when working with QuickTime.
With a Movie pointer in hand, you can use functions from
the QuickTime API to access, manipulate, and change any QuickTime attributes
that are unavailable from NSMovie.
The following example illustrates how to access several QuickTime movie
attributes that are not available from NSMovie:
- (void) Get_QuickTime_Attributtes: (NSMovie *)Example_Movie
{
Movie QuickTime_Movie;
TimeScale Time_Scale;
TimeValue Current_Time, Movie_Length;
QuickTime_Movie = [Example_Movie QTMovie];
Current_Time = GetMovieTime( QuickTime_Movie, nil );
Time_Scale = GetMovieTimeScale( QuickTime_Movie );
Movie_Length = GetMovieDuration( QuickTime_Movie );
}
On the Screen, Please!
Okay, so you have an NSMovie object ... now what? Most of
the time, the answer to that question will be that you need to play
it. That's where NSMovieView comes in.
|
|
Figure 1 illustrates a typical use of NSMovieView. In this
case, the view is displayed with a movie controller, which allows the
user to play the movie, set the volume, reposition the play head, and
make selections.
Before you get started working with NSMovieView, I recommend
that you get thoroughly familiar with the features and behavior of Apple's
QuickTime Player. Much of the functionality of NSMovieView
is demonstrated directly in the features of the QuickTime Player.



