Program multimedia with JMF, Part 2

Jump into the Java Media Framework's important classes and interfaces

If you know Java, multimedia programming is a piece of cake. Last month, in Part 1, you saw how many parts of the Java Media Framework (JMF) classes and interfaces can integrate together. In this article, you'll see working JMF code performing multimedia functions.

Read the whole "Program Multimedia with JMF" series:

However, before you start coding with JMF, you must install the reference implementation and the supporting applications as discussed below. You should also be aware of the hardware and software requirements. Examples in this article were tested using a Pentium III 800-MHz PC on Windows 2000 with a Logitech USB camera and a built-in microphone. Therefore, the solution presented here could be Windows-specific. Even though the code should not change when deployed to other platforms, the JMF reference implementation is not available for all Java platforms. The reference implementation is not currently available for Linux users, for instance.

Hardware and software requirements

To use JMF, you won't find it difficult to meet the hardware and software requirements. Your old 166-MHz Pentium proves sufficient as long as it has at least 32 MB of RAM. JMF can also run on 166-MHz or greater Power PC or UltraSparc systems. You need a SoundBlaster-compatible card for audio playback if you want sound. If you happen to use an AIX machine, you can use an Ultimedia-compatible sound card.

On Windows, the software requirements comprise:

  • Windows 95/98, Windows NT 4.0, or Windows 2000.
  • JDK 1.1.3 or later for Windows (from Sun). If you want to be safe on the Y2K compatibility issue, you should use JDK 1.1.6 or later.
  • JMF classes and native libraries.
  • A modern browser if you plan to use applets to display your video. Modern here means at least Netscape Communicator 4.05 with JDK 1.1 patch or Microsoft Internet Explorer 4.0 or later.

Get the reference implementation

Yes, you definitely need to download the Java Media Framework 2.1 reference implementation. Once at the download page, you can choose from the following:

  • "Cross-platform Java"
  • "Windows Performance Pack"
  • "Solaris SPARC Performance Pack"

As a Java developer, you may be tempted to download the "Cross-platform Java" version. However, select the "Windows Performance Pack" if you are working with Windows. The all-Java version isn't ideal, as it doesn't support audio and video capture. (Also, you may wish to check out the list of known platform-specific issues.)

In contrast to the all-Java version, JMF's Windows version supports all video capture devices that employ the VFW (Video for Windows) interface. Moreover, with this version, some cameras have been tested by Sun engineers. These include:

  • Alaris QuickVideo DVC1
  • QuickCam Home USB
  • WinTV on 95/98

In fact, JMF's Windows version supports almost any capture device. For the list of supported capture devices, go to:

Set up and run JMF 2.1 for Windows

After you download the JMF 2.1 into a directory, double-click the jmf-2_1-win.exefile to install the reference implementation with its classfiles and native libraries for running JMF players. Afterward, you need to make sure that InstallShield properly configured your CLASSPATH and PATH during installation. If not, you can do it manually with the following command:

set CLASSPATH=%WINDIR%\java\classes\jmf.jar;%WINDIR%\java\classes\sound.jar;.;%CLASSPATH%

Your PATH should be set to include the JMF library files:

set PATH=%WINDIR%\System32;%PATH% (on Windows NT) 
set PATH=%WINDIR%\System;%PATH% (on Windows 95/98)

If you later have a problem with the installation, Sun provides the JMF Diagnostics applet to verify that JMF is set up properly on your system.


If you plan to use a capture device such as a camera, you must make sure you have installed the correct device driver for that capture device. In addition, you need the JMFRegistryapplication.

The JMFRegistry, a standalone Java application, registers new DataSources, MediaHandlers, PlugIns, and capture devices with JMF so that you can use them with your JMF 2.1 installation. You need to run JMFRegistryonly once to register all capture devices available on the system.

After you run JMFRegistryfrom the command line or inside your Java tool, you should see a window similar to Figure 1.

Figure 1. Register your capture device with JMFRegistry Click on thumbnailto view full-size image. (71 KB)

Click the "Capture Devices" tab, and then click the "Detect Capture Devices" button. A list should display all the audio and video capture devices on the system. As seen in Figure 1, JMFRegistryfound JavaSound audio capture, a Logitech USB Video Camera, and Microsoft WDM Image Capture. Clicking a list item will display all formats that can be used for that capture device. For example, the Logitech USB camera in Figure 1 supports RGB color with a resolution of 352x288, 160x120, and so on.

If JMFRegistryfails to detect your capture device, it means there is something wrong with the device driver, installation process, or both.

JMFRegistryalso enables you to rearrange the search order and remove registered extensions.

The JMF API specification

When programming with JMF, it's helpful to have the JMF API specification. Note that JMF 2.1 is an implementation update, which means the implementation features new updates and fixes, but uses the same API as defined in JMF 2.0.

Also helpful are the sample JMF applications. These applications, especially JMStudio, contain the source code that you can consult when you want to learn more or when you have a problem with your code.

Our JMF project

Due to space limitations, it's impossible to implement all of JMF 2.1's features in our JMF project. I therefore chose three basic functions that you will always need with JMF:

  • Play multimedia files
  • Capture devices
  • Capture audio and video

The capture devices function must be run prior to capturing any audio and video data, but it's not needed to play multimedia files.

Our project comprises two classfiles: 1 in the source code) and 2).

Play multimedia files

In our project, we have a play()method in the JMFclass. This method plays a multimedia source file of our choice. As discussed in Part 1, to play a multimedia data source, you need a Player. In the code, dualPlayeris the object reference for Player:

Player dualPlayer;  //for merging audio and video data sources

dualPlayer, as the name implies, can play both audio and video data.

In the play()method, you get the filenamestring as the data source by using a FileDialogto browse your computer to choose a file:

  try {
    FileDialog fd = 
      new FileDialog(this, "Select File", FileDialog.LOAD);;
    String filename = fd.getDirectory() + fd.getFile();
    // . . .
  catch (Exception e) {

You then create a Playerindirectly through the media Manager. You can use the Manager's createPlayer()or createProcessor()to get a new Player. In our play()method, we use the createPlayer()method:

    dualPlayer = Manager.createPlayer
      (new MediaLocator("file:///" + filename));

Sometimes, in situations like ours, you might want to use a Playerto control other Players or Controllers. A single controlling Playercan invoke start(), stop(), setMediaTime(), and other methods on the entire group. The controlling Playermanages all of the state transitions and event postings. We then use the addControllerListener()to specify a ControllerListenerto which a Controllerwill send an event. The Controllerinterface provides resource-allocation state information, event generation, and a mechanism for obtaining objects that provide additional control over a Controller:


Lastly, we need to call the start()method, which starts the Playeras soon as possible. The start()method attempts to transition the Playerto the Started state. If the Playerhas not been Realized or Prefetched, start()automatically performs those actions. (For more information about Playerstates, refer to Part 1.)


Since the JMFclass implements the ControllerListenerinterface, we must implement the controllerUpdate()method, called when a Controller(with which this listener is registered) generates an event:

public synchronized void controllerUpdate(ControllerEvent event) {
  if (event instanceof RealizeCompleteEvent) {
    Component comp;
    if ((comp = dualPlayer.getVisualComponent()) != null)
      add ("Center", comp);
    if ((comp = dualPlayer.getControlPanelComponent()) != null)
      add("South", comp);

As soon as JMF generates RealizeCompleteEvent, the controllerUpdate()method adds the visual component and a control-panel component. With the visual component, the video data is played; whereas a control-panel component controls the media, such as play back, stop, and so on. Figure 3 at the end of this article shows a piece of video on the visual component. Notice the control panel lying under it.

It's interesting to note the following messages from the console. (These messages have been reformatted for reading convenience):

Starting player
Open log file: C:\123data\JavaProjects\JMF\JMF\jmf.log
Adding visual component
Adding control panel

As soon as you call the start()method, the Playerwill be changed to the Started state from whatever state it is currently in. The message above clearly describes the state transition from the Unrealized state to the Started state. When the EndOfMediaevent is invoked (the Playerhas finished playing the media), the state moves from Started back to Prefetched. Also note that when the RealizeCompleteevent is invoked, it quickly adds the visual component and the control panel.

Register capture devices

The register capture devices function in our JMF project acts as an internal function that does not register anything to outside the project. Its purpose: When multiple capture devices exist on the user's computer, tell the application what audio or video device the user wants to capture. Further, it tells the application what audio or video format to use when capturing. For example, an audio device may support a linear stereo sound format with a 44,100 times-per-second sampling rate or formats with lower sampling rates. When you select an audio device from the Audio Device(s) list, the Audio Format(s) List control will also get updated because each device can support different formats. Likewise, when you select a video device from the Video Device(s) list, the Video Format(s) values will be updated.

It is therefore important to get the device configuration before the capture process. In our JMF project, the CaptureDeviceDialogclass is a dialog that appears when the user clicks "Capture Device" from the "Configure" menu. Since capture device configuration must be done prior to capturing, the same dialog also displays if the user clicks "Capture" from the "Action" menu before any configuration is done.

The "Capture Device" dialog is shown in Figure 2.

Figure 2. "Capture Device" dialog Click on thumbnail to view full-size image. (28 KB)

Consider the init()method in the CaptureDeviceDialogclass. After the usual initialization for creating components on the dialog, the code continues by trying to obtain all capture devices available on the user's machine using the getDeviceList()static method of the CaptureDeviceManager:

    //get all the capture devices
    devices = CaptureDeviceManager.getDeviceList ( null );

CaptureDeviceManager, a manager class, provides access to a list of the capture devices available on the system. CaptureDeviceManageruses query mechanisms and a registry to locate devices and return CaptureDeviceInfoobjects for available devices. The CaptureDeviceManageralso registers new capture devices.

1 2 Page 1
Page 1 of 2