Java/2D Graphics GUI/Media

Материал из Java эксперт
Перейти к: навигация, поиск

A Bare Bones Player: play the media object

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

/*******************************************************************************

* A "Bare Bones" Player Applet (BBP Applet) that will play the media object
* indicated in the "media2Play" property of the Applet tag.
* 
*

* The applet demonstrates the relative ease with which the JMF can be employed, * particularly for playing. The applet a minimal player, placing the controls * for the player and the visual component for the played object within the * Applet. The object plays once, but can be controlled by the user through the * control panel provided. * * <p> * The tag for the Applet should look something like: * * * * @author Spike Barlow ******************************************************************************/ import java.applet.*; import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; import java.util.*; import javax.media.*; public class BBPApplet extends Applet implements ControllerListener { /*************************************************************************** * Object to play the media. Only attribute that the Applet really needs. **************************************************************************/ protected Player player; /*************************************************************************** * The name of the media to be played. **************************************************************************/ protected String nameOfMedia2Play; /*************************************************************************** * Name of the Property field within the applet tage indicating the name of * the media to play. **************************************************************************/ private static final String MEDIA_NAME_PROPERTY = "media2Play"; /*************************************************************************** * Object describing the location of the media to be played. **************************************************************************/ protected MediaLocator locator; /*************************************************************************** * Initialise the applet by attempting to create and start a Player object * capable of playing the media specified in the applet tag. **************************************************************************/ public void init() { setLayout(new BorderLayout()); setBackground(Color.lightGray); try { nameOfMedia2Play = (new URL(getDocumentBase(), getParameter(MEDIA_NAME_PROPERTY))).toExternalForm(); locator = new MediaLocator(nameOfMedia2Play); player = Manager.createPlayer(locator); player.addControllerListener(this); player.start(); } catch (Exception e) { throw new Error("Couldn"t initialise BBPApplet: " + e.getMessage()); } } /*************************************************************************** * Respond to ControllerEvents from the Player that was created. For the * bare bones player the only event of import is the RealizeCompleteEvent. * At that stage the visual component and controller for the Player can * finally be obtained and thus displayed. **************************************************************************/ public synchronized void controllerUpdate(ControllerEvent e) { if (e instanceof RealizeCompleteEvent) { add(player.getVisualComponent(), "North"); add(player.getControlPanelComponent(), "South"); validate(); } } } </source>

Capture audio or video through devices connected to the PC

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

import javax.media.*; import javax.media.format.*; import javax.media.protocol.*; import java.util.*; /*******************************************************************************

* A simple application to allow users to capture audio or video through devices
* connected to the PC. Via command-line arguments the user specifies whether
* audio (-a) or video (-v) capture, the duration of the capture (-d) in
* seconds, and the file to write the media to (-f).
* 
* The application would be far more useful and versatile if it provided control
* over the formats of the audio and video captured as well as the content type
* of the output.
* 
* The class searches for capture devices that support the particular default
* track formats: linear for audio and Cinepak for video. As a fall-back two
* device names are hard-coded into the application as an example of how to
* obtain DeviceInfo when a device"s name is known. The user may force the
* application to use these names by using the -k (known devices) flag.
* 
* The class is static but employs the earlier Location2Location example to
* perform all the Processor and DataSink related work. Thus the application
* chiefly involves CaptureDevice related operations.
* 
* @author Michael (Spike) Barlow
******************************************************************************/

public class SimpleRecorder {

 /////////////////////////////////////////////////////////////
 // Names for the audio and video capture devices on the
 // author"s system. These will vary system to system but are
 // only used as a fallback.
 /////////////////////////////////////////////////////////////
 private static final String AUDIO_DEVICE_NAME = "DirectSoundCapture";
 private static final String VIDEO_DEVICE_NAME = "vfw:Microsoft WDM Image Capture:0";
 ///////////////////////////////////////////////////////////
 // Default names for the files to write the output to for
 // the case where they are not supplie by the user.
 //////////////////////////////////////////////////////////
 private static final String DEFAULT_AUDIO_NAME = "file://./captured.wav";
 private static final String DEFAULT_VIDEO_NAME = "file://./captured.avi";
 ///////////////////////////////////////////
 // Type of capture requested by the user.
 //////////////////////////////////////////
 private static final String AUDIO = "audio";
 private static final String VIDEO = "video";
 private static final String BOTH = "audio and video";
 ////////////////////////////////////////////////////////////////////
 // The only audio and video formats that the particular application
 // supports. A better program would allow user selection of formats
 // but would grow past the small example size.
 ////////////////////////////////////////////////////////////////////
 private static final Format AUDIO_FORMAT = new AudioFormat(
     AudioFormat.LINEAR);
 private static final Format VIDEO_FORMAT = new VideoFormat(
     VideoFormat.CINEPAK);
 public static void main(String[] args) {
   //////////////////////////////////////////////////////
   // Object to handle the processing and sinking of the
   // data captured from the device.
   //////////////////////////////////////////////////////
   Location2Location capture;
   /////////////////////////////////////
   // Audio and video capture devices.
   ////////////////////////////////////
   CaptureDeviceInfo audioDevice = null;
   CaptureDeviceInfo videoDevice = null;
   /////////////////////////////////////////////////////////////
   // Capture device"s "location" plus the name and location of
   // the destination.
   /////////////////////////////////////////////////////////////
   MediaLocator captureLocation = null;
   MediaLocator destinationLocation;
   String destinationName = null;
   ////////////////////////////////////////////////////////////
   // Formats the Processor (in Location2Location) must match.
   ////////////////////////////////////////////////////////////
   Format[] formats = new Format[1];
   ///////////////////////////////////////////////
   // Content type for an audio or video capture.
   //////////////////////////////////////////////
   ContentDescriptor audioContainer = new ContentDescriptor(
       FileTypeDescriptor.WAVE);
   ContentDescriptor videoContainer = new ContentDescriptor(
       FileTypeDescriptor.MSVIDEO);
   ContentDescriptor container = null;
   ////////////////////////////////////////////////////////////////////
   // Duration of recording (in seconds) and period to wait afterwards
   ///////////////////////////////////////////////////////////////////
   double duration = 10;
   int waitFor = 0;
   //////////////////////////
   // Audio or video capture?
   //////////////////////////
   String selected = AUDIO;
   ////////////////////////////////////////////////////////
   // All devices that support the format in question.
   // A means of "ensuring" the program works on different
   // machines with different capture devices.
   ////////////////////////////////////////////////////////
   Vector devices;
   //////////////////////////////////////////////////////////
   // Whether to search for capture devices that support the
   // format or use the devices whos names are already
   // known to the application.
   //////////////////////////////////////////////////////////
   boolean useKnownDevices = false;
   /////////////////////////////////////////////////////////
   // Process the command-line options as to audio or video,
   // duration, and file to save to.
   /////////////////////////////////////////////////////////
   for (int i = 0; i < args.length; i++) {
     if (args[i].equals("-d")) {
       try {
         duration = (new Double(args[++i])).doubleValue();
       } catch (NumberFormatException e) {
       }
     } else if (args[i].equals("-w")) {
       try {
         waitFor = Integer.parseInt(args[++i]);
       } catch (NumberFormatException e) {
       }
     } else if (args[i].equals("-a")) {
       selected = AUDIO;
     } else if (args[i].equals("-v")) {
       selected = VIDEO;
     } else if (args[i].equals("-b")) {
       selected = BOTH;
     } else if (args[i].equals("-f")) {
       destinationName = args[++i];
     } else if (args[i].equals("-k")) {
       useKnownDevices = true;
     } else if (args[i].equals("-h")) {
       System.out
           .println("Call as java SimpleRecorder [-a | -v | -b] [-d duration] [-f file] [-k] [-w wait]");
       System.out
           .println("\t-a\tAudio\n\t-v\tVideo\n\t-b\tBoth audio and video (system dependent)");
       System.out.println("\t-d\trecording Duration (seconds)");
       System.out
           .println("\t-f\tFile to save to\n\t-k\tuse Known device names (don"t search for devices)");
       System.out
           .println("\t-w\tWait the specified time (seconds) before abandoning capture");
       System.out
           .println("Defaults: 10 seconds, audio, and captured.wav or captured.avi, 4x recording duration wait");
       System.exit(0);
     }
   }
   /////////////////////////////////////////////////////////////////
   // Perform setup for audio capture. Includes finding a suitable
   // device, obatining its MediaLocator and setting the content
   // type.
   ////////////////////////////////////////////////////////////////
   if (selected.equals(AUDIO)) {
     devices = CaptureDeviceManager.getDeviceList(AUDIO_FORMAT);
     if (devices.size() > 0 && !useKnownDevices) {
       audioDevice = (CaptureDeviceInfo) devices.elementAt(0);
     } else
       audioDevice = CaptureDeviceManager.getDevice(AUDIO_DEVICE_NAME);
     if (audioDevice == null) {
       System.out.println("Can"t find suitable audio device. Exiting");
       System.exit(1);
     }
     captureLocation = audioDevice.getLocator();
     formats[0] = AUDIO_FORMAT;
     if (destinationName == null)
       destinationName = DEFAULT_AUDIO_NAME;
     container = audioContainer;
   }
   /////////////////////////////////////////////////////////////////
   // Perform setup for video capture. Includes finding a suitable
   // device, obatining its MediaLocator and setting the content
   // type.
   ////////////////////////////////////////////////////////////////
   else if (selected.equals(VIDEO)) {
     devices = CaptureDeviceManager.getDeviceList(VIDEO_FORMAT);
     if (devices.size() > 0 && !useKnownDevices)
       videoDevice = (CaptureDeviceInfo) devices.elementAt(0);
     else
       videoDevice = CaptureDeviceManager.getDevice(VIDEO_DEVICE_NAME);
     if (videoDevice == null) {
       System.out.println("Can"t find suitable video device. Exiting");
       System.exit(1);
     }
     captureLocation = videoDevice.getLocator();
     formats[0] = VIDEO_FORMAT;
     if (destinationName == null)
       destinationName = DEFAULT_VIDEO_NAME;
     container = videoContainer;
   } else if (selected.equals(BOTH)) {
     captureLocation = null;
     formats = new Format[2];
     formats[0] = AUDIO_FORMAT;
     formats[1] = VIDEO_FORMAT;
     container = videoContainer;
     if (destinationName == null)
       destinationName = DEFAULT_VIDEO_NAME;
   }
   ////////////////////////////////////////////////////////////////////
   // Perform all the necessary Processor and DataSink preparation via
   // the Location2Location class.
   ////////////////////////////////////////////////////////////////////
   destinationLocation = new MediaLocator(destinationName);
   System.out.println("Configuring for capture. Please wait.");
   capture = new Location2Location(captureLocation, destinationLocation,
       formats, container, 1.0);
   /////////////////////////////////////////////////////////////////////////////
   // Start the recording and tell the user. Specify the length of the
   // recording. Then wait around for up to 4-times the duration of
   // recording
   // (can take longer to sink/write the data so should wait a bit incase).
   /////////////////////////////////////////////////////////////////////////////
   System.out.println("Started recording " + duration + " seconds of "
       + selected + " ...");
   capture.setStopTime(new Time(duration));
   if (waitFor == 0)
     waitFor = (int) (4000 * duration);
   else
     waitFor *= 1000;
   int waited = capture.transfer(waitFor);
   /////////////////////////////////////////////////////////
   // Report on the success (or otherwise) of the recording.
   /////////////////////////////////////////////////////////
   int state = capture.getState();
   if (state == Location2Location.FINISHED)
     System.out.println(selected
         + " capture successful in approximately "
         + ((int) ((waited + 500) / 1000))
         + " seconds. Data written to " + destinationName);
   else if (state == Location2Location.FAILED)
     System.out.println(selected
         + " capture failed after approximately "
         + ((int) ((waited + 500) / 1000)) + " seconds");
   else {
     System.out.println(selected
         + " capture still ongoing after approximately "
         + ((int) ((waited + 500) / 1000)) + " seconds");
     System.out.println("Process likely to have failed");
   }
   System.exit(0);
 }

}

      </source>   



Choose the media they wish to play

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

import java.awt.*; import java.awt.event.*; import javax.media.*; import javax.media.protocol.*; import javax.media.control.*; import java.io.*; /*******************************************************************************

* A Graphical application allowing the user to choose the media they wish to
* play. PlayerOfMedia presents a Dialog in which the user may enter the URL of
* the media to play, or select a file from the local system.
* 
* @author Spike Barlow
******************************************************************************/

public class PlayerOfMedia extends Frame implements ActionListener,

   ControllerListener {
 /** Location of the media. */
 MediaLocator locator;
 /** Player for the media */
 Player player;
 /** Dialog for user to select media to play. */
 Dialog selectionDialog;
 /** Buttons on user dialog box. */
 Button cancel, open, choose;
 /** Field for user to enter media filename */
 TextField mediaName;
 /** The menus */
 MenuBar bar;
 Menu fileMenu;
 /** Dialog for informing user of errors. */
 Dialog errorDialog;
 Label errorLabel;
 Button ok;
 /** Graphical component for controlling player. */
 Component controlComponent;
 /** Graphical component showing what isbeing played. */
 Component visualComponent;
 /** Graphical component to show download progress. */
 Component progressBar;
 /** Sizes to ensure Frame is correctly sized. */
 Dimension controlSize;
 Dimension visualSize;
 int menuHeight = 50;
 /** Directory user last played a file from. */
 String lastDirectory = null;
 /** Flags indicating conditions for resizing the Frame. */
 protected static final int VISUAL = 1;
 protected static final int PROGRESS = 2;
 /***************************************************************************
  * Construct a PlayerOfMedia. The Frame will have the default title of
  * "Player of Media". All initial actions on the PlayerOfMedia object are
  * initiated through its menu (or shotcut key).
  **************************************************************************/
 PlayerOfMedia() {
   this("Player of Media");
 }
 /***************************************************************************
  * Construct a PlayerOfMedia. The Frame will have the title supplied by the
  * user. All initial actions on the PlayerOfMedia object are initiated
  * through its menu (or shotcut key).
  **************************************************************************/
 PlayerOfMedia(String name) {
   super(name);
   ///////////////////////////////////////////////////////////
   // Setup the menu system: a "File" menu with Open and Quit.
   ///////////////////////////////////////////////////////////
   bar = new MenuBar();
   fileMenu = new Menu("File");
   MenuItem openMI = new MenuItem("Open...", new MenuShortcut(
       KeyEvent.VK_O));
   openMI.setActionCommand("OPEN");
   openMI.addActionListener(this);
   fileMenu.add(openMI);
   MenuItem quitMI = new MenuItem("Quit", new MenuShortcut(KeyEvent.VK_Q));
   quitMI.addActionListener(this);
   quitMI.setActionCommand("QUIT");
   fileMenu.add(quitMI);
   bar.add(fileMenu);
   setMenuBar(bar);
   ///////////////////////////////////////////////////////
   // Layout the frame, its position on screen, and ensure
   // window closes are dealt with properly, including
   // relinquishing the resources of any Player.
   ///////////////////////////////////////////////////////
   setLayout(new BorderLayout());
   setLocation(100, 100);
   addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       if (player != null) {
         player.stop();
         player.close();
       }
       System.exit(0);
     }
   });
   /////////////////////////////////////////////////////
   // Build the Dialog box by which the user can select
   // the media to play.
   /////////////////////////////////////////////////////
   selectionDialog = new Dialog(this, "Media Selection");
   Panel pan = new Panel();
   pan.setLayout(new GridBagLayout());
   GridBagConstraints gbc = new GridBagConstraints();
   mediaName = new TextField(40);
   gbc.gridx = 0;
   gbc.gridy = 0;
   gbc.gridwidth = 2;
   pan.add(mediaName, gbc);
   choose = new Button("Choose File...");
   gbc.ipadx = 10;
   gbc.ipady = 10;
   gbc.gridx = 2;
   gbc.gridwidth = 1;
   pan.add(choose, gbc);
   choose.addActionListener(this);
   open = new Button("Open");
   gbc.gridy = 1;
   gbc.gridx = 1;
   pan.add(open, gbc);
   open.addActionListener(this);
   cancel = new Button("Cancel");
   gbc.gridx = 2;
   pan.add(cancel, gbc);
   cancel.addActionListener(this);
   selectionDialog.add(pan);
   selectionDialog.pack();
   selectionDialog.setLocation(200, 200);
   ////////////////////////////////////////////////////
   // Build the error Dialog box by which the user can
   // be informed of any errors or problems.
   ////////////////////////////////////////////////////
   errorDialog = new Dialog(this, "Error", true);
   errorLabel = new Label("");
   errorDialog.add(errorLabel, "North");
   ok = new Button("OK");
   ok.addActionListener(this);
   errorDialog.add(ok, "South");
   errorDialog.pack();
   errorDialog.setLocation(150, 300);
   Manager.setHint(Manager.PLUGIN_PLAYER, new Boolean(true));
 }
 /***************************************************************************
  * React to menu selections (quit or open) or one of the the buttons on the
  * dialog boxes.
  **************************************************************************/
 public void actionPerformed(ActionEvent e) {
   if (e.getSource() instanceof MenuItem) {
     //////////////////////////////////////////////////
     // Quit and free up any player acquired resources.
     //////////////////////////////////////////////////
     if (e.getActionCommand().equalsIgnoreCase("QUIT")) {
       if (player != null) {
         player.stop();
         player.close();
       }
       System.exit(0);
     }
     /////////////////////////////////////////////////////////
     // User to open/play media. Show the selection dialog box.
     /////////////////////////////////////////////////////////
     else if (e.getActionCommand().equalsIgnoreCase("OPEN")) {
       selectionDialog.show();
     }
   }
   //////////////////////
   // One of the Buttons.
   //////////////////////
   else {
     /////////////////////////////////////////////////////////////
     // User to browse the local file system. Popup a file dialog.
     /////////////////////////////////////////////////////////////
     if (e.getSource() == choose) {
       FileDialog choice = new FileDialog(this, "Media File Choice",
           FileDialog.LOAD);
       if (lastDirectory != null)
         choice.setDirectory(lastDirectory);
       choice.show();
       String selection = choice.getFile();
       if (selection != null) {
         lastDirectory = choice.getDirectory();
         mediaName.setText("file://" + choice.getDirectory()
             + selection);
       }
     }
     ///////////////////////////////////////////////
     // User chooses to cancel opening of new media.
     ///////////////////////////////////////////////
     else if (e.getSource() == cancel) {
       selectionDialog.hide();
     }
     ///////////////////////////////////////////////////////
     // User has selected the name of the media. Attempt to
     // create a Player.
     ///////////////////////////////////////////////////////
     else if (e.getSource() == open) {
       selectionDialog.hide();
       createAPlayer(mediaName.getText());
     }
     ////////////////////////////////////////////
     // User has seen error message. Now hide it.
     ////////////////////////////////////////////
     else if (e.getSource() == ok)
       errorDialog.hide();
   }
 }
 /***************************************************************************
  * Attempt to create a Player for the media who"s name is passed the the
  * method. If successful the object will listen to the new Player and start
  * it towards Realized.
  **************************************************************************/
 protected void createAPlayer(String nameOfMedia) {
   ////////////////////////////////////////////////////////////
   // If an existing player then stop listening to it and free
   // up its resources.
   ////////////////////////////////////////////////////////////
   if (player != null) {
     System.out.println("Stopping and closing previous player");
     player.removeControllerListener(this);
     player.stop();
     player.close();
   }
   ///////////////////////////////////////////////////////////
   // Use Manager class to create Player from a MediaLocator.
   // If exceptions are thrown then inform user and recover
   // (go no further).
   //////////////////////////////////////////////////////////
   locator = new MediaLocator(nameOfMedia);
   try {
     System.out.println("Creating player");
     player = Manager.createPlayer(locator);
   } catch (IOException ioe) {
     errorDialog("Can"t open " + nameOfMedia);
     return;
   } catch (NoPlayerException npe) {
     errorDialog("No player available for " + nameOfMedia);
     return;
   }
   //////////////////////////////////////////////////////////
   // Player created successfully. Start listening to it and
   // realize it.
   //////////////////////////////////////////////////////////
   player.addControllerListener(this);
   System.out.println("Attempting to realize player");
   player.realize();
 }
 /***************************************************************************
  * Popup a dialog box informing the user of some error. The passed argument
  * isthe text of the message.
  **************************************************************************/
 protected void errorDialog(String errorMessage) {
   errorLabel.setText(errorMessage);
   errorDialog.pack();
   errorDialog.show();
 }
 /***************************************************************************
  * Resize the Frame (window) due to the addition or removal of Components.
  **************************************************************************/
 protected void resize(int mode) {
   //////////////////////////////////////////
   // Player"s display and controls in frame.
   //////////////////////////////////////////
   if (mode == VISUAL) {
     int maxWidth = (int) Math.max(controlSize.width, visualSize.width);
     setSize(maxWidth, controlSize.height + visualSize.height
         + menuHeight);
   }
   ////////////////////////////////
   // Progress bar (only) in frame.
   ////////////////////////////////
   else if (mode == PROGRESS) {
     Dimension progressSize = progressBar.getPreferredSize();
     setSize(progressSize.width, progressSize.height + menuHeight);
   }
   validate();
 }
 /***************************************************************************
  * React to events from the player so as to drive the presentation or catch
  * any exceptions.
  **************************************************************************/
 public synchronized void controllerUpdate(ControllerEvent e) {
   ///////////////////////////////////////
   // Events from a "dead" player. Ignore.
   ///////////////////////////////////////
   if (player == null)
     return;
   ////////////////////////////////////////////////////////////
   // Player has reached realized state. Need to tidy up any
   // download or visual components from previous player. Then
   // obtain visual and control components for the player,add
   // them to the screen and resize window appropriately.
   ////////////////////////////////////////////////////////////
   if (e instanceof RealizeCompleteEvent) {
     ////////////////////////////////////////////////////
     // Remove any inappropriate Components from display.
     ////////////////////////////////////////////////////
     if (progressBar != null) {
       remove(progressBar);
       progressBar = null;
     }
     if (controlComponent != null) {
       remove(controlComponent);
       validate();
     }
     if (visualComponent != null) {
       remove(visualComponent);
       validate();
     }
     ///////////////////////////////////////////////////////
     // Add control and visual components for new player to
     // display.
     //////////////////////////////////////////////////////
     controlComponent = player.getControlPanelComponent();
     if (controlComponent != null) {
       controlSize = controlComponent.getPreferredSize();
       add(controlComponent, "Center");
     } else
       controlSize = new Dimension(0, 0);
     visualComponent = player.getVisualComponent();
     if (visualComponent != null) {
       visualSize = visualComponent.getPreferredSize();
       add(visualComponent, "North");
     } else
       visualSize = new Dimension(0, 0);
     //////////////////////////////////////////////////////////
     // Resize frame for new components and move to prefetched.
     //////////////////////////////////////////////////////////
     resize(VISUAL);
     System.out.println("Player is now pre-fetching");
     player.prefetch();
   }
   ////////////////////////////////////////////////////////////
   // Provide user with a progress bar for "lengthy" downloads.
   ////////////////////////////////////////////////////////////
   else if (e instanceof CachingControlEvent
       && player.getState() <= Player.Realizing && progressBar == null) {
     CachingControlEvent cce = (CachingControlEvent) e;
     progressBar = cce.getCachingControl().getControlComponent();
     if (progressBar != null) {
       add(progressBar, "Center");
       resize(PROGRESS);
     }
   }
   ////////////////////////////////////////////////
   // Player initialisation complete. Start it up.
   ////////////////////////////////////////////////
   else if (e instanceof PrefetchCompleteEvent) {
     System.out.println("Pre-fetching complete, now starting");
     player.start();
   }
   ///////////////////////////////////////////////////////
   // Reached end of media. Start over from the beginning.
   ///////////////////////////////////////////////////////
   else if (e instanceof EndOfMediaEvent) {
     player.setMediaTime(new Time(0));
     System.out.println("End of Media - restarting");
     player.start();
   }
   //////////////////////////////////////////////////////////////
   // Some form of error. Free up all resources associated with
   // the player, don"t listen to it anymore, and inform the
   // user.
   //////////////////////////////////////////////////////////////
   else if (e instanceof ControllerErrorEvent) {
     player.removeControllerListener(this);
     player.stop();
     player.close();
     errorDialog("Controller Error, abandoning media");
   }
 }
 /***************************************************************************
  * Create a PlayerOfMedia object and pop it up on the screen for the user to
  * interact with.
  **************************************************************************/
 public static void main(String[] args) {
   PlayerOfMedia ourPlayer = new PlayerOfMedia();
   ourPlayer.pack();
   ourPlayer.setSize(200, 100);
   ourPlayer.show();
 }

}

      </source>   



Do Audio Capture

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

import javax.media.*; import javax.media.format.*; import javax.media.protocol.*; public class DoAudioCapture {

 public static void main(String[] args) {
   Location2Location capture;
   CaptureDeviceInfo audioDevice;
   MediaLocator audioLocation;
   MediaLocator destination;
   audioDevice = CaptureDeviceManager.getDevice("DirectSoundCapture");
   audioLocation = audioDevice.getLocator();
   Format[] format = new Format[1];
   format[0] = new AudioFormat(AudioFormat.LINEAR);
   ContentDescriptor container = new ContentDescriptor(
       FileTypeDescriptor.WAVE);
   destination = new MediaLocator(
       "file://d:\\jmf\\book\\media\\capturedSound.wav");
   capture = new Location2Location(audioLocation, destination, format,
       container, 1.0);
   System.out.println("Started recording...");
   capture.setStopTime(new Time(10.0));
   int waited = capture.transfer(35000);
   int state = capture.getState();
   System.out.println("Waited " + waited + " milliseconds. State now "
       + state);
   waited /= 1000;
   while (state != Location2Location.FINISHED
       && state != Location2Location.FAILED) {
     try {
       Thread.sleep(10000);
     } catch (InterruptedException ie) {
     }
     System.out.println("Waited another 10 seconds, state = "
         + capture.getState());
     waited += 10;
   }
   System.out.println("Waited a total of " + waited + " seconds");
   System.exit(0);
 }

}

      </source>   



Java Media: Find Components

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

import java.awt.image.DirectColorModel; public class FindComponents {

 DirectColorModel dcm32;
 DirectColorModel dcm16;
 int[] components;
 float[] componentsf;
 int value32;
 short value16;
 int red8, green8, blue8, alpha8;
 short red5, green5, blue5;
 /**
  * FindComponents.java -- prints out normalized color components for two
  * different
  */
 public FindComponents() {
   red8 = red5 = 30;
   green8 = green5 = 20;
   blue8 = blue5 = 10;
   alpha8 = 255;
   dcm32 = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff,
       0xff000000);
   value32 = (alpha8 << 24) + (red8 << 16) + (green8 << 8) + blue8;
   components = dcm32.getComponents(value32, null, 0);
   componentsf = dcm32.getNormalizedComponents(components, 0, null, 0);
   System.out.println("Normalized components are: ");
   for (int i = 0; i < componentsf.length; i++)
     System.out.println("\t" + componentsf[i]);
   dcm16 = new DirectColorModel(16, 0x7c00, 0x3e0, 0x1f);
   value16 = (short) ((red5 << 10) + (green5 << 5) + blue5);
   components = dcm16.getComponents(value16, null, 0);
   componentsf = dcm16.getNormalizedComponents(components, 0, null, 0);
   System.out.println("Normalized components are: ");
   for (int i = 0; i < componentsf.length; i++)
     System.out.println("\t" + componentsf[i]);
 }
 public static void main(String[] args) {
   new FindComponents();
 }

}

      </source>   



List all capture devices currently known to the JMF

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

import javax.media.*; import java.util.*; /*******************************************************************************

* Simple application to list all capture devices currently known to the JMF.
* The CaptureDeviceManager is queried as to known devices and its output
* printed to the screen.
* 
* @author Michael (Spike) Barlow
******************************************************************************/

public class ListCaptureDevices {

 public static void main(String[] args) {
   /////////////////////////////////////////////////////////////
   // Query CaptureDeviceManager about ANY capture devices (null
   // format)
   Vector info = CaptureDeviceManager.getDeviceList(null);
   if (info == null)
     System.out.println("No Capture devices known to JMF");
   else {
     System.out.println("The following " + info.size()
         + " capture devices are known to the JMF");
     for (int i = 0; i < info.size(); i++)
       System.out
           .println("\t" + (CaptureDeviceInfo) info.elementAt(i));
   }
 }

}

      </source>   



Play the media object

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

/*******************************************************************************

* A "Bare Bones" Player Applet (BBP Applet) that will play the media object
* indicated in the "media2Play" property of the Applet tag.
* 
* <p>
* The applet demonstrates the relative ease with which the JMF can be employed,
* particularly for playing. The applet a minimal player, placing the controls
* for the player and the visual component for the played object within the
* Applet. The object plays once, but can be controlled by the user through the
* control panel provided.
* 
* <p>
* The tag for the Applet should look something like:
* 
* 
* 
* @author Spike Barlow
******************************************************************************/

import java.applet.*; import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; import java.util.*; import javax.media.*; public class TimedPApplet extends Applet implements ControllerListener {

 /***************************************************************************
  * Object to play the media. Only attribute that the Applet really needs.
  **************************************************************************/
 protected Player player;
 /***************************************************************************
  * The name of the media to be played.
  **************************************************************************/
 protected String nameOfMedia2Play;
 /***************************************************************************
  * Name of the Property field within the applet tage indicating the name of
  * the media to play.
  **************************************************************************/
 private static final String MEDIA_NAME_PROPERTY = "media2Play";
 /***************************************************************************
  * Object describing the location of the media to be played.
  **************************************************************************/
 protected MediaLocator locator;
 protected SystemTimeBase timer;
 /***************************************************************************
  * Initialise the applet by attempting to create and start a Player object
  * capable of playing the media specified in the applet tag.
  **************************************************************************/
 public void init() {
   setLayout(new BorderLayout());
   setBackground(Color.lightGray);
   try {
     nameOfMedia2Play = (new URL(getDocumentBase(),
         getParameter(MEDIA_NAME_PROPERTY))).toExternalForm();
     locator = new MediaLocator(nameOfMedia2Play);
     player = Manager.createPlayer(locator);
     player.addControllerListener(this);
     timer = new SystemTimeBase();
     player.start();
   } catch (Exception e) {
     throw new Error("Couldn"t initialise BBPApplet: " + e.getMessage());
   }
 }
 /***************************************************************************
  * Respond to ControllerEvents from the Player that was created. For the
  * bare bones player the only event of import is the RealizeCompleteEvent.
  * At that stage the visual component and controller for the Player can
  * finally be obtained and thus displayed.
  **************************************************************************/
 public synchronized void controllerUpdate(ControllerEvent e) {
   System.out.println("" + (double) timer.getNanoseconds()
       / Time.ONE_SECOND + ": " + e);
   if (e instanceof RealizeCompleteEvent) {
     add(player.getVisualComponent(), "North");
     add(player.getControlPanelComponent(), "South");
     validate();
   }
 }

}

      </source>   



Play the media object 3

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

/*******************************************************************************

* A "Bare Bones" Player Applet (BBP Applet) that will play the media object
* indicated in the "media2Play" property of the Applet tag.
* 
* <p>
* The applet demonstrates the relative ease with which the JMF can be employed,
* particularly for playing. The applet a minimal player, placing the controls
* for the player and the visual component for the played object within the
* Applet. The object plays once, but can be controlled by the user through the
* control panel provided.
* 
* <p>
* The tag for the Applet should look something like:
* 
* 
* 
* @author Spike Barlow
******************************************************************************/

import java.applet.*; import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; import java.util.*; import javax.media.*; import javax.media.control.*; public class ControlQueryPApplet extends Applet implements ControllerListener {

 /***************************************************************************
  * Object to play the media. Only attribute that the Applet really needs.
  **************************************************************************/
 protected Player player;
 /***************************************************************************
  * The name of the media to be played.
  **************************************************************************/
 protected String nameOfMedia2Play;
 /***************************************************************************
  * Name of the Property field within the applet tage indicating the name of
  * the media to play.
  **************************************************************************/
 private static final String MEDIA_NAME_PROPERTY = "media2Play";
 /***************************************************************************
  * Object describing the location of the media to be played.
  **************************************************************************/
 protected MediaLocator locator;
 protected SystemTimeBase timer;
 /***************************************************************************
  * Initialise the applet by attempting to create and start a Player object
  * capable of playing the media specified in the applet tag.
  **************************************************************************/
 public void init() {
   setLayout(new BorderLayout());
   setBackground(Color.lightGray);
   try {
     nameOfMedia2Play = (new URL(getDocumentBase(),
         getParameter(MEDIA_NAME_PROPERTY))).toExternalForm();
     locator = new MediaLocator(nameOfMedia2Play);
     Manager.setHint(Manager.PLUGIN_PLAYER, new Boolean(true));
     player = Manager.createPlayer(locator);
     player.addControllerListener(this);
     timer = new SystemTimeBase();
     player.start();
   } catch (Exception e) {
     throw new Error("Couldn"t initialise BBPApplet: " + e.getMessage());
   }
 }
 /***************************************************************************
  * Respond to ControllerEvents from the Player that was created. For the
  * bare bones player the only event of import is the RealizeCompleteEvent.
  * At that stage the visual component and controller for the Player can
  * finally be obtained and thus displayed.
  **************************************************************************/
 public synchronized void controllerUpdate(ControllerEvent e) {
   if (e instanceof RealizeCompleteEvent) {
     Control[] allControls = player.getControls();
     System.out.println("" + allControls.length
         + " controls for a Player @ REALIZED:");
     for (int i = 0; i < allControls.length; i++)
       System.out.println("" + (i + 1) + ": " + allControls[i]);
     add(player.getVisualComponent(), "North");
     add(player.getControlPanelComponent(), "South");
     validate();
   } else if (e instanceof StartEvent) {
     Control[] allControls = player.getControls();
     System.out.println("" + allControls.length
         + " controls for a Player @ START:");
     Panel panel = new Panel();
     for (int i = 0; i < allControls.length; i++) {
       System.out.println("" + (i + 1) + ": " + allControls[i]);
       Component cont = allControls[i].getControlComponent();
       if (cont != null) {
         System.out.println("Has a graphical component");
         panel.add(cont);
       }
     }
     panel.validate();
     add(panel, "Center");
     validate();
     FrameGrabbingControl frameControl = (FrameGrabbingControl) player
         .getControl("javax.media.control.FrameGrabbingControl");
     if (frameControl == null)
       System.out.println("Unable to obtain FrameRateControl");
     else {
       System.out.println("Have Frame Rate control");
       panel.add(frameControl.getControlComponent());
       panel.validate();
     }
   }
 }

}

      </source>   



Query the manager class about the configuration and support of JMF

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

/*******************************************************************************

* ManagerQuery - Query the manager class about the configuration and support of
* the installed JMF version. ManagerQuery is a text-based application that
* provides a report on the support of the JMF for Players, Processors and
* DataSinks.
* 
* Without any command-line arguments ManagerQuery prints a complete (LONG) list
* of Player, Processor, and DataSource classes that support the various
* formats, protocols, and content types.
* 
* Alternatively it is possible to provide command-line arguments specifying the
* format or protocol for which support is to be checked. The means of calling
* is as follows: java ManagerQuery [ [-h|-p|-d] support1 support2 ... supportN]
* The -h flag specifies handlers (Players) only. The -p flag specifies
* Processors only. The -d flag specifies DataSources only. Leaving off the flag
* defaults behaviour to checking for Players only.
* 
* For instance: java ManagerQuery -h mp3 ulaw would list the classes capable of
* Playing the MP3 (MPEG, Layer 3) and U-Law formats (codecs).
* 
* ManagerQuery always prints the version of JMF, caching directory, and hints
* prior to any other output.
* 
* @author Spike Barlow
******************************************************************************/

import javax.media.*; import javax.media.protocol.*; import javax.media.format.*; import java.util.*; public class ManagerQuery {

 ///////////////////////////////////////////////////
 // Constants to facilitate selection of the
 // approprite get*List() method.
 ///////////////////////////////////////////////////
 public static final int HANDLERS = 1;
 public static final int PROCESSORS = 2;
 public static final int DATASOURCES = 3;
 ///////////////////////////////////////////////////////
 // Array containing all the content types that JMF2.1.1
 // supports. This is used when the user provides no
 // command-line arguments in order to generate a
 // complete list of support for all the content types.
 /////////////////////////////////////////////////////////
 private static final String[] CONTENTS = {
     ContentDescriptor.CONTENT_UNKNOWN, ContentDescriptor.MIXED,
     ContentDescriptor.RAW, ContentDescriptor.RAW_RTP,
     FileTypeDescriptor.AIFF, FileTypeDescriptor.BASIC_AUDIO,
     FileTypeDescriptor.GSM, FileTypeDescriptor.MIDI,
     FileTypeDescriptor.MPEG, FileTypeDescriptor.MPEG_AUDIO,
     FileTypeDescriptor.MSVIDEO, FileTypeDescriptor.QUICKTIME,
     FileTypeDescriptor.RMF, FileTypeDescriptor.VIVO,
     FileTypeDescriptor.WAVE, VideoFormat.CINEPAK, VideoFormat.H261,
     VideoFormat.H263, VideoFormat.H261_RTP, VideoFormat.H263_RTP,
     VideoFormat.INDEO32, VideoFormat.INDEO41, VideoFormat.INDEO50,
     VideoFormat.IRGB, VideoFormat.JPEG, VideoFormat.JPEG_RTP,
     VideoFormat.MJPEGA, VideoFormat.MJPEGB, VideoFormat.MJPG,
     VideoFormat.MPEG_RTP, VideoFormat.RGB, VideoFormat.RLE,
     VideoFormat.SMC, VideoFormat.YUV, AudioFormat.ALAW,
     AudioFormat.DOLBYAC3, AudioFormat.DVI, AudioFormat.DVI_RTP,
     AudioFormat.G723, AudioFormat.G723_RTP, AudioFormat.G728,
     AudioFormat.G728_RTP, AudioFormat.G729, AudioFormat.G729_RTP,
     AudioFormat.G729A, AudioFormat.G729A_RTP, AudioFormat.GSM,
     AudioFormat.GSM_MS, AudioFormat.GSM_RTP, AudioFormat.IMA4,
     AudioFormat.IMA4_MS, AudioFormat.LINEAR, AudioFormat.MAC3,
     AudioFormat.MAC6, AudioFormat.MPEG, AudioFormat.MPEG_RTP,
     AudioFormat.MPEGLAYER3, AudioFormat.MSADPCM, AudioFormat.MSNAUDIO,
     AudioFormat.MSRT24, AudioFormat.TRUESPEECH, AudioFormat.ULAW,
     AudioFormat.ULAW_RTP, AudioFormat.VOXWAREAC10,
     AudioFormat.VOXWAREAC16, AudioFormat.VOXWAREAC20,
     AudioFormat.VOXWAREAC8, AudioFormat.VOXWAREMETASOUND,
     AudioFormat.VOXWAREMETAVOICE, AudioFormat.VOXWARERT29H,
     AudioFormat.VOXWARETQ40, AudioFormat.VOXWARETQ60,
     AudioFormat.VOXWAREVR12, AudioFormat.VOXWAREVR18 };
 ////////////////////////////////////
 // The protocols that JMF supports.
 ///////////////////////////////////
 private static final String[] PROTOCOLS = { "ftp", "file", "rtp", "http" };
 /***************************************************************************
  * Return a String being a list of all hints settings.
  **************************************************************************/
 public static String getHints() {
   return "\tSecurity: " + Manager.getHint(Manager.MAX_SECURITY)
       + "\n\tCaching: " + Manager.getHint(Manager.CACHING)
       + "\n\tLightweight Renderer: "
       + Manager.getHint(Manager.LIGHTWEIGHT_RENDERER)
       + "\n\tPlug-in Player: "
       + Manager.getHint(Manager.PLUGIN_PLAYER);
 }
 /***************************************************************************
  * Produce a list of all classes that support the content types or protocols
  * passed to the method. The list is returned as a formatted String, while
  * the 2nd parameter (which) specifies whether it is Player (Handler),
  * Processor, or DataSource classes.
  **************************************************************************/
 public static String getHandlersOrProcessors(String[] contents, int which) {
   String str = "";
   Vector classes;
   int NUM_PER_LINE = 2;
   String LEADING = "\t    ";
   String SEPARATOR = "  ";
   if (contents == null)
     return null;
   /////////////////////////////////////////////////////////////////////
   // Generate a separate list for each content-type/protocol specified.
   /////////////////////////////////////////////////////////////////////
   for (int i = 0; i < contents.length; i++) {
     str = str + "\t" + contents[i] + ":\n";
     if (which == HANDLERS)
       classes = Manager.getHandlerClassList(contents[i]);
     else if (which == PROCESSORS)
       classes = Manager.getProcessorClassList(contents[i]);
     else
       classes = Manager.getDataSourceList(contents[i]);
     if (classes == null)
       str = str + "\t    <None>\n";
     else
       str = str + formatVectorStrings(classes, LEADING, 2, SEPARATOR);
   }
   return str;
 }
 /***************************************************************************
  * Get a list of all Handler (Player) classes that support each of the
  * formats (content types).
  **************************************************************************/
 public static String getHandlers() {
   return getHandlersOrProcessors(CONTENTS, HANDLERS);
 }
 /***************************************************************************
  * Get a list of all Processor classes that support each of the formats
  * (content types).
  **************************************************************************/
 public static String getProcessors() {
   return getHandlersOrProcessors(CONTENTS, PROCESSORS);
 }
 /***************************************************************************
  * Get a list of all DataSources classes that support each of the protocols.
  **************************************************************************/
 public static String getDataSources() {
   return getHandlersOrProcessors(PROTOCOLS, DATASOURCES);
 }
 /***************************************************************************
  * Format the Vector of Strings returned by the get*List() methods into a
  * single String. A simple formatting method.
  **************************************************************************/
 public static String formatVectorStrings(Vector vec, String leading,
     int count, String separator) {
   String str = leading;
   for (int i = 0; i < vec.size(); i++) {
     str = str + (String) vec.elementAt(i);
     if ((i + 1) == vec.size())
       str = str + "\n";
     else if ((i + 1) % count == 0)
       str = str + "\n" + leading;
     else
       str = str + separator;
   }
   return str;
 }
 /***************************************************************************
  * Produce a list showing total support (i.e., Player, Processors, and
  * DataSinks) for all content types and protocols.
  **************************************************************************/
 public static void printTotalList() {
   System.out.println("\nPlayer Handler Classes:");
   System.out.println(getHandlers());
   System.out.println("\nProcessor Class List:");
   System.out.println(getProcessors());
   System.out.println("\nDataSink Class List: ");
   System.out.println(getDataSources());
 }
 /***************************************************************************
  * Main method. Produce a version and hints report. Then if no command line
  * arguments produce a total class list report. Otherwise process the
  * command line arguments and produce a report on their basis only.
  **************************************************************************/
 public static void main(String args[]) {
   System.out.println("JMF: " + Manager.getVersion());
   String cacheArea = Manager.getCacheDirectory();
   if (cacheArea == null)
     System.out.println("No cache directory specified.");
   else
     System.out.println("Cache Directory: " + cacheArea);
   System.out.println("Hints:");
   System.out.println(getHints());
   // No command-line arguments. Make a toral report.
   if (args == null || args.length == 0)
     printTotalList();
   else {
     // Command-line. Process flags and then support to be
     // queried upon in order to generate appropriate report.
     String header = "";
     int whichCategory = 0;
     String[] interested;
     int i;
     int start;
     if (args[0].equalsIgnoreCase("-h")) {
       header = "\nPlayer Handler Classes: ";
       whichCategory = HANDLERS;
     } else if (args[0].equalsIgnoreCase("-p")) {
       header = "\nProcessor Class List:";
       whichCategory = PROCESSORS;
     } else if (args[0].equalsIgnoreCase("-d")) {
       header = "\nDataSink Class List: ";
       whichCategory = DATASOURCES;
     }
     if (whichCategory == 0) {
       whichCategory = HANDLERS;
       header = "\nPlayer Handler Classes: ";
       interested = new String[args.length];
       start = 0;
     } else {
       interested = new String[args.length - 1];
       start = 1;
     }
     for (i = start; i < args.length; i++)
       interested[i - start] = args[i];
     System.out.println(header);
     System.out.println(getHandlersOrProcessors(interested,
         whichCategory));
   }
 }

}

      </source>   



Show the Location2Location class in action

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

import javax.media.*; import javax.media.protocol.*; import javax.media.format.*; /*******************************************************************************

* Simple example to show the Location2Location class in action. The
* Location2Location class transfer media from one location to another
* performing any requested tanscoding (format changes) at the same time.
* 
* The class is used twice. Once to transform a short wave audio file of an
* electric guitar (guitar.wav) into MP3 format. The second example converts of
* Quicktime version of the example video from chapter 7, encoded with the Indeo
* 5.o codec and GSM audio into an AVI version with Cinepak codec for the video
* and linear encoding for the audio.
******************************************************************************/

public class StaticTranscode {

 public static void main(String[] args) {
   String src;
   String dest;
   Format[] formats;
   ContentDescriptor container;
   int waited;
   Location2Location dupe;
   /////////////////////////////////////////////////////////////////
   // Transcode a wave audio file into an MP3 file, transferring it
   // to a new location (dest) at the same time.
   ////////////////////////////////////////////////////////////////
   src = "file://d:\\jmf\\book\\media\\guitar.wav";
   dest = "file://d:\\jmf\\book\\media\\guitar.mp3";
   formats = new Format[1];
   formats[0] = new AudioFormat(AudioFormat.MPEGLAYER3);
   container = new FileTypeDescriptor(FileTypeDescriptor.MPEG_AUDIO);
   dupe = new Location2Location(src, dest, formats, container);
   System.out.println("After creation, state = " + dupe.getStateName());
   waited = dupe.transfer(10000);
   System.out.println("Waited " + waited + " milliseconds. State is now "
       + dupe.getStateName());
   ///////////////////////////////////////////////////////////////////
   // Transcode a Quicktime version of a movie into an AVI version.
   // The video codec is altered from Indeo5.0 to Cinepak,the audio
   // track is transcoded from GSM to linear, and is result is saved
   // as a file "qaz.avi".
   //////////////////////////////////////////////////////////////////
   src = "file://d:\\jmf\\book\\media\\videoexample\\iv50_320x240.mov";
   dest = "file://d:\\jmf\\book\\media\\qaz.avi";
   formats = new Format[2];
   formats[0] = new VideoFormat(VideoFormat.CINEPAK);
   formats[1] = new AudioFormat(AudioFormat.LINEAR);
   container = new FileTypeDescriptor(FileTypeDescriptor.MSVIDEO);
   dupe = new Location2Location(src, dest, formats, container, 5.0f);
   System.out.println("After creation, state = " + dupe.getStateName());
   waited = dupe.transfer(Location2Location.INDEFINITE);
   int state = dupe.getState();
   System.out.println("Waited " + (waited / 1000)
       + " seconds. State is now " + dupe.getStateName()
       + ", rate was " + dupe.getRate());
   System.exit(0);
 }

}

      </source>   



Statistics about the tracks that compose a media object

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

import javax.media.*; import javax.media.control.*; import javax.media.format.*; /*******************************************************************************

* A Class to determine statistics about the tracks that compose a media object.
* Given the name (URL/location) of media a Processor is constructed and brought
* to the Configured state. At that stage its TrackControls are obtained as a
* means of discovering the Formats of the individual tracks.
* 
* Because reaching Configured can take time, the MediaStatistics object keeps
* track of its own state and provides methods for determining that state. Only
* when it reaches the KNOWN state can statistics be obtained. Similarly there
* are 2 constructors: one creating a Processor and starting it toward
* Configured but returning immediately. The other is a blocking constructor, it
* won"t return until the Processor reaches Configured or the specified time-out
* expires. This has the advantage that the object can be used immediately
* (rather than polling it to determine when it enters the KNOWN state.
* 
* The chief information gathering method is getReport() which returns a String
* reporting on the Format of all tracks of the media. Alternatively the Format
* of individual tracks can also be ascertained.
* 
* @author Spike Barlow
******************************************************************************/

public class MediaStatistics implements ControllerListener {

 /** State: Yet to create the Processor. */
 public static final int NOT_CREATED = 0;
 /** State: Unable to create the Processor. */
 public static final int FAILED = -1;
 /** State: Processor is Configuring. */
 public static final int CONFIGURING = 1;
 /** State: Details of media are Known. */
 public static final int KNOWN = 2;
 /** Number of tracks is Unknown. */
 public static final int UNKNOWN = Integer.MIN_VALUE;
 /**
  * Period in milliseconds to sleep for before rechecking if reached KNOWN
  * state.
  */
 protected static final int WAIT_INTERVAL = 20;
 /** Number of tracks possessed by the media. */
 protected int numTracks = UNKNOWN;
 /** Formats of the individual tracks. */
 protected Format[] trackFormats;
 /** Processor needed to ascertain track information. */
 protected Processor processor;
 /**
  * State that the object is currently in. A reflection of the state the
  * Processor is in.
  */
 protected int state = NOT_CREATED;
 /** The name of the media on which stats are being compiled. */
 protected String nameOfMedia;
 /***************************************************************************
  * Construct a MediaStatistics object for the media with the passed name.
  * This is a blocking constructor. It returns only when it is possible to
  * obtain the track statistics or when the specified time-out period (in
  * milliseconds) has transpired.
  **************************************************************************/
 MediaStatistics(String mediaName, int timeOutInMilliseconds) {
   nameOfMedia = mediaName;
   // Construct the Processor
   try {
     MediaLocator locator = new MediaLocator(mediaName);
     processor = Manager.createProcessor(locator);
   }
   // Any exception is a failure.
   catch (Exception e) {
     state = FAILED;
     return;
   }
   // Listen to and start configuration of the Processor.
   processor.addControllerListener(this);
   state = CONFIGURING;
   processor.configure();
   //////////////////////////////////////////////////////////
   // Wait till the Processor reaches configured (the object
   // reaches KNOWN) or the specified time-out interval has
   // transpired, by looping, sleeping,and rechecking.
   //////////////////////////////////////////////////////////
   if (timeOutInMilliseconds > 0) {
     int waitTime = 0;
     while (waitTime < timeOutInMilliseconds && !isKnown()) {
       try {
         Thread.sleep(WAIT_INTERVAL);
       } catch (InterruptedException ie) {
       }
       waitTime += WAIT_INTERVAL;
     }
   }
 }
 /***************************************************************************
  * Construct a MediaStatistics object for the media with the passed name.
  * This is not a blocking constructor: it returns immediately. Thus calling
  * getReport() immediately may result in "Still parsing media" report. The
  * isKnown() method should be used to check for this condition.
  **************************************************************************/
 MediaStatistics(String mediaName) {
   this(mediaName, -1);
 }
 /***************************************************************************
  * Respond to events from the Porcessor. In particular the ConfigureComplete
  * event is the only one of interest. In this case obtain the TrackControls
  * anduse these to obtain the Formats of each track. Also modify the state
  * and close down the Processor (free up its resources).
  **************************************************************************/
 public synchronized void controllerUpdate(ControllerEvent e) {
   if (e instanceof ConfigureCompleteEvent) {
     TrackControl[] controls = processor.getTrackControls();
     // As long as there are TrackControls, get each track"s format.
     if (controls.length != 0) {
       numTracks = controls.length;
       trackFormats = new Format[controls.length];
       for (int i = 0; i < controls.length; i++) {
         trackFormats[i] = controls[i].getFormat();
       }
       state = KNOWN;
     } else {
       state = FAILED;
     }
     // Close down the Processor.
     processor.removeControllerListener(this);
     processor.close();
     processor = null;
   }
 }
 /***************************************************************************
  * Determine what state the object is in. Returns one of the class constants
  * such as KNOWN, FAILED or CONFIGURING.
  **************************************************************************/
 public int getState() {
   return state;
 }
 /***************************************************************************
  * Determine the number of tracks possessed by the media. If that is
  * unknown, either due to the processor creation failing or because the
  * processor is not yet Configured then the class constant UNKNOWN is
  * returned.
  **************************************************************************/
 public int getNumTracks() {
   return numTracks;
 }
 /***************************************************************************
  * Obtain the Format for the specified track number. If the track doesn"t
  * exist, or it has yet to be determined how many tracks the media
  * possesses, null is returned.
  **************************************************************************/
 public Format getTrackFormat(int track) {
   if (track < 0 || track >= numTracks)
     return null;
   return trackFormats[track];
 }
 /***************************************************************************
  * Is the object in the KNOWN state? The KNOWN state reflects the fact that
  * information is known about the number and Format of the tracks. The
  * method can be used to ascertain whether a report is available
  * (meaningful) or not.
  **************************************************************************/
 public boolean isKnown() {
   return state == KNOWN;
 }
 /***************************************************************************
  * Returns true if the specified track number is an audio track. If the
  * track doesn"t exist, the number of tracks is yet unknown, or it isn"t
  * audio then false is returned.
  **************************************************************************/
 public boolean isAudioTrack(int track) {
   if (track < 0 || track >= numTracks)
     return false;
   return trackFormats[track] instanceof AudioFormat;
 }
 /***************************************************************************
  * Returns true if the specified track number is a video track. If the track
  * doesn"t exist, the number of tracks is yet unknown, or it isn"t video
  * then false is returned.
  **************************************************************************/
 public boolean isVideoTrack(int track) {
   if (track < 0 || track >= numTracks)
     return false;
   return trackFormats[track] instanceof VideoFormat;
 }
 /***************************************************************************
  * Returns a report, as a String, detailing thenumber and format of the
  * individual tracks that compose the media that this object obtained
  * statistics for. If the object is not in the KNOWN state then the report
  * is a simple String, indicating this.
  **************************************************************************/
 public String getReport() {
   String mess;
   if (state == FAILED)
     return "Unable to Handle Media " + nameOfMedia;
   else if (state == CONFIGURING)
     return "Still Parsing Media " + nameOfMedia;
   else if (state == KNOWN) {
     if (numTracks == 1)
       mess = nameOfMedia + ": 1 Track\n";
     else
       mess = nameOfMedia + ": " + numTracks + " Tracks\n";
     for (int i = 0; i < numTracks; i++) {
       if (trackFormats[i] instanceof AudioFormat)
         mess += "\t" + (i + 1) + " [Audio]: ";
       else if (trackFormats[i] instanceof VideoFormat)
         mess += "\t" + (i + 1) + " [Video]: ";
       else
         mess += "\t" + (i + 1) + " [Unknown]: ";
       mess += trackFormats[i].toString() + "\n";
     }
     return mess;
   } else
     return "Unknown State in Processing " + nameOfMedia;
 }
 /***************************************************************************
  * Simple main method to exercise the class. Takes command line arguments
  * and constructs MediaStatistics objects for them, before generating a
  * report on them.
  **************************************************************************/
 public static void main(String[] args) {
   MediaStatistics[] stats = new MediaStatistics[args.length];
   for (int i = 0; i < args.length; i++) {
     stats[i] = new MediaStatistics(args[i], 200);
     System.out.println(stats[i].getReport());
     stats[i] = null;
   }
   System.exit(0);
 }

}


      </source>   



Transfer media from one location to another carrying out the specified

<source lang="java"> /* Java Media APIs: Cross-Platform Imaging, Media and Visualization Alejandro Terrazas Sams, Published November 2002, ISBN 0672320940

  • /

import javax.media.*; import javax.media.datasink.*; import javax.media.protocol.*; /*******************************************************************************

* Transfer media from one location to another carrying out the specified
* transcoding (track formats and content type) at the same time.
* <p>
* Users specify a source and destination location, the Formats (to be realised)
* of the individual tracks, and a ContentDescriptor (content type) for output.
* <p>
* A Processor is created to perform and transcoding and its output DataSource
* is employed to construct a DataSink in order to complete the transfer.
* <p>
* The most important method of the class is transfer() as this opens and starts
* the DataSink. The constructor builds both the Processor (which is starts) and
* the DataSink.
* <p>
* The object keeps track of its own state, which can be queried with the
* getState() method. Defined constants are FAILED, TRANSLATING, TRANSFERRING,
* and FINISHED. The process is asychronous: transcoding largish movies can take
* a long time. The calling code should make allowances for that.
******************************************************************************/

public class Location2Location implements ControllerListener {

 /** Output of the Processor: the transcoded media. */
 protected DataSource source;
 /** Sink used to "write" out the transcoded media. */
 protected DataSink sink;
 /** Processor used to transcode the media. */
 protected Processor processor;
 /**
  * Model used in constructing the processor, and which specifies track
  * formats and output content type
  */
 protected ProcessorModel model;
 /** State the object is in. */
 protected int state;
 /** Location that the media will be "written" to. */
 protected MediaLocator sinkLocation;
 /** The rate of translation. */
 protected float translationRate;
 /** Process has failed. */
 public static final int FAILED = 0;
 /**
  * Processor is working but not finished. DataSink is yet to start.
  */
 public static final int TRANSLATING = 1;
 /** DataSink has started but not finished. */
 public static final int TRANSFERRING = 3;
 /** Transcoding and transfer is complete. */
 public static final int FINISHED = 4;
 /** String names for each of the states. More user friendly */
 private static final String[] STATE_NAMES = { "Failed", "Translating",
     "<UNUSED>", "Transferring", "Finished" };
 /**
  * Period (in milliseconds) between checks for the blocking transfer method.
  */
 public static final int WAIT_PERIOD = 50;
 /**
  * Wait an "indefinite" period of time for the transfer method to complete.
  * i.e., pass to transfer() if the user wishes to block till the process is
  * complete, regardless of how long it will take.
  */
 public static final int INDEFINITE = Integer.MAX_VALUE;
 /***************************************************************************
  * Construct a transfer/transcode object that transfers media from
  * sourceLocation to destinationLocation, transcoding the tracks as
  * specified by the outputFormats. The output media is to have a content
  * type of outputContainer and the process should (if possible) run at the
  * passed rate.
  **************************************************************************/
 Location2Location(MediaLocator sourceLocation,
     MediaLocator destinationLocation, Format[] outputFormats,
     ContentDescriptor outputContainer, double rate) {
   //////////////////////////////////////////////
   // Construct the processor for the transcoding
   //////////////////////////////////////////////
   state = TRANSLATING;
   sinkLocation = destinationLocation;
   try {
     if (sourceLocation == null)
       model = new ProcessorModel(outputFormats, outputContainer);
     else
       model = new ProcessorModel(sourceLocation, outputFormats,
           outputContainer);
     processor = Manager.createRealizedProcessor(model);
   } catch (Exception e) {
     state = FAILED;
     return;
   }
   translationRate = processor.setRate((float) Math.abs(rate));
   processor.addControllerListener(this);
   ////////////////////////////////////////////////////////////
   // Construct the DataSink and employ an anonymous class as
   // a DataSink listener in order that the end of transfer
   // (completion of task) can be detected.
   ///////////////////////////////////////////////////////////
   source = processor.getDataOutput();
   try {
     sink = Manager.createDataSink(source, sinkLocation);
   } catch (Exception sinkException) {
     state = FAILED;
     processor.removeControllerListener(this);
     processor.close();
     processor = null;
     return;
   }
   sink.addDataSinkListener(new DataSinkListener() {
     public void dataSinkUpdate(DataSinkEvent e) {
       if (e instanceof EndOfStreamEvent) {
         sink.close();
         source.disconnect();
         if (state != FAILED)
           state = FINISHED;
       } else if (e instanceof DataSinkErrorEvent) {
         if (sink != null)
           sink.close();
         if (source != null)
           source.disconnect();
         state = FAILED;
       }
     }
   });
   // Start the transcoding
   processor.start();
 }
 /***************************************************************************
  * Alternate constructor: source and destination specified as Strings, and
  * no rate provided (hence rate of 1.0)
  **************************************************************************/
 Location2Location(String sourceName, String destinationName,
     Format[] outputFormats, ContentDescriptor outputContainer) {
   this(new MediaLocator(sourceName), new MediaLocator(destinationName),
       outputFormats, outputContainer);
 }
 /***************************************************************************
  * Alternate constructor: No rate specified therefore rate of 1.0
  **************************************************************************/
 Location2Location(MediaLocator sourceLocation,
     MediaLocator destinationLocation, Format[] outputFormats,
     ContentDescriptor outputContainer) {
   this(sourceLocation, destinationLocation, outputFormats,
       outputContainer, 1.0f);
 }
 /***************************************************************************
  * Alternate constructor: source and destination specified as Strings.
  **************************************************************************/
 Location2Location(String sourceName, String destinationName,
     Format[] outputFormats, ContentDescriptor outputContainer,
     double rate) {
   this(new MediaLocator(sourceName), new MediaLocator(destinationName),
       outputFormats, outputContainer, rate);
 }
 /***************************************************************************
  * Respond to events from the Processor performing the transcoding. If its
  * task is completed (end of media) close it down. If there is an error
  * close it down and mark the process as FAILED.
  **************************************************************************/
 public synchronized void controllerUpdate(ControllerEvent e) {
   if (state == FAILED)
     return;
   // Transcoding complete.
   if (e instanceof StopEvent) {
     processor.removeControllerListener(this);
     processor.close();
     if (state == TRANSLATING)
       state = TRANSFERRING;
   }
   // Transcoding failed.
   else if (e instanceof ControllerErrorEvent) {
     processor.removeControllerListener(this);
     processor.close();
     state = FAILED;
   }
 }
 /***************************************************************************
  * Initiate the transfer through a DataSink to the destination and wait
  * (block) until the process is complete (or failed) or the supplied number
  * of milliseconds timeout has passed. The method returns the total amount
  * of time it blocked.
  **************************************************************************/
 public int transfer(int timeOut) {
   // Can"t initiate: Processor already failed to transcode
   ////////////////////////////////////////////////////////
   if (state == FAILED)
     return -1;
   // Start the DataSink
   //////////////////////
   try {
     sink.open();
     sink.start();
   } catch (Exception e) {
     state = FAILED;
     return -1;
   }
   if (state == TRANSLATING)
     state = TRANSFERRING;
   if (timeOut <= 0)
     return timeOut;
   // Wait till the process is complete, failed, or the
   // prescribed time has passed.
   /////////////////////////////////////////////////////
   int waited = 0;
   while (state != FAILED && state != FINISHED && waited < timeOut) {
     try {
       Thread.sleep(WAIT_PERIOD);
     } catch (InterruptedException ie) {
     }
     waited += WAIT_PERIOD;
   }
   return waited;
 }
 /***************************************************************************
  * Initiate the transfer through a DataSink to the destination but return
  * immediately to the caller.
  **************************************************************************/
 public void transfer() {
   transfer(-1);
 }
 /***************************************************************************
  * Determine the object"s current state. Returns one of the class constants.
  **************************************************************************/
 public int getState() {
   return state;
 }
 /***************************************************************************
  * Returns the object"s state as a String. A more user friendly version of
  * getState().
  **************************************************************************/
 public String getStateName() {
   return STATE_NAMES[state];
 }
 /***************************************************************************
  * Obtain the rate being used for the process. This is often 1, despite what
  * the user may have supplied as Clocks (hence Processors) don"t have to
  * support any other rate than 1 (and will default to that).
  **************************************************************************/
 public float getRate() {
   return translationRate;
 }
 /***************************************************************************
  * Set the time at which media processing will stop. Specification is in
  * media time. This means only the first "when" amount of the media will be
  * transferred.
  **************************************************************************/
 public void setStopTime(Time when) {
   if (processor != null)
     processor.setStopTime(when);
 }
 /***************************************************************************
  * Stop the processing and hence transfer. This gives user control over the
  * duration of a transfer. It could be started with the transfer() call and
  * after a specified period stop() could be called.
  **************************************************************************/
 public void stop() {
   if (processor != null)
     processor.stop();
 }

}

</source>