A Gentle Re-Introduction to QuickTime for Javaby Chris Adamson
This article is going to be a bit of a restart, a "retro intro" if you will, to the topic of QuickTime for Java (QTJ). In two previous articles, one on using QTJ as a helper for the Java Media Framework and another on the inner workings of the QuickTime file format, I've covered essential concepts and important issues only as they related to other topics, perhaps burying them to a degree. Feedback suggests the time is right to go back and do a beginner-level introduction to QTJ.
It's not that we think O'Reilly readers skip the developer docs or ignore the demos that come with the SDK, but we just want to be sure we're good before we hit the hard stuff. After all, there's matrix math coming up when we get to sprite animation ...
I will be using this article in the future for reference purposes, in the
sense of "If this is your first time writing a QTJ app, go back to this
article and make sure you've got everything set up correctly." Between
CLASSPATH issues and the obtuse situation with QTJ and Java 1.4.1 on Mac OS X, it'll be nice to not have to reiterate three paragraphs of
gotchas every time.
A Little Background ...
Apple's QuickTime for Java is a Java wrapper around much of the native QuickTime media API, which itself has been available and under ongoing development since 1991. It is available for the classic Mac OS, Mac OS X, and Windows. Note the obvious omission: it is not available for Linux or any other OS at this time; nor is there an all-Java version.
QuickTime is sometimes thought of as just a media format and player, a rival to Windows Media and Real Player, with support for a wide variety of media formats, including some that most people aren't aware of (such as Flash 5 and Photoshop). But that thinking overlooks the fact that it was designed as a media creation API, with tools to capture and edit media, apply effects, and to export to different formats. QuickTime also includes a legacy imaging API, sprites, and support for interactivity within a movie. QuickTime used to include a 3D API, QuickDraw 3D, but it was dropped in Mac OS X in favor of OpenGL. We won't discuss it again.
QuickTime had been around for years before the QTJ project started, and was
designed for use with straight C — not necessarily C++ or Objective-C.
While QTJ re-envisions QuickTime from a more object-oriented perspective, QTJ
code still seems different than what you might be used to working with in
JavaSoft's APIs. For example, while most classes in core Java and the standard
extensions define constants in the classes where they are used (e.g.,
Integer.MAX_VALUE), QTJ defines massive
lists of constants in
StdQTConstants4, etc., which hints at their origin as members of
big C header files like Movies.h.
By the way, Apple's sample code has a tendency to declare that it
implements these no-method interfaces, which is an easy-to-write
but hard-to-follow way of inheriting the constants. In my sample code, I will
always explicitly reference the constant by class so you can find it again
When Not to Use QuickTime for Java
Let me start with the ultimate in simplicity — not using QTJ at all. Every once in a while, someone will post the to the quicktime-java list that they need to learn QTJ because they want to put a movie in an applet in a web page.
That is overkill. Since it requires the user to have Java, QuickTime, and QuickTime for Java all installed, the size of the potential audience is smaller than it would be without so many dependencies.
If all you want to do is put a QuickTime movie in a web page, just use a
pair of simple HTML tags. Most browsers will pick up the
<EMBED> tag, but since Internet Explorer is special, it needs an
<OBJECT> tag. Here's a simple example of a suitable tag:
<object classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="160" height="136" codebase="http://www.apple.com/qtactivex/qtplugin.cab"> <param name="src" VALUE="../media/keagy-ball-1.mov"/> <param name="autoplay" VALUE="false"/> <embed src="../media/keagy-ball-1.mov" width="160" height="136" autoplay="false" pluginspage="http://www.apple.com/quicktime/download/"/> </object>
Some of these values are boilerplate and never change, namely the
pluginspage. Beyond that,
the variables that you populate simply need to get repeated as both
<param> children of the
<object> tag and
attributes of the
<embed> tag. The only required values for
the simplest case are:
src: The URL of the movie
width: Dimensions of the movie. If you intend to show the controller (the bar with the volume control, play/pause button, and the "scrubber"), add 16 pixels to the height.
I've added an entry,
autoplay, as another attribute, mostly just
to keep things interesting — it doesn't have a default value, since
general autoplay behavior is determined by the user's QuickTime preferences.
This and many more attributes are described in Apple's document "Embedding QuickTime
for Web Delivery."
You could also drop the controller, instead controlling the movie through
your own HTML buttons, links, or other page elements. You can do this with the
support. In this case, just add the attribute
true to the
<embed> tag (it's not necessary for the
<object> tag), give it a
name attribute and
parameter, and then refer to the movie by that name when you call methods such
Stop(), as in this example. More sophisticated methods are available for getting and setting movie properties like the playback rate
and volume, examining the track structure of the movie, and getting limited
access to sprite and QuickTime VR properties.
One option to get a lot of mileage out of authoring (in lieu of coding) is to use the "Synchronized Multimedia Integration Language", or SMIL (pronounced "smile"). This XML markup, a WC3 standard, allows you to present audio, video, text, and other elements, from multiple sources, in one display, using the markup to arrange the elements temporally and spatially, indicating what goes where and when.
Here's an example QuickTime SMIL presentation. It shows some logos with background music, then offers links to multiple versions of a QuickTime movie:
<smil> <head> <layout> <root-layout id="root" width="320" height="240" background-color="white"/> <region id="main" width="320" height="240" z-index="1" fit="meet" /> <region id="onjava-reg" width="294" height="82" z-index="1" left="13" top="79"/> <region id="macdevcenter-reg" width="202" height="88" z-index="1" left="59" top="76"/> <region id="and-reg" width="40" height="20" left="140" top="110"/> <region id="present-reg" width="80" height="20" left="120" top="110"/> <region id="link1-reg" width="80" height="60" left="240" top="60" z-index="2"/> <region id="link2-reg" width="80" height="60" left="240" top="135" z-index="2"/> </layout> </head> <body> <par> <!-- 15 seconds of audio parallel to a sequence of images --> <audio src="Worldwide-15.mp3"/> <seq> <img src="onjava_logo.jpg" region="onjava-reg" dur="03" /> <img src="and.gif" region="and-reg" dur="01"/> <img src="macdevcenter_logo.gif" region="macdevcenter-reg" dur="3 sec" /> <img src="present.gif" region="present-reg" dur="02"/> <!-- last thing in sequence is poster with link buttons! --> <par> <img src="keagy-closeup.jpeg" region="main"/> <a href="keagy-closeup-320-sv.mov" show="replace"> <img src="link1.gif" region="link1-reg"/></a> <a href="keagy-closeup-160-sv.mov" show="new"> <img src="link2.gif" region="link2-reg"/></a> </par> </seq> </par> </body> </smil>
<head> tag, we define a number of spatial
"regions". Our content will refer to these to indicate where it will
be placed on the screen. You can have any number of regions, with several used at
References to media go in the
<body> section, grouped
according to whether different items are "parallel" or in
"sequence." Items in a
<par> tag are shown or
played at the same time, while those in a
<seq> tag are
shown or played one after another, either for their natural duration (if
appropriate) or for the time specified in a "dur" attribute.
Our example pairs an audio clip (a 15-second soundtrack from FreePlay Music, whose royalty-free audio clips are available to .Mac users via the iDisk Software folder), with a sequence of elements. The first four
members of the sequence are graphics: the ONJava logo, an "and" graphic, the MacDevCenter logo, and a "presents" graphic. Note that Apple's SMIL docs include a way to include text from a file or a
URL, but I used graphics so I could control the font and color.
The last member of the sequence is another
this time combining a poster frame,
keagy-closeup.jpeg, with two
image links to the movie. Notice that the link elements refer to two regions
2, while the
region has a
1. This causes the link graphics to be
drawn on top of the poster image.
Among the many possible uses of SMIL, this illustrates a way to create "alternate movies" (movies that redirect to other QuickTime movies, perhaps to offer different sizes or bitrates). This is easier than the technique offered here. (If you don't scare easily, check out the low-level details of how this kind of real "alternate movie" works, along with an audacious QuickTime for Java implementation.)
Pages: 1, 2