Progress on the JMF and Java Media APIs

Learn about JMF 2.0 and how the Java Media APIs have changed in the past year

My first JavaWorld article way-back-when was on the Java Media Framework (JMF). As the various Media APIs have matured, I feel that things have come full circle. Therefore, I'll dedicate my final Media Programming column to a revisit of JMF and the general state of all the Java Media APIs.

There have been some notable changes in the JMF and other Java Media technologies, the companies developing implementations of them, and their availability for developers. This article updates the material from previous articles as appropriate.

An important reminder: Java Media Framework is a specific API for synchronizing multimedia streams (files, network streams, and so on). It is one of several of the Java Media APIs, which also include Java 2D, Java 3D, Java Speech, and so on. I refer to the Java Media Framework as the JMF, reserving the term Java Media for the entire collection of multimedia APIs.

JMF history and basics

Of the JMF 1.0, aka Java Media Player API, I wrote the following in April of 1997 (see Resources):

The Java Media Player API, a portion of the Java Media Framework (JMF), lets Java programmers easily embed audio and video within applets and applications. Both static and streaming multimedia are supported from any valid URL. JMF players may be controlled by other players, providing for synchronous playback of multiple audio and video samples.

This information still holds true with the updates and additions of the last two years. JMF, however, has evolved new capabilities and grown in scope, especially with the upcoming 2.0 API release (expected in the second half of 1999).

JMF industry players

First, let's have a look at the industry players. Sun, Silicon Graphics (SGI), and Intel designed and specified the original JMF 1.0 in mid-1998. In the interim since the initial version of the API, both SGI and Intel have withdrawn from the JMF specification process. For a while, there was significant concern in the JMF user community that Sun was the only vendor supporting JMF. This situation was undesirable.

Luckily, in late 1998 IBM stepped in with interest in the JMF. Shortly after IBM joined Sun, an all-Java implementation of the 1.0 API was released (December 1998). This implementation, known as JMF 1.1 for Java platforms, supports a limited but significant subset of the content and protocol types supported by the Win32 and Solaris-native JMF 1.1 implementations (known as performance packs). The availability of an all-Java JMF 1.1 was a major milestone for JMF, in that the technology became available for any Java 1.1-compliant or Java 2 runtime. In fact, the JMF 1.1 Java implementation is even available in a Web-oriented version with tools that allow developers to include only the relevant JMF classes in a JAR file for download with their JMF applets. This allows one to deploy JMF-based applets on a Web server for use by any Java 1.1-compliant browser. Both Netscape and Microsoft support Java 1.1 -- and therefore JMF 1.1 for Java -- in their recent browser releases of Navigator and Internet Explorer, respectively.

IBM is helping Sun to codefine the JMF 2.0 API, which will include a specification and provide a reference implementation of the next JMF API: Java Media Capture. Let's hope IBM will figure out how to subsequently roll JMF functionality into some of its business-oriented Java-based software products -- a potentially good thing for the longevity of JMF technology.

What's new in JMF 2.0 vs. 1.0?

The JMF 1.0 API specifies the components necessary to handle playback of synchronized audio and video. Please refer to my previous JMF article (see Resources) for a review of the capabilities of JMF 1.0.

JMF 2.0 makes several key additions to the spec:

  • Audio and video capture
  • Streaming of audio and video, and thereby the possibility of building all-Java streaming servers in addition to clients
  • Pluggable codec support within players

For more information on JMF 2.0 and its new capabilities, please refer to the Java Media Framework Programmer's Guide (see Resources), currently available in version 0.5 early access.

Installation of JMF development tools and runtime

Both Silicon Graphics and Intel have removed previous versions of JMF from their respective Web sites. You can, however, download the latest reference implementations (denoted JMF 1.1, compliant with the 1.0 API spec) for Win32, Solaris, and Java platforms from the Sun site (see Resources).

Note that the documentation for the all-Java version specifically mentions AIX, indicating that IBM has been testing this software on its AIX Java runtime. I expect future releases of the JMF (2.0 and beyond) to specifically support IBM operating environments, whether through a pure Java implementation or OS-specific native implementations.

Updated JMF examples

I have updated the JMF 1.0 beta-compliant example from my previous JMF article to run in JMF 1.0 API-compliant environments. You can download the example code and try it out under JMF 1.1 implementations using your own media files. The applet should also run on JMF 2.0 runtimes when they become available. (To download all of the files associated with this article in zip format, see Resources.)

001 //Comment out the following package statement to compile separately. 002 //package com.javaworld.media.jmf; 003 004 import java.applet.*; 005 import java.awt.*; 006 import java.net.*; 007 import java.io.*; 008 import javax.media.*; 009 010 /** 011 * JMF11Applet updates the JMFApplet from the April 1997 012 * JavaWorld article for JMF 1.1 API-compliance. Please 013 * refer to the article at:

014 * http://www.javaworld.com/jw-04-1997/jw-04-jmf.html 015 *

016 * In addition, JMF11Applet has been re-worked to 017 * use the Java 1.1 (and beyond) event model. This 018 * version has been developed and tested on Java 2 019 * and the JMF 1.1 all-Java implementation, May 1999. 020 *

021 * This applet may be deployed to public Web servers 022 * using the jmf-server.jar provided in the JMF 1.1 023 * for Web Servers download. This JAR archive contains 024 * the necessary JMF all-Java runtime classes. JMF11Applet 025 * has been deployed in this manner for the June 1999 026 * column:

027 * http://www.javaworld.com/jw-06-1999/jw-06-media.html 028 * 029 * @author Bill Day < bill.day@javaworld.com > 030 * @version 1.1 031 * @see javax.media.ControllerEvent 032 * @see javax.media.ControllerListener 033 * @see javax.media.Manager 034 * @see javax.media.NoPlayerException 035 * @see javax.media.Player 036 * @see javax.media.RealizeCompleteEvent 037 **/ 038 039 public class JMF11Applet extends Applet implements ControllerListener { 040 private URL myURL = null; 041 private Player myPlayer = null; 042 private Component myVisual = null; 043 private Component myControls = null; 044 private Panel visualPanel = null; 045 046 /** 047 * Initialize JMF11Applet. We lay out the interface and 048 * create our player in the init(). 049 **/ 050 public void init() { 051 super.init(); 052 053 // Specify AWT Layout Manager. 054 setLayout (new BorderLayout()); 055 056 // Load URL from the Web page JMF11Applet is embedded in. 057 String asset = getParameter("ASSET"); 058 059 // Check the URL and create a URL object to hold it. 060 if (asset.equals("")) { 061 //we haven't entered an asset in the applet. 062 } else { 063 try { 064 myURL = new URL(getDocumentBase(),asset); 065 } catch (MalformedURLException e) { 066 //We entered an incomplete asset or built incorrect URL. 067 //More robust applet should handle this gracefully. 068 } 069 } 070 try { 071 //Here's an interesting bit. Manager is used to 072 //create the actual player for this URL. We then 073 //add JMF11Applet as a ControllerListener for myPlayer. 074 //This lets us respond to RealizeCompleteEvents. 075 myPlayer = Manager.createPlayer(myURL); 076 myPlayer.addControllerListener(this); 077 } catch (IOException e) { 078 // Encountered some problem with I/O; exit. 079 System.out.println("I/O problem attempting to create player...exiting"); 080 System.exit(1); 081 } catch (NoPlayerException e) { 082 // Unable to return a usable Player; exit. 083 System.out.println("No usable Player returned...exiting"); 084 System.exit(1); 085 } 086 } 087 088 /** 089 * Override the default applet start method to call Player's 090 * realize(). This will first do the realization, which in turn 091 * triggers the final bits of GUI building in the controllerUpdate() 092 * method. We do not automatically start playback: The user needs 093 * to click on the "play" button in our applet to start playing the 094 * media sample. 095 **/ 096 public void start() { 097 myPlayer.realize(); 098 } 099 100 101 /** 102 * Override the default applet stop method to call myPlayer.stop() 103 * and myPlayer.deallocate() so that we properly free up resources 104 * if someone exits this page in their browser. 105 **/ 106 public void stop() { 107 myPlayer.stop(); 108 myPlayer.deallocate(); 109 } 110 111 /** 112 * Since we must know when realize completes, we use 113 * controllerUpdate() to handle RealizeCompleteEvents. 114 * When we receive the RealizeCompleteEvent, we layout 115 * and display the video component and controls in our 116 * applet GUI. 117 **/ 118 public void controllerUpdate(ControllerEvent event) { 119 if (event instanceof RealizeCompleteEvent) { 120 //System.out.println("Received RCE..."); 121 // Now that we have a Realized player, we can get the 122 // VisualComponent and ControlPanelComponent and pack 123 // them into our applet. 124 myVisual = myPlayer.getVisualComponent(); 125 if (myVisual != null) { 126 // In order to ensure that the VisualComponent 127 // is not resized by BorderLayout, I nest it 128 // within visualPanel using FlowLayout. 129 visualPanel = new Panel(); 130 visualPanel.setLayout(new FlowLayout()); 131 visualPanel.add(myVisual); 132 add(visualPanel,BorderLayout.CENTER); 133 //System.out.println("Added VisualComponent..."); 134 } 135 myControls = myPlayer.getControlPanelComponent(); 136 if (myControls != null) { 137 add(myControls,BorderLayout.SOUTH); 138 //System.out.println("Added controls..."); 139 } 140 //invalidate(); 141 validate(); 142 } 143 // Else we simply consume the event. 144 } 145 }

I have included a simple example HTML document, example.html (which you can try in your browser right now by clicking here), to show you how to embed the applet into your own Web pages. Simply change the media file in the ASSET tag and off you go!

For this example, I used the JMF 1.1 for Web Servers download (documented on the JMF Web site) to enable JMF11Applet to automatically download jmf-server.jar, a code archive containing the necessary JMF runtime classes. This allows the applet to execute within any Java 1.1-compatible browser, with no software for the end user to install. (Note that the JMF for Web Servers version also includes a customization tool, JMFCustomizer, that will potentially allow you to remove even more unneeded classes from the JMF JAR file. This tool does not currently work under Java 2, however, as it uses an outdated package name for Swing.)

In the particular example embedded in example.html, we load a WAV file (welcome.wav), ascertain the appropriate control components to make available (no video component, since this is a sound-only media file), and play back the multimedia file. Note that the WAV file (600 KB) and JMF classes (570 KB) may require several minutes to download to your machine depending upon your connection speed.

After parsing the example page, Java 1.1-compliant browsers should load the applet and supporting JMF classes automatically from the JavaWorld Web server. Once the applet is loaded and running, you can press the Play button to begin playback of the WAV sound file. Try repositioning the playback using the scrollbar and pausing and restarting playback using the Pause/Play button.

The JMF 1.1 Java platform implementation uses all-Java widgets for its controls, so the controls have the same appearance from browser to browser and platform to platform. Notice how the applet looks running within Netscape Communicator's JVM on Solaris 7 and Microsoft's JVM in Internet Explorer on Win32.

Figure 1. JMF11Applet running on Solaris 7 in Netscape Communicator 4.51
Figure 2. JMF11Applet running on Win32 in Internet Explorer 4.01

The button labeled i provides information on the media file playing in the JMF applet. Click on this information link to get details on the WAV file running in this Web page.

Figure 3. Information for WAV file in Internet Explorer 4.01
1 2 Page 1
Page 1 of 2