Mega Code Archive

 
Categories / Java / 2D Graphics GUI
 

Statistics about the tracks that compose a media object

/* 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);   } }