Mark's Steps to Using JMF

Step #1: Get a file name, make a File object

  1. To use the File class, you must import java.io.*; at the top of your source file.
  2. In a Console app, you can just get a file name from the command line, like so:
    public static void main(String[] args) {
    	if (args.length < 1) {
    		System.err.println("usage: ConsolePlayer soundFile");
    		System.exit(1);
    	}
    
    	// made it to here? then we have an arg. make a file from it
    	// (Note: this next line may throw an exception.)
    	File file = new File(args[0]);
    	...
    
  3. In a GUI application, you will want to use the: JFileChooser (see my Using JFileChooser" page.

Step #2: Construct a URL from the File

  1. To use the URL class, you must import java.net.*; at the top of your source file.
  2. First, you need to get the "canonical path" of the file. The "canonical path" is basically an absolute path (i.e. one that starts from the root directory) with all extraneous ".."s and extra slashes removed. The following code accomplishes this:
    String path = file.getCanonicalPath();
  3. Second, you need to make a URL string, as follows. (Note: The leading "file://" shows which protocol we use for this URL.)
    String urlString = "file://" + path;
  4. Third: Create a new URL from the string:
    URL url = new URL(urlString);
  5. Note: You could do all the above steps in one line if you wanted to.

Step #3: Create a new Player from the URL

  1. To use the JMF classes, you must import javax.media.*; at the top of your source file.
  2. Create a new player as follows. (Note: 'Player' is actually an interface.) (Aside: This is an example of a "factory" method, or a "makes-a" relationship.)
    Player player = Manager.createPlayer(url);
  3. (Optional step, but we usually do it in GUI apps) Listen for controller events sent by the player.
    1. Have a class (probably your frame ) implement the ControllerListener interface:
      class MyFrame extends JFrame implements ControllerListener { ...
    2. Tell the player that the frame will listen for controller events:
      player.addControllerListener(this);
    3. Override The controllerUpdate() method that the frame inherits from the ControllerListener:
      public void controllerUpdate(ControllerEvent e) { ...
    4. In the body of the controllerUpdate() method, you can test the particular instance of the ControllerEvent to track the state of the player. Sample code would look like: (Note: "instanceof" is a keyword, not a method.)
      if (e instanceof EventType)
    5. Here are some examples of event types that you could substitute in place of EventType: (See the JMF state model page for further explanation of the states.)
      1. RealizeCompleteEvent: Realizing is done, player is now in 'realized' state. This means it knows about the media file's meta-information.
      2. PrefetchCompleteEvent: As with realize, we are done prefetching (buffering) the media.
      3. StartEvent: The user hit the "play" button, or we called player.start().
      4. StopByRequestEvent: Pause button hit by user.
      5. EndOfMediaEvent: Done playing the file.

Step #4: Realize the Media

  1. Call player.realize() to download the meta-information about the media file. (Refer to the JMF state model.)
  2. When the media is realized (See step 3-B-5-a), you can now add a visual component (if it's a video), like so:
    visualComponent = player.getVisualComponent();
    if (visualComponent != null) {
    	getContentPane().add(BorderLayout.CENTER, visualComponent);
    }
    
  3. Additionaly, you can add the control (panel) component (something you will often want to do) as follows. Note: we could make our own set of buttons & slider, but the canned ones are convenient.
    controlComponent = player.getControlPanelComponent();
    if (controlComponent != null) {
    	getContentPane().add(BorderLayout.SOUTH, controlComponent);
    }
    

Step #5: Prefetch the Media

  1. Call player.prefetch() to buffer the media. (Again, refer, state diagram for where this puts us.)
  2. Aside: We could display a progress bar here if we wanted to to show the buffering status; there is a canned one we can use. (Perhaps a future revision of this tutorial will cover that...)

Step #6: Start Playing

  1. Call player.start() to get the media playing.
  2. Note: We could actually do steps 4-6 in one step by just calling .start() (as that will automatically advance it through other steps), but we might want to do things at the intervening milestones, such as display meta-information when it's available, or show the user how far along we are in the process.

Step #7: Cleanup

  1. Call player.stop(); to make sure it's stopped; you can't deallocate a start'ed player (which we do next).
  2. Call player.deallocate(); maybe this is done in destructor, but we want to make sure memory and other resources are freed up, so we do it by hand.