Java Media Framework Player API

Multimedia playback comes to Java! Learn how to start using audio and video in your applets and applications

What is the Java Media Framework?

The JMF is a set of three new APIs being co-defined by the JMF Working Group members — Sun, Silicon Graphics, and Intel. These APIs eventually will include Java Media Player, Capture, and Conferencing. The first to be delivered, the Player API provides a framework for implementors to build media players and provide them in a standard way on all Java platforms. The JMF specification is flexible enough to allow developers to extend players by adding their own nodes (such as images filters, audio reverb effects, and so on) or to use the standard players without making any additions.

Before the JMF Player API, multimedia playback support in Java was extremely limited. Programmers had to generate their own GUI controls. (JMF returns a standard set of controls in the form of a ControlPanel and other Control objects.) The supported media types in the core Java API were limited (Sun’s muLaw format for sound, and no media option for video), so developers were forced to implement their own players without any underlying framework to assist them.

With the JMF Player API, however, Java programmers can implement support for almost any audio or video format by building upon an established media playback framework. In addition, standard implementations (see Resources for URLs pointing to more information on implementations from Intel, Silicon Graphics, and Sun) provide built-in support for common Web formats such as muLaw, Apple AIFF, and Microsoft PC WAV for audio, as well as Apple QuickTime video, Microsoft AVI video, and Motion Picture Expert Group’s MPEG-1 and MPEG-2 for video. MIDI currently is supported in the Silicon Graphics IRIX implementation and is slated for support in Intel’s Windows implementation. If you want to use one of these standard Web-based formats, you are now able to easily integrate multimedia playback into applets and applications alike with only a few lines of code.

JMF allows player implementors to use native methods as need be underneath the covers for greater speed. This lets the implementors optimize performance on each platform. At the same time, the common Java Media Player API ensures that applets and standalone applications will run on any Java platform.

Installing JMF software

Installation of the JMF software is straightforward. You need only download a package containing the classes, documentation, and accompanying files for your platform and install it using the standard method.

Implementations currently are available from Silicon Graphics and Intel for IRIX and Windows 95/NT, respectively. Sun currently is working on a Solaris implementation. Note that you can use JMF with Sun’s Java Development Kit (JDK) or with a browser. Implementations that work for Netscape Navigator 3.01 are available on all platforms, and Intel’s Windows 95/NT implementation also supports Microsoft Internet Explorer 3.01.

To interact with the JMF applets embedded in this article, you must have the JMF Player implementation for your platform. See Resources for URLs at which you can download and install JMF.

Using a player

Java Media players support a six-state model based on the two fundamental states Stopped and Started.

This model is outlined in the accompanying state diagram, with Stopped states given in green and the Started state in white. The states are Unrealized, Realizing, Realized, Prefetching, Prefetched, and Started. Note that the transitions from Realizing to Realized and Prefetching to Prefetched are automatic (Realizing and Prefetching are transient states of indeterminate length). Other transitions are brought about by method calls, with some of the most important methods being given in the diagram.

State transitions are accompanied by the appropriate TransitionEvent being generated. Any interested class can implement the ControllerListener interface and use its controllerUpdate method to handle such TransitionEvents accordingly. A complete listing of TransitionEvents is available in the JMF Player API Documentation.

A JMF player fundamentally is an encapsulation of the multimedia component that allows for control of state transitions during playback. JMF players provide methods to query the current state, to acquire necessary resources, and to start, stop, and control the actual playback of the media file or stream. Read on for a brief description of how to create a player and control it.

java.media.Manager uses the media sample’s URL to build a player using a PlayerFactory. This factory model is very similar to the Connection Factory used in JDBC and similar to other factories used throughout the Java APIs. The Factory itself uses appropriate protocol handlers and content handlers to build and return the final media player. A player is built and returned as:

Player myPlayer = Manager.createPlayer(myURL);

After being returned from the PlayerFactory, a player must be “Realized” and “Prefetched” before it can be started. Realization refers to the process of finding all resources the player will need to play, whereas prefetching actually loads the resources and readies the player to begin playing. Each of these state transitions are completed by making one call to the Player API. Note that the realize method is a non-blocking method, but that players need to be realized to use many of their methods (such as getVisualComponent, for example), so it is often useful to implement a blockingRealize yourself for use in guaranteeing that you have a realized player. This example blockingRealize works in cooperation with the controllerUpdate method and a boolean variable to ensure that a realized player is returned.

boolean realized = false;

public synchronized void blockingRealize() { myPlayer.realize(); while (!realized) { try { wait(); } catch (java.lang.InterruptedException e) { status.setText("Interrupted while waiting on realize...exiting."); System.exit(1); } } }

public synchronized void controllerUpdate (ControllerEvent event) { if (event instanceof RealizeCompleteEvent) { realized = true; notify(); } else if (event instanceof EndOfMediaEvent) { eomReached = true; } }

Once prefetched, a player has the necessary resources to begin playback. A call to the start() method begins playback at the beginning of the media sample or the appropriate point in a live multimedia stream. Note that if start() is called on an Unrealized player, the player first uses its realize() and prefetch() methods before starting. Similarly, calling start() on a realized player that is not yet prefetched will result in prefetching occurring before starting.

An example JMF player applet illustrates how one can easily and quickly create a simple applet that can load various media types (here, a QuickTime movie and a wav audio file), ascertain the appropriate visual and control components to make available, and play back the multimedia component.

Because JMF is not yet included in browser Java implementations by default, I’ve placed the applets on a separate page.

After you have installed JMF on your platform, you can interact with the example players. Both applets on this page are instances of the same example applet, with a complete code listing available here. Note that TransitionEvents are printed to standard output, so if you open your Java Console before loading the example page, you can see events as the player transitions from state to state.

Advanced JMF issues

JMF was developed for Java Development Kit (JDK) 1.0.2 compatibility, and follows JDK 1.0.2 design practices. For example, it employs its own event model rather than using the new JDK 1.1 event model based on java.util.EventObject. This is both a strength and a weakness, as it provides backward compatibility while failing to take advantage of some of the benefits available in the new JDK event model.

The java.media.Player interface extends from the Controller interface, which itself extends the Clock interface. The Clock interface specifies methods used for synchronization and timekeeping, while Controller adds variables and methods used to track state and state transitions.

The separation of functionality between the Clock, Controller, and Player interfaces allows developers to implement portions of functionality without having to implement everything. For example, one could create a Controller without having to bother with providing an implementation for the methods in Player that a controller does not need.

The JMF Player API allows for the creation of streaming media players as well as players for stored media files. For example, players can be created to display and integrate live broadcasts and large multimedia streams such as movies or music albums into the Web. Such players, combined with a high-performance media server such as Silicon Graphics Cosmo MediaBase, allow for the dissemination of pay-per-view content on the Web, training videos on corporate intranets, etc., all without the content provider having to worry about the client’s platform (so long as the client has a Java-capable browser).

Note that while the long-term plan for JMF is possibly to provide Java implementations for decoders and lower-level framework components, current Player implementations use native methods for much of the lower-level processing. For example, Intel uses Microsoft’s ActiveMovie while Silicon Graphics uses its own Digital Media libraries to provide the core decoders for movie playback.

Though the lower-level native code is non-portable, this tradeoff is made for the sake of speed. A further disadvantage, however, is that native code complicates the debugging of applets and applications that use JMF players, as native method debugging is not yet well supported in most Java development environments.

Other advanced features are provided for in the Player API. Any player may act as a controller for one or more other players. This synchronization is achieved through the use of TimeBase objects, which function as clocks in JMF. Players can synchronize with one another using methods such as getTimeBase and setTimeBase.

The JMF Player API includes a CachingControl interface for use in building a CachingControl. This minimizes the impact of varying network performance by providing a buffer out of which the multimedia stream can be played while the network catches up to the player after heavy loading slows it down.

Interfaces also are provided for GainControl and GainChangeListener so that multimedia samples with soundtracks can be better controlled. The API also contains packages to provide for reliable and unreliable, or streaming, media content (see the API documentation for java.media.content packages) and to provide for file and HTTP protocols (outlined in the API documentation for the java.media.protocol packages).

Future additions to Java Media

The JMF Player API currently is in beta, with a final implementation expected in the second quarter of 1997. Though the current JMF Player API supports only media display, future additions to JMF are intended to add support for media capture and conferencing. JavaSoft currently states that the Media Capture portion of the JMF will be available with a final implementation sometime during 1997 (the specific quarter is to be determined), while the Media Conference API’s final implementation date is still to be determined.

The JMF Player API will be integrated into the Java platform sometime subsequent to the current JDK 1.1 release. Whether JMF will be a core API or a standard extension is currently listed as “to be determined” by JavaSoft. Up-to-date information is available from the Java API Overview page at JavaSoft.

Conclusions

The JMF Player API is both powerful and simple to use — evidence of the elegance of object-oriented programming and Java. The Player API provides the core functionality that Java needs to be a powerful multimedia processing and display platform.

Everyone, from applet programmers with personal Web sites to player implementors at software companies and Web designers at content providers, will benefit in their newfound ability to deliver audio and video functionality in their programs. Future enhancements promise to add Capture and Conferencing tools, bringing Java in line with (or possibly ahead of) other languages in its multimedia processing and presentation capabilities.

Bill Day is a software test engineer at
Silicon Graphics Computer Systems. He worked on SGI’s Java IDE, Cosmo Code,
before designing a test suite for SGI’s implementation of the Java
Media Framework Player API. His freeware applet, VisAnimator,
has received numerous awards from around the Web. When Bill’s not
working on Web projects or next generation workstations at SGI, he
loves to travel with his wife, speak French, and enjoy life. Java,
c’est magnifique!

Source: www.infoworld.com