ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

A Gentle Re-Introduction to QuickTime for Java

by Chris Adamson
05/14/2003

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 horrid 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.

Related Reading

Mac OS X for Java Geeks
By Will Iverson

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., Label.LEFT, Integer.MAX_VALUE), QTJ defines massive lists of constants in StdQTConstants, 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 later.

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 <object>'s classid and codebase, and the <embed>'s 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
  • height and 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 QuickTime plug-in's JavaScript support. In this case, just add the attribute enablejavascript = 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 as Play() and 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.

The downside of the JavaScript support is that it is only as good as the LiveConnect — or, in QuickTime 6, XPCOM — support in your browser. For QuickTime 6, that means that Mozilla and Internet Explorer work fine on Windows, but the situation is a disaster on the Mac, where only Mozilla supports JavaScript control of the QuickTime plug-in. IE is known not to work, and while Apple says that Mozilla-based browsers should be OK, Camino and OmniWeb don't work with my example, nor does Safari beta 2 (v.72).

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>

In the <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 a time.

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 data: URL, but I used graphics so I could control the font and color.

The last member of the sequence is another <par> tag, 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 whose z-index is 2, while the main region has a z-index of 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

Next Pagearrow