Java/2D Graphics GUI/Media
Содержание
- 1 A Bare Bones Player: play the media object
- 2 Capture audio or video through devices connected to the PC
- 3 Choose the media they wish to play
- 4 Do Audio Capture
- 5 Java Media: Find Components
- 6 List all capture devices currently known to the JMF
- 7 Play the media object
- 8 Play the media object 3
- 9 Query the manager class about the configuration and support of JMF
- 10 Show the Location2Location class in action
- 11 Statistics about the tracks that compose a media object
- 12 Transfer media from one location to another carrying out the specified
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>