Java/2D Graphics GUI/JMF
Содержание
- 1 A motion detection algoritm for use with the Java Media Framework API (JMF).
- 2 javax.media
- 3 Media player
- 4 Query the installed version of the JMF
- 5 Renderer for RGB images using AWT Image using Java Media API
- 6 Sample program to demonstrate FramePositioningControl.
- 7 Select a media file from tjelocal file system and gain statistics
A motion detection algoritm for use with the Java Media Framework API (JMF).
<source lang="java">
/**
* A motion detection algoritm for use with the Java Media Framework API (JMF). * The main idea of the algorithm is to compare the pixelcolours of two successive frames in an incoming videostream. * To prevent noise to be mistaken for motion each frame is divided into many small squares for which only the mean colour is used for compairson. * @version 2002-09-26 * @author Mattias Hedlund, mathed-8. * @author Fredrik Jonsson, frejon-9. * @author David Åberg, davabe-9 all students at Luleå University of Technology. */
import javax.media.*; import javax.media.format.*; import java.awt.*; import java.io.IOException; public class MotionDetectionEffect implements Effect {
/** * The initial square side. */ private final static int INITIAL_SQUARE_SIZE = 5; public final static Format[] supportedFormat = new Format[] { // new RGBFormat(null, // Format.NOT_SPECIFIED, // Format.byteArray, // Format.NOT_SPECIFIED, // 24, // 3, 2, 1, // 3, Format.NOT_SPECIFIED, // Format.TRUE, // Format.NOT_SPECIFIED) // }; private Format inputFormat; private Format outputFormat; private Format[] inputFormats; private Format[] outputFormats; private int[] bwPixels; private byte[] bwData; /** * Visual mode is set. */ private boolean visualize = true; /** * Server mode is set. */ private boolean serverActive = true; /** * Update requested is set. */ private boolean updateRequested; private int avg_ref_intensity; private int avg_img_intensity; /** * The RGBFormat of the inbuffer. */ private RGBFormat vfIn = null; /** * Four different thresholds. Set initial values here. */ private int[] threshs = { 20, 30, 40, 50 }; private int det_thresh = threshs[1]; /** * The corresponding colours to the four different thresholds. */ private int[] colors = { 0x00FF0000, 0x00FF9900, 0x00FFFF00, 0x00FFFFFF }; /** * The mean values of all squares in an image. */ private int[] newImageSquares = null; /** * The mean values of all squares in an image. */ private int[] oldImageSquares = null; /** * The difference of all the mean values of all squares in an image. */ private int[] changedSquares = null; /** * The number of squares fitted in the image. */ private int numberOfSquaresWide; /** * The number of squares fitted in the image. */ private int numberOfSquaresHigh; /** * The number of squares fitted in the image. */ private int numberOfSquares; /** * The square side, in pixels. */ private int sqSide = INITIAL_SQUARE_SIZE; /** * The square area, in pixels. */ private int sqArea = 0; /** * The amount of pixels left when all normal sized squares have been removed. */ private int sqWidthLeftover = 0; /** * The amount of pixels left when all normal sized squares have been removed. */ private int sqHeightLeftover = 0; /** * Optional, less processing is needed if some pixels are left out during some of the calculations. */ private int pixelSpace = 0; /** * Image property. */ private int imageWidth = 0; /** * Image property. */ private int imageHeight = 0; /** * Image property. */ private int imageArea = 0; /** * Initialize the effect plugin. */ public MotionDetectionEffect() { inputFormats = new Format[] { new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, 24, 3, 2, 1, 3, Format.NOT_SPECIFIED, Format.TRUE, Format.NOT_SPECIFIED) }; outputFormats = new Format[] { new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, 24, 3, 2, 1, 3, Format.NOT_SPECIFIED, Format.TRUE, Format.NOT_SPECIFIED) }; } /** * Get the inputformats that we support. * @return All supported Formats. */ public Format[] getSupportedInputFormats() { return inputFormats; } /** * Get the outputformats that we support. * @param input the current inputformat. * @return All supported Formats. */ public Format[] getSupportedOutputFormats(Format input) { if (input == null) { return outputFormats; } if (matches(input, inputFormats) != null) { return new Format[] { outputFormats[0].intersects(input) }; } else { return new Format[0]; } } /** * Set the input format. * */ public Format setInputFormat(Format input) { inputFormat = input; return input; } /** * Set our output format. * */ public Format setOutputFormat(Format output) { if (output == null || matches(output, outputFormats) == null) return null; RGBFormat incoming = (RGBFormat) output; Dimension size = incoming.getSize(); int maxDataLength = incoming.getMaxDataLength(); int lineStride = incoming.getLineStride(); float frameRate = incoming.getFrameRate(); int flipped = incoming.getFlipped(); int endian = incoming.getEndian(); if (size == null) return null; if (maxDataLength < size.width * size.height * 3) maxDataLength = size.width * size.height * 3; if (lineStride < size.width * 3) lineStride = size.width * 3; if (flipped != Format.FALSE) flipped = Format.FALSE; outputFormat = outputFormats[0].intersects(new RGBFormat(size, maxDataLength, null, frameRate, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, lineStride, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED)); return outputFormat; } /** * Process the buffer. This is where motion is analysed and optionally visualized. * */ public synchronized int process(Buffer inBuffer, Buffer outBuffer) { int outputDataLength = ((VideoFormat) outputFormat).getMaxDataLength(); validateByteArraySize(outBuffer, outputDataLength); outBuffer.setLength(outputDataLength); outBuffer.setFormat(outputFormat); outBuffer.setFlags(inBuffer.getFlags()); byte[] inData = (byte[]) inBuffer.getData(); byte[] outData = (byte[]) outBuffer.getData(); int[] sqAvg = null; int[] refsqAvg = null; vfIn = (RGBFormat) inBuffer.getFormat(); Dimension sizeIn = vfIn.getSize(); int pixStrideIn = vfIn.getPixelStride(); int lineStrideIn = vfIn.getLineStride(); imageWidth = (vfIn.getLineStride()) / 3; //Divide by 3 since each pixel has 3 colours. imageHeight = ((vfIn.getMaxDataLength()) / 3) / imageWidth; imageArea = imageWidth * imageHeight; int r, g, b = 0; //Red, green and blue values. if (oldImageSquares == null) { //For the first frame. changeSqSize(INITIAL_SQUARE_SIZE); updateRequested = true; } //Copy all data from the inbuffer to the outbuffer. The purpose is to display the video input on the screen. System.arraycopy(inData, 0, outData, 0, outData.length); // Simplify the image to black and white, image information shrinks to one third of the original amount. Less processing needed. bwPixels = new int[outputDataLength / 3]; for (int ip = 0; ip < outputDataLength; ip += 3) { int bw = 0; r = (int) inData[ip] & 0xFF; g = (int) inData[ip + 1] & 0xFF; b = (int) inData[ip + 2] & 0xFF; bw = (int) ((r + b + g) / (double) 3); bwPixels[ip / 3] = bw; //Now containing a black and white image. } if (updateRequested) { updateRequested = false; updateSquares(); return BUFFER_PROCESSED_OK; } else { updateSquares(); oldNewChange(); int c = 0; for (int i = 0; i < changedSquares.length; i++) { if (changedSquares[i] > det_thresh) { c++; } } if (c > 10 && serverActive) { // try{ System.out.println("Motion detected (motion at " + c + "areas"); // multicast.send("Motion detected"); - Disabled // } catch(IOException e){} } // If chosen, the detected motion is presented on top of the video input, thus covering the edges of the moving object. if (visualize) { for (int i = 1; i <= numberOfSquares; i++) { // For all blobs if ((changedSquares[i - 1] > threshs[0])) { // Critical threshold, if less, then no motion is said to have occured. if (((i % numberOfSquaresWide) != 0) && (numberOfSquares - i) > numberOfSquaresWide) {//Normal square, the other cases is not presented! int begin = ((((i % numberOfSquaresWide) - 1) * sqSide) + ((i / numberOfSquaresWide) * imageWidth * sqSide)) * 3; //Calculate start of square. if (changedSquares[i - 1] > threshs[3]) { //Very strong motion. b = (byte) (colors[3] & 0xFF); g = (byte) ((colors[3] >> 8) & 0xFF); r = (byte) ((colors[3] >> 16) & 0xFF); } else if (changedSquares[i - 1] > threshs[2]) { //Strong motion. b = (byte) (colors[2] & 0xFF); g = (byte) ((colors[2] >> 8) & 0xFF); r = (byte) ((colors[2] >> 16) & 0xFF); } else if (changedSquares[i - 1] > threshs[1]) { //Weak motion. b = (byte) (colors[1] & 0xFF); g = (byte) ((colors[1] >> 8) & 0xFF); r = (byte) ((colors[1] >> 16) & 0xFF); } else { //The Weakest motion detected. b = (byte) (colors[0] & 0xFF); g = (byte) ((colors[0] >> 8) & 0xFF); r = (byte) ((colors[0] >> 16) & 0xFF); } for (int k = begin; k < (begin + (sqSide * imageWidth * 3)); k = k + (imageWidth * 3)) { //Ev <= for (int j = k; j < (k + (sqSide * 3)); j = j + 3) { try { outData[j] = (byte) b; outData[j + 1] = (byte) g; outData[j + 2] = (byte) r; } catch (ArrayIndexOutOfBoundsException e) { System.out.println("Nullpointer: j = " + j + ". Outdata.length = " + outData.length); System.exit(1); } } } } } } } } return BUFFER_PROCESSED_OK; } // Methods for interface PlugIn public String getName() { return "Motion Detection Codec"; } public void open() { } public void close() { } public void reset() { } // Methods for interface javax.media.Controls public Object getControl(String controlType) { System.out.println(controlType); return null; } public Object[] getControls() { return null; } // Utility methods. public Format matches(Format in, Format outs[]) { for (int i = 0; i < outs.length; i++) { if (in.matches(outs[i])) return outs[i]; } return null; } // Credit : example at www.java.sun.ru byte[] validateByteArraySize(Buffer buffer, int newSize) { Object objectArray = buffer.getData(); byte[] typedArray; if (objectArray instanceof byte[]) { // Has correct type and is not null typedArray = (byte[]) objectArray; if (typedArray.length >= newSize) { // Has sufficient capacity return typedArray; } byte[] tempArray = new byte[newSize]; // Reallocate array System.arraycopy(typedArray, 0, tempArray, 0, typedArray.length); typedArray = tempArray; } else { typedArray = new byte[newSize]; } buffer.setData(typedArray); return typedArray; } /** * Sets the current pixelspace, default is zero. * This is mainly for use where limited processing capacity are availible. Some pixels are left out in the calculations. * @param newSpace the space between two successive pixels. */ private void setPixelSpace(int newSpace) { pixelSpace = newSpace; } /** * Changes the size of the square shaped area that divides the detection area into many small parts. * @param newSide the side of the square, in pixels. */ private void changeSqSize(int newSide) { sqSide = newSide; sqArea = newSide * newSide; int wid = (imageWidth / sqSide); //The number of squares wide. int hei = (imageHeight / sqSide); //The number of squares high. sqWidthLeftover = imageWidth % sqSide; sqHeightLeftover = imageHeight % sqSide; if (sqWidthLeftover > 0) { wid++; } if (sqHeightLeftover > 0) { hei++; } numberOfSquaresWide = wid; numberOfSquaresHigh = hei; numberOfSquares = wid * hei; newImageSquares = new int[numberOfSquares]; oldImageSquares = new int[numberOfSquares]; changedSquares = new int[numberOfSquares]; } /** * Calculates the average colour in each square thus indirect eliminate noise. * @param startX the starting position of this square, in pixels, left edge. * @param startY the starting position of this square, in pixels, bottom edge. * @param sqWidth the width of this square, in pixels. * @param sqHeight the height of this square, in pixels. * @return The average greyscale value for this square. */ private int averageInSquare(int startX, int startY, int sqWidth, int sqHeight) { int average = 0; for (int i = 0; i < sqHeight; i = i + 1 + pixelSpace) {// For all pixels for (int j = 0; j < sqWidth; j = j + 1 + pixelSpace) { average += bwPixels[(((startY + i) * imageWidth) + (startX + j))]; //Sum all the pixel values. } } average = average / (sqWidth * sqHeight); //Divide by the number of pixels to get the average value. return average; } /** * Backup the most recent frame examined. For the new frame, calculate the average greyscale value for all squares. */ private void updateSquares() { System.arraycopy(newImageSquares, 0, oldImageSquares, 0, newImageSquares.length); int sqCount = 0; //Keep track of the current square for (int j = 0; j < (imageHeight); j = j + sqSide) { //For all squares for (int i = 0; i < (imageWidth); i = i + sqSide) { if (i <= (imageWidth - sqSide) && j <= (imageHeight - sqSide)) { newImageSquares[sqCount] = averageInSquare(i, j, sqSide, sqSide); //No edge! } else if (i > (imageWidth - sqSide) && j <= (imageHeight - sqSide)) { newImageSquares[sqCount] = averageInSquare(i, j, sqWidthLeftover, sqSide); //Right edge! } else if (i <= (imageWidth - sqSide) && j > (imageHeight - sqSide)) { newImageSquares[sqCount] = averageInSquare(i, j, sqSide, sqHeightLeftover); //Bottom edge! } else if (i > (imageWidth - sqSide) && j > (imageHeight - sqSide)) { newImageSquares[sqCount] = averageInSquare(i, j, sqWidthLeftover, sqHeightLeftover); //Bottom right edge! } sqCount++; } } } /** * Calculate the difference per square between currently stored frames. */ private void oldNewChange() { for (int i = 0; i <= (numberOfSquares - 1); i++) { //For all squares int difference = Math.abs((newImageSquares[i]) - (oldImageSquares[i])); //Compare each square with the corresponding square in the previous frame. changedSquares[i] = difference; //Save the difference. } } public synchronized void updateModel(boolean visualize, boolean serverActive, boolean simplified, int[] threshs, int[] colors, int sqSide, int det_thresh) { this.visualize = visualize; this.serverActive = serverActive; if (sqSide != this.sqSide) changeSqSize(sqSide); if (!simplified) { System.out.println((colors == null) + " " + (this.colors == null)); System.arraycopy(colors, 0, this.colors, 0, colors.length); System.arraycopy(threshs, 0, this.threshs, 0, colors.length); this.det_thresh = det_thresh; System.out.println("New det_threhsh: " + this.det_thresh); } updateRequested = true; } /** *Check if the visualize variable is set. *@returns the current value. */ public boolean isVisual() { return visualize; } /** *Get the current threshold values in a vector. *@returns the current values. */ public int[] getThreshholds() { return threshs; } /** *Check if the server is active. *@returns the current value. */ public boolean isServerActive() { return serverActive; } public int[] getColors() { return colors; } /** *Get the current square side. *@returns the current value. */ public int getSqSide() { return sqSide; }
}
</source>
javax.media
<source lang="java"> //-----------------------------------------------------------------------// // // // T e s t I m a g e 3 // // // // Copyright (C) Herve Bitteur 2000-2007. All rights reserved. // // This software is released under the terms of the GNU General Public // // License. Please contact the author at herve.bitteur@laposte.net // // to report bugs & suggestions. // //-----------------------------------------------------------------------// package omr.jai; import omr.jai.ImageInfo; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.color.ColorSpace; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.awt.image.renderable.ParameterBlock; import javax.media.jai.JAI; import javax.media.jai.PlanarImage; import javax.swing.JFrame; import javax.swing.JPanel; import java.util.Arrays; import javax.media.jai.InterpolationNearest; import javax.media.jai.InterpolationBilinear; public class TestImage3
extends JPanel
{
//RenderedImage image; PlanarImage image; // Affine tranform final float ratio = 4f; AffineTransform scaleXform = AffineTransform.getScaleInstance(ratio, ratio); private static char WHITE = "-"; // And transparent private static char[] charTable = new char[] { "#", // 0 Black "$", // 1 "*", // 2 "0", // 3 "o", // 4 "+", // 5 ".", // 6 WHITE // 7 }; //------------// // TestImage3 // //------------// public TestImage3() { JFrame frame = new JFrame(getClass().getName()); Container pane = frame.getContentPane(); pane.setLayout(new BorderLayout()); pane.add(this); image = decodeImage(new String[] { "#-###############", "-----------------", "#################", "-----------------", "#################", "-----------------", "#################", "-----------------", "#################", "-----------------", "#################", "-----------------", "-----------------", "-----------------", "---####----------", "-------##--------", "---------####----", "-------------#---", "-------------#---", "-----------------", "--#############--", "--#############--", "--#############--", "--#############--", "--#############--", "--#############--", "--#############--", "--#############--", "--#############--", "--#############--", "--#############--", "-----------------", "-----------------", "---####----------", "-------##--------", "---------####----", "-------------#---", "-------------#---", "-----------------", "--#############--", "--#############--", "-----------------", "-----------------" }); // checkImageFormat(); ImageInfo.print(image); // Scaling final float scale = 1f; ParameterBlock pb = new ParameterBlock() .addSource(image) .add(scale) .add(scale) .add(0f) .add(0f) .add(new InterpolationNearest()); image = JAI.create("scale", pb); dumpPixels(0, 0, 5, 7); if (false) { System.out.println("\nBand Selection"); image = JAI.create("bandselect",image,new int[] {0, 1, 2}); ImageInfo.print(image); dumpPixels(0, 0, 5, 7); } frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocation(100, 100); frame.pack(); frame.setSize(100, 250); frame.setVisible(true); } private void dumpPixels (int x0, int y0, int w, int h) { Raster raster = image.getData(); int[] pixel = null; System.out.print("pixels="); for (int y = y0; y < y0+h; y++) { System.out.println(); for (int x = x0; x <= x0+w; x++) { pixel = raster.getPixel(x, y, pixel); System.out.print(" ["); for (int i = 0; i < pixel.length; i++) { System.out.print(String.format("%3x", pixel[i])); } System.out.print("]"); } } System.out.println(); }
//------// // main // //------// public static void main(String... args) { new TestImage3(); } //----------------// // paintComponent // //----------------// public void paintComponent(Graphics g) { // For background super.paintComponent(g); // Meant for visual check if (image != null) { Graphics2D g2 = (Graphics2D) g; g2.drawRenderedImage (image, scaleXform); //g2.drawImage (image, 1, 1, this); } } //-------------// // decodeImage // //-------------// public static PlanarImage decodeImage (String[] rows) { // Create the DataBuffer to hold the pixel samples final int width = rows[0].length(); final int height = rows.length; // Create Raster Raster raster; if (true) { raster = Raster.createPackedRaster (DataBuffer.TYPE_INT, width, height, new int[] {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000},// bandMasks RGBA null); } else { raster = Raster.createInterleavedRaster (DataBuffer.TYPE_BYTE, width, height, 4,// num of bands null); } // Populate the data buffer DataBuffer dataBuffer = raster.getDataBuffer(); int index = 0; for (String row : rows) { for (int x = 0; x < width; x++) { int argb = toARGB(row.charAt(x)); dataBuffer.setElem(index, argb); index++; } } // Dump
// final int size = width * height; // System.out.println("DataBuffer :"); // for (int i = 0; i < size; i++) { // if (i % width == 0) { // System.out.println(); // } // System.out.print(String.format("%8x ", dataBuffer.getElem(i))); // } // System.out.println();
// Create the image BufferedImage bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB); bufferedImage.setData(raster); // Dump
// System.out.println("BufferedImage :"); // for (int y = 0; y < height; y++) { // System.out.println(); // for (int x = 0; x < width; x++) { // System.out.print(String.format("%8x ", bufferedImage.getRGB(x, y))); // } // } // System.out.println();
return PlanarImage.wrapRenderedImage(bufferedImage); } //--------// // toARGB // //--------// /** * Compute the ARGB pixel that corresponds to the given char * * @param c the char * @return the corresponding pixel value (ARGB format) */ private static int toARGB (char c) { // Check the char if (c == WHITE) { return 0x00ffffff; // Totally transparent / white } else { for (int i = charTable.length -1; i >= 0; i--) { if (charTable[i] == c) { int level = 3 + i * 36; // Range 3 .. 255 (not too bad) return 255 << 24 | // Alpha (opaque) level << 16 | // R level << 8 | // G level; // B } } } return 0x00ffffff; // Totally transparent / white } //------------------// // checkImageFormat // //------------------// /** * Check if the image format (and especially its color model) is * properly handled by Audiveris. * * @throws ImageFormatException is the format is not supported */ private void checkImageFormat() { // Check nb of bands int numBands = image.getSampleModel().getNumBands(); if (numBands != 1) { if (numBands == 3) { image = colorToGray(image); } else { throw new RuntimeException ("Unsupported sample model" + " numBands=" + numBands); } } // Check pixel size ColorModel colorModel = image.getColorModel(); int pixelSize = colorModel.getPixelSize(); if (pixelSize != 8) { System.out.println("pixelSize=" + pixelSize + " colorModel=" + colorModel); image = grayToGray256(image); } } //--------// // invert // //--------// private static PlanarImage invert (PlanarImage image) { return JAI.create("Invert", new ParameterBlock() .addSource(image) .add(null) .add(null) .add(null) .add(null) .add(null), null); } //-------------// // colorToGray // //-------------// private static PlanarImage colorToGray (PlanarImage image) { System.out.println("Converting color image to gray ..."); double[][] matrix = { {0.114d, 0.587d, 0.299d, 0.0d} }; return JAI.create("bandcombine", new ParameterBlock() .addSource(image) .add(matrix), null); } //---------------// // grayToGray256 // //---------------// private static PlanarImage grayToGray256 (PlanarImage image) { System.out.println("Converting gray image to gray-256 ..."); ColorSpace colorSpace = ColorSpace.getInstance (java.awt.color.ColorSpace.CS_GRAY);
// int[] bits = new int[]{8}; // int opaque = Transparency.OPAQUE; // int dataType = DataBuffer.TYPE_BYTE; // ColorModel colorModel = new ComponentColorModel // (colorSpace, bits, false, false, opaque, dataType);
return JAI.create("colorConvert", image, colorSpace, null); }
} //-----------------------------------------------------------------------// //// //I m a g e I n f o // //// //Copyright (C) Herve Bitteur 2000-2007. All rights reserved. // //This software is released under the terms of the GNU General Public // //License. Please contact the author at herve.bitteur@laposte.net // //to report bugs & suggestions. // //-----------------------------------------------------------------------//
import java.awt.Transparency; import java.awt.image.*; import java.io.File; import javax.media.jai.*; public class ImageInfo { public static void main(String[] args) { // Open the image (using the name passed as a command line parameter) PlanarImage pi = JAI.create("fileload", args[0]); // Get the image file size (non-JAI related). File image = new File(args[0]); System.out.println("Image file size: "+image.length()+" bytes."); print(pi); } public static void print (PlanarImage pi) { // Show the image dimensions and coordinates. System.out.print("Image Dimensions: "); System.out.print(pi.getWidth()+"x"+pi.getHeight()+" pixels"); // Remember getMaxX and getMaxY return the coordinate of the next point! System.out.println(" (from "+pi.getMinX()+","+pi.getMinY()+" to " + (pi.getMaxX()-1)+","+(pi.getMaxY()-1)+")"); if ((pi.getNumXTiles() != 1)||(pi.getNumYTiles() != 1)) { // Is it tiled? // Tiles number, dimensions and coordinates. System.out.print("Tiles: "); System.out.print(pi.getTileWidth()+"x"+pi.getTileHeight()+" pixels"+ " ("+pi.getNumXTiles()+"x"+pi.getNumYTiles()+" tiles)"); System.out.print(" (from "+pi.getMinTileX()+","+pi.getMinTileY()+ " to "+pi.getMaxTileX()+","+pi.getMaxTileY()+")"); System.out.println(" offset: "+pi.getTileGridXOffset()+","+ pi.getTileGridXOffset()); } // Display info about the SampleModel of the image. SampleModel sm = pi.getSampleModel(); System.out.println("Number of bands: "+sm.getNumBands()); System.out.print("Data type: "); switch(sm.getDataType()) { case DataBuffer.TYPE_BYTE: System.out.println("byte"); break; case DataBuffer.TYPE_SHORT: System.out.println("short"); break; case DataBuffer.TYPE_USHORT: System.out.println("ushort"); break; case DataBuffer.TYPE_INT: System.out.println("int"); break; case DataBuffer.TYPE_FLOAT: System.out.println("float"); break; case DataBuffer.TYPE_DOUBLE: System.out.println("double"); break; case DataBuffer.TYPE_UNDEFINED:System.out.println("undefined"); break; } // Display info about the ColorModel of the image. ColorModel cm = pi.getColorModel(); if (cm != null) { System.out.println("Number of color components: "+ cm.getNumComponents()); System.out.println("Bits per pixel: "+cm.getPixelSize()); System.out.print("Image Transparency: "); switch(cm.getTransparency()) { case Transparency.OPAQUE: System.out.println("opaque"); break; case Transparency.BITMASK: System.out.println("bitmask"); break; case Transparency.TRANSLUCENT: System.out.println("translucent"); break; } } else System.out.println("No color model."); } }
</source>
Media player
<source lang="java">
/*
* @(#)MDIApp.java 1.3 01/03/13 * * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */
import java.awt.BorderLayout; import java.awt.CheckboxMenuItem; import java.awt.ruponent; import java.awt.Dimension; import java.awt.FileDialog; import java.awt.Frame; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.media.ControllerEvent; import javax.media.ControllerListener; import javax.media.EndOfMediaEvent; import javax.media.Manager; import javax.media.NoPlayerException; import javax.media.Player; import javax.media.PrefetchCompleteEvent; import javax.media.RealizeCompleteEvent; import javax.media.Time; import javax.swing.JDesktopPane; import javax.swing.JInternalFrame; import javax.swing.UIManager; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; import com.sun.media.ui.MessageBox; public class MDIApp extends Frame {
/************************************************************************* * MAIN PROGRAM / STATIC METHODS *************************************************************************/ public static void main(String args[]) { MDIApp mdi = new MDIApp(); } static void Fatal(String s) { MessageBox mb = new MessageBox("JMF Error", s); } /************************************************************************* * VARIABLES *************************************************************************/ JMFrame jmframe = null; JDesktopPane desktop; FileDialog fd = null; CheckboxMenuItem cbAutoLoop = null; Player player = null; Player newPlayer = null; String filename; /************************************************************************* * METHODS *************************************************************************/ public MDIApp() { super("Java Media Player"); // Add the desktop pane setLayout( new BorderLayout() ); desktop = new JDesktopPane(); desktop.setDoubleBuffered(true); add("Center", desktop); setMenuBar(createMenuBar()); setSize(640, 480); setVisible(true); try { UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); } catch (Exception e) { System.err.println("Could not initialize java.awt Metal lnf"); } addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent we) { System.exit(0); } } ); Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, new Boolean(true)); } private MenuBar createMenuBar() { ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent ae) { String command = ae.getActionCommand(); if (command.equals("Open")) { if (fd == null) { fd = new FileDialog(MDIApp.this, "Open File", FileDialog.LOAD); fd.setDirectory("/movies"); } fd.show(); if (fd.getFile() != null) { String filename = fd.getDirectory() + fd.getFile(); openFile("file:" + filename); } } else if (command.equals("Exit")) { dispose(); System.exit(0); } } }; MenuItem item; MenuBar mb = new MenuBar(); // File Menu Menu mnFile = new Menu("File"); mnFile.add(item = new MenuItem("Open")); item.addActionListener(al); mnFile.add(item = new MenuItem("Exit")); item.addActionListener(al); // Options Menu Menu mnOptions = new Menu("Options"); cbAutoLoop = new CheckboxMenuItem("Auto replay"); cbAutoLoop.setState(true); mnOptions.add(cbAutoLoop); mb.add(mnFile); mb.add(mnOptions); return mb; } /** * Open a media file. */ public void openFile(String filename) { String mediaFile = filename; Player player = null; // URL for our media file URL url = null; try { // Create an url from the file name and the url to the // document containing this applet. if ((url = new URL(mediaFile)) == null) { Fatal("Can"t build URL for " + mediaFile); return; } // Create an instance of a player for this media try { player = Manager.createPlayer(url); } catch (NoPlayerException e) { Fatal("Error: " + e); } } catch (MalformedURLException e) { Fatal("Error:" + e); } catch (IOException e) { Fatal("Error:" + e); } if (player != null) { this.filename = filename; JMFrame jmframe = new JMFrame(player, filename); desktop.add(jmframe); } }
} class JMFrame extends JInternalFrame implements ControllerListener {
Player mplayer; Component visual = null; Component control = null; int videoWidth = 0; int videoHeight = 0; int controlHeight = 30; int insetWidth = 10; int insetHeight = 30; boolean firstTime = true; public JMFrame(Player player, String title) { super(title, true, true, true, true); getContentPane().setLayout( new BorderLayout() ); setSize(320, 10); setLocation(50, 50); setVisible(true); mplayer = player; mplayer.addControllerListener((ControllerListener) this); mplayer.realize(); addInternalFrameListener( new InternalFrameAdapter() { public void internalFrameClosing(InternalFrameEvent ife) { mplayer.close(); } } ); } public void controllerUpdate(ControllerEvent ce) { if (ce instanceof RealizeCompleteEvent) { mplayer.prefetch(); } else if (ce instanceof PrefetchCompleteEvent) { if (visual != null) return; if ((visual = mplayer.getVisualComponent()) != null) { Dimension size = visual.getPreferredSize(); videoWidth = size.width; videoHeight = size.height; getContentPane().add("Center", visual); } else videoWidth = 320; if ((control = mplayer.getControlPanelComponent()) != null) { controlHeight = control.getPreferredSize().height; getContentPane().add("South", control); } setSize(videoWidth + insetWidth, videoHeight + controlHeight + insetHeight); validate(); mplayer.start(); } else if (ce instanceof EndOfMediaEvent) { mplayer.setMediaTime(new Time(0)); mplayer.start(); } }
}
</source>
Query the installed version of the JMF
<source lang="java"> /*******************************************************************************
* GUIManagerQuery - A Graphical User Interface built atop the ManagerQuery * class allowing the user to query the installed version of the JMF as to its * support in termsof different players, processors, and protocols. * * @author Spike Barlow ******************************************************************************/
import java.awt.*; import java.awt.event.*; import javax.media.*; import java.util.*; public class GUIManagerQuery extends Frame implements ActionListener {
/** The version of the JMF. */ protected Label versionLabel; /** Button to print JMF"s hints. */ protected Button hintsButton; /** Button to print list of players. */ protected Button playersButton; /** Button to print list of processors. */ protected Button processorsButton; /** Button to print list of data sources. */ protected Button sourcesButton; /** TextField in which user can enter protocols or content types. */ protected TextField contentsField; /** Area in which the results are displayed. */ protected TextArea results; /*************************************************************************** * Construct the GUIManagerQuery object, constructing the various components * and laying them out on the screen. **************************************************************************/ public GUIManagerQuery() { super("GUIManagerQuery"); setLayout(new BorderLayout()); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); versionLabel = new Label("JMF v" + Manager.getVersion()); add(versionLabel, "North"); Panel lower = new Panel(); lower.add(new Label("Content/Protocol")); contentsField = new TextField(32); lower.add(contentsField); add(lower, "South"); results = new TextArea(20, 80); results.setEditable(false); add(results, "Center"); Panel controls = new Panel(); controls.setLayout(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); hintsButton = new Button("Hints"); gbc.gridx = 0; gbc.gridy = 0; controls.add(hintsButton, gbc); hintsButton.addActionListener(this); playersButton = new Button("Players"); gbc.gridy = 1; controls.add(playersButton, gbc); playersButton.addActionListener(this); processorsButton = new Button("Processors"); gbc.gridy = 2; controls.add(processorsButton, gbc); processorsButton.addActionListener(this); sourcesButton = new Button("DataSources"); gbc.gridy = 3; controls.add(sourcesButton, gbc); sourcesButton.addActionListener(this); add(controls, "East"); } /*************************************************************************** * Respond to button presses from the user indicating the desire for * information such as a list of players. **************************************************************************/ public void actionPerformed(ActionEvent e) { int type; String[] cons; //////////////////////////////////////////////////////////////// // Handle hints - simplest case [no need to check content types] //////////////////////////////////////////////////////////////// if (e.getSource() == hintsButton) { results.setText(ManagerQuery.getHints()); } ///////////////////////////////////////////////////////////////////// // Players, processors, or datasources. Need to check the contents // field and if it has text in there then use that as a qualifier // in the search for classes. However if empty then generate a // complete list of all classes of the required type. User may // enter multiple content types either comma or space separated, // hence use of StringTokenizer. //////////////////////////////////////////////////////////////////// else { if (e.getSource() == playersButton) type = ManagerQuery.HANDLERS; else if (e.getSource() == processorsButton) type = ManagerQuery.PROCESSORS; else type = ManagerQuery.DATASOURCES; String contents = contentsField.getText(); if (contents == null || contents.length() == 0) cons = null; else { StringTokenizer tokenizer = new StringTokenizer(contents, " ,\t;"); cons = new String[tokenizer.countTokens()]; for (int i = 0; i < cons.length; i++) cons[i] = tokenizer.nextToken(); } if (cons != null && cons.length > 0) results.setText(ManagerQuery .getHandlersOrProcessors(cons, type)); else if (type == ManagerQuery.HANDLERS) results.setText(ManagerQuery.getHandlers()); else if (type == ManagerQuery.PROCESSORS) results.setText(ManagerQuery.getProcessors()); else results.setText(ManagerQuery.getDataSources()); } } /*************************************************************************** * Main method - construct a GUIManagerQuery frame and show it on the * screen. **************************************************************************/ public static void main(String[] args) { GUIManagerQuery gui = new GUIManagerQuery(); gui.pack(); gui.setSize(640, 600); gui.show(); }
}
</source>
Renderer for RGB images using AWT Image using Java Media API
<source lang="java">
/*
* @(#)SampleAWTRenderer.java 1.3 01/03/13 * * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */
import javax.media.*; import javax.media.renderer.VideoRenderer; import javax.media.Format; import javax.media.format.VideoFormat; import javax.media.format.RGBFormat; import java.awt.*; import java.awt.image.*; import java.awt.color.ColorSpace; import java.awt.event.*; import java.util.Vector; /**
* Renderer for RGB images using AWT Image. */
public class SampleAWTRenderer implements javax.media.renderer.VideoRenderer {
/*************************************************************************
* Variables and Constants
*************************************************************************/
// The descriptive name of this renderer
private static final String name = "Sample AWT Renderer";
protected RGBFormat inputFormat;
protected RGBFormat supportedRGB;
protected Format[] supportedFormats;
protected MemoryImageSource sourceImage;
protected Image destImage;
protected Buffer lastBuffer = null;
protected int inWidth = 0;
protected int inHeight = 0;
protected Component component = null;
protected Rectangle reqBounds = null;
protected Rectangle bounds = new Rectangle();
protected boolean started = false;
/*************************************************************************
* Constructor
*************************************************************************/
public SampleAWTRenderer() {
// Prepare supported input formats and preferred format
int rMask = 0x000000FF;
int gMask = 0x0000FF00;
int bMask = 0x00FF0000;
supportedRGB = new RGBFormat(null, // size
Format.NOT_SPECIFIED, // maxDataLength
int[].class, // buffer type
Format.NOT_SPECIFIED, // frame rate
32, // bitsPerPixel
rMask, gMask, bMask, // component masks
1, // pixel stride
Format.NOT_SPECIFIED, // line stride
Format.FALSE, // flipped
Format.NOT_SPECIFIED // endian
);
supportedFormats = new VideoFormat[1];
supportedFormats[0] = supportedRGB;
}
/****************************************************************
* Controls implementation
****************************************************************/
/**
* Returns an array of supported controls
**/
public Object[] getControls() {
// No controls
return (Object[]) new Control[0];
}
/**
* Return the control based on a control type for the PlugIn.
*/
public Object getControl(String controlType) {
try {
Class cls = Class.forName(controlType);
Object cs[] = getControls();
for (int i = 0; i < cs.length; i++) {
if (cls.isInstance(cs[i]))
return cs[i];
}
return null;
} catch (Exception e) { // no such controlType or such control
return null;
}
}
/*************************************************************************
* PlugIn implementation
*************************************************************************/
public String getName() {
return name;
}
/**
* Opens the plugin
*/
public void open() throws ResourceUnavailableException {
sourceImage = null;
destImage = null;
lastBuffer = null;
}
/**
* Resets the state of the plug-in. Typically at end of media or when media
* is repositioned.
*/
public void reset() {
// Nothing to do
}
public void close() {
// Nothing to do
}
/*************************************************************************
* Renderer implementation
*************************************************************************/
public void start() {
started = true;
}
public void stop() {
started = false;
}
/**
* Lists the possible input formats supported by this plug-in.
*/
public Format[] getSupportedInputFormats() {
return supportedFormats;
}
/**
* Set the data input format.
*/
public Format setInputFormat(Format format) {
if (format != null && format instanceof RGBFormat && format.matches(supportedRGB)) {
inputFormat = (RGBFormat) format;
Dimension size = inputFormat.getSize();
inWidth = size.width;
inHeight = size.height;
return format;
} else
return null;
}
/**
* Processes the data and renders it to a component
*/
public synchronized int process(Buffer buffer) {
if (component == null)
return BUFFER_PROCESSED_FAILED;
Format inf = buffer.getFormat();
if (inf == null)
return BUFFER_PROCESSED_FAILED;
if (inf != inputFormat || !buffer.getFormat().equals(inputFormat)) {
if (setInputFormat(inf) != null)
return BUFFER_PROCESSED_FAILED;
}
Object data = buffer.getData();
if (!(data instanceof int[]))
return BUFFER_PROCESSED_FAILED;
if (lastBuffer != buffer) {
lastBuffer = buffer;
newImage(buffer);
}
sourceImage.newPixels(0, 0, inWidth, inHeight);
Graphics g = component.getGraphics();
if (g != null) {
if (reqBounds == null) {
bounds = component.getBounds();
bounds.x = 0;
bounds.y = 0;
} else
bounds = reqBounds;
g.drawImage(destImage, bounds.x, bounds.y, bounds.width, bounds.height, 0, 0, inWidth, inHeight, component);
}
return BUFFER_PROCESSED_OK;
}
/****************************************************************
* VideoRenderer implementation
****************************************************************/
/**
* Returns an AWT component that it will render to. Returns null
* if it is not rendering to an AWT component.
*/
public java.awt.ruponent getComponent() {
if (component == null) {
component = new Canvas() {
public Dimension getPreferredSize() {
return new Dimension(getInWidth(), getInHeight());
}
public void update(Graphics g) {
}
public void paint(Graphics g) {
// TODO: Need to repaint image if the movie is in paused state
}
};
}
return component;
}
/**
* Requests the renderer to draw into a specified AWT component.
* Returns false if the renderer cannot draw into the specified
* component.
*/
public boolean setComponent(java.awt.ruponent comp) {
component = comp;
return true;
}
/**
* Sets the region in the component where the video is to be
* rendered to. Video is to be scaled if necessary. If rect
* is null, then the video occupies the entire component.
*/
public void setBounds(java.awt.Rectangle rect) {
reqBounds = rect;
}
/**
* Returns the region in the component where the video will be
* rendered to. Returns null if the entire component is being used.
*/
public java.awt.Rectangle getBounds() {
return reqBounds;
}
/*************************************************************************
* Local methods
*************************************************************************/
int getInWidth() {
return inWidth;
}
int getInHeight() {
return inHeight;
}
private void newImage(Buffer buffer) {
if (!(buffer.getData() instanceof int[]))
return;
int[] data = (int[]) buffer.getData();
RGBFormat format = (RGBFormat) buffer.getFormat();
//data = processImage(buffer);
data = (int[]) buffer.getData();
DirectColorModel dcm = new DirectColorModel(format.getBitsPerPixel(), format.getRedMask(), format.getGreenMask(), format.getBlueMask());
sourceImage = new MemoryImageSource(format.getLineStride(), format.getSize().height, dcm, (int[]) data, 0, format.getLineStride());
sourceImage.setAnimated(true);
sourceImage.setFullBufferUpdates(true);
if (component != null) {
destImage = component.createImage(sourceImage);
component.prepareImage(destImage, component);
}
}
private int[] processImage(Buffer buf) {
int[] data = (int[]) buf.getData();
int[] ret = new int[data.length];
RGBFormat fmt = (RGBFormat) buf.getFormat();
DirectColorModel dcm = new DirectColorModel(fmt.getBitsPerPixel(), fmt.getRedMask(), fmt.getGreenMask(), fmt.getBlueMask());
int[] rgb;
int k;
for (int i = 0; i < data.length; i++) {
rgb = dcm.getComponents(data[i], null, 0);
k = toGray(rgb);
rgb[0] = rgb[1] = rgb[2] = k;
ret[i] = dcm.getDataElement(rgb, 0);
}
return ret;
}
private int toGray(int[] rgb) {
return (int) (0.2125 * rgb[0] + 0.7154 * rgb[1] + 0.0721 * rgb[2]);
}
}
</source>
Sample program to demonstrate FramePositioningControl.
<source lang="java">
/*
* @(#)Seek.java 1.2 01/03/13 * * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved. * * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, * modify and redistribute this software in source and binary code form, * provided that i) this copyright notice and license appear on all copies of * the software; and ii) Licensee does not utilize the software in a manner * which is disparaging to Sun. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * This software is not designed or intended for use in on-line control of * aircraft, air traffic, aircraft navigation or aircraft communications; or in * the design, construction, operation or maintenance of any nuclear * facility. Licensee represents and warrants that it will not use or * redistribute the Software for such purposes. */
import java.awt.BorderLayout; import java.awt.Button; import java.awt.ruponent; import java.awt.Frame; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileNotFoundException; import javax.media.ConfigureCompleteEvent; import javax.media.ControllerEvent; import javax.media.ControllerListener; import javax.media.Duration; import javax.media.EndOfMediaEvent; import javax.media.Manager; import javax.media.MediaLocator; import javax.media.Player; import javax.media.PrefetchCompleteEvent; import javax.media.RealizeCompleteEvent; import javax.media.ResourceUnavailableEvent; import javax.media.SizeChangeEvent; import javax.media.Time; import javax.media.control.FramePositioningControl; import javax.media.protocol.DataSource;
/**
* Sample program to demonstrate FramePositioningControl. */
public class Seek extends Frame implements ControllerListener, ActionListener {
Player p; FramePositioningControl fpc; Object waitSync = new Object(); boolean stateTransitionOK = true; int totalFrames = FramePositioningControl.FRAME_UNKNOWN; Panel cntlPanel; Button fwdButton; Button bwdButton; Button rndButton; /** * Given a DataSource, create a player and use that player * as a player to playback the media. */ public boolean open(DataSource ds) { System.err.println("create player for: " + ds.getContentType()); try { p = Manager.createPlayer(ds); } catch (Exception e) { System.err.println("Failed to create a player from the given DataSource: " + e); return false; } p.addControllerListener(this); p.realize(); if (!waitForState(p.Realized)) { System.err.println("Failed to realize the player."); return false; } // Try to retrieve a FramePositioningControl from the player. fpc = (FramePositioningControl)p.getControl("javax.media.control.FramePositioningControl"); if (fpc == null) { System.err.println("The player does not support FramePositioningControl."); System.err.println("There"s no reason to go on for the purpose of this demo."); return false; } Time duration = p.getDuration(); if (duration != Duration.DURATION_UNKNOWN) { System.err.println("Movie duration: " + duration.getSeconds()); totalFrames = fpc.mapTimeToFrame(duration); if (totalFrames != FramePositioningControl.FRAME_UNKNOWN) System.err.println("Total # of video frames in the movies: " + totalFrames); else System.err.println("The FramePositiongControl does not support mapTimeToFrame."); } else { System.err.println("Movie duration: unknown"); } // Prefetch the player. p.prefetch(); if (!waitForState(p.Prefetched)) { System.err.println("Failed to prefetch the player."); return false; } // Display the visual & control component if there"s one. setLayout(new BorderLayout()); cntlPanel = new Panel(); fwdButton = new Button("Forward"); bwdButton = new Button("Backward"); rndButton = new Button("Random"); fwdButton.addActionListener(this); bwdButton.addActionListener(this); rndButton.addActionListener(this); cntlPanel.add(fwdButton); cntlPanel.add(bwdButton); cntlPanel.add(rndButton); Component vc; if ((vc = p.getVisualComponent()) != null) { add("Center", vc); } add("South", cntlPanel); setVisible(true); return true; }
public void addNotify() { super.addNotify(); pack(); }
/** * Block until the player has transitioned to the given state. * Return false if the transition failed. */ boolean waitForState(int state) { synchronized (waitSync) { try { while (p.getState() < state && stateTransitionOK) waitSync.wait(); } catch (Exception e) {} } return stateTransitionOK; }
public void actionPerformed(ActionEvent ae) { String command = ae.getActionCommand(); if (command.equals("Forward")) { int dest = fpc.skip(1); System.err.println("Step forward " + dest + " frame."); } else if (command.equals("Backward")) { int dest = fpc.skip(-1); System.err.println("Step backward " + dest + " frame."); } else if (command.equals("Random")) { if (totalFrames == FramePositioningControl.FRAME_UNKNOWN) System.err.println("Cannot jump to a random frame."); else { int randomFrame = (int)(totalFrames * Math.random()); randomFrame = fpc.seek(randomFrame); System.err.println("Jump to a random frame: " + randomFrame); } } int currentFrame = fpc.mapTimeToFrame(p.getMediaTime()); if (currentFrame != FramePositioningControl.FRAME_UNKNOWN) System.err.println("Current frame: " + currentFrame); }
/** * Controller Listener. */ public void controllerUpdate(ControllerEvent evt) { if (evt instanceof ConfigureCompleteEvent || evt instanceof RealizeCompleteEvent || evt instanceof PrefetchCompleteEvent) { synchronized (waitSync) { stateTransitionOK = true; waitSync.notifyAll(); } } else if (evt instanceof ResourceUnavailableEvent) { synchronized (waitSync) { stateTransitionOK = false; waitSync.notifyAll(); } } else if (evt instanceof EndOfMediaEvent) { p.setMediaTime(new Time(0)); //p.start(); //p.close(); //System.exit(0); } else if (evt instanceof SizeChangeEvent) { } }
/** * Main program */ public static void main(String [] args) { if (args.length == 0) { prUsage(); System.exit(0); } MediaLocator ml; if ((ml = new MediaLocator(args[0])) == null) { System.err.println("Cannot build media locator from: " + args[0]); prUsage(); System.exit(0); } DataSource ds = null; // Create a DataSource given the media locator. try { ds = Manager.createDataSource(ml); } catch (Exception e) { System.err.println("Cannot create DataSource from: " + ml); System.exit(0); } Seek seek = new Seek(); if (!seek.open(ds)) System.exit(0); } static void prUsage() { System.err.println("Usage: java Seek <url>"); }
}
</source>
Select a media file from tjelocal file system and gain statistics
<source lang="java"> /**********************************************************************
- GUIMediaStatistics - a GUI allowing the user to select a media
- file from tjelocal file system and gain statistics on that media
- (audio or video) concerning its tracks and their format/composition.
- The class is built atop the MediaStatistics class and arguably
- provides a more user friendly mechanism for determining the
- format of media.
- @author Spike Barlow
- /
import java.awt.*; import java.awt.event.*; import javax.media.*; import java.util.*; public class GUIMediaStatistics extends Frame implements ActionListener {
/** Object to determine the format ofthe media. Performs all the real work. */ protected MediaStatistics stats; /** User wants to search for a file. */ protected Button browseButton; /** User wants to know the format of the current file. */ protected Button getStatsButton; /** Current state of processing. */ protected int state; /** Where the format informationis displayed. */ protected TextArea results; /** Area i which the user can type the name of a file. */ protected TextField mediaField; /** Pause in milliseconds between checks to see if format is known. */ public static final int PAUSE = 50; /** Maximum wait before giving up on determining theformat. */ public static final int MAX_WAIT_PERIOD = 10000; /** Directory that the user last searched for files. */ protected String lastDirectory;
/**********************************************************************
- Construct the GUIMediaStatistics object, constructing the various
- components and laying them out on the screen.
- /
public GUIMediaStatistics() {
super("GUIMediaStatistics"); setLayout(new BorderLayout()); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); Panel filePanel = new Panel(); filePanel.add(new Label("File:")); mediaField = new TextField(40); filePanel.add(mediaField); browseButton =new Button("browse..."); filePanel.add(browseButton); browseButton.addActionListener(this); getStatsButton = new Button("get stats..."); filePanel.add(getStatsButton); getStatsButton.addActionListener(this); add(filePanel,"North"); results = new TextArea(80,10); results.setEditable(false); add(results,"Center");
}
/************************************************************************
- Respond to user button presses - either browsing for a file or
- gathering format info on the current file.
- /
public void actionPerformed(ActionEvent e) {
///////////////////////////////// // Browse - use FileDialog class. ///////////////////////////////// if (e.getSource() == browseButton) { 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(); mediaField.setText("file://" + choice.getDirectory() + selection); } } //////////////////////////////////////////////////////// // Get statistics - create a MediaStatistics object and // monitor its progress. /////////////////////////////////////////////////////// else { stats = new MediaStatistics(mediaField.getText()); monitorAndReport(); } } /************************************************************************ * Monitor the progress of the MediaStatistics object as it attempts to * determineformatinformation for the current file. It periodically * polls the object, obtaining a report from it and printing it to the * screen. The polling stops as soon as the format is known, it is * found that it isimpossible to determine a format, or a certain time * period is exceeded. **************************************************************************/ private void monitorAndReport() { int elapsed = 0; state = stats.getState(); while (elapsed < MAX_WAIT_PERIOD && (state != MediaStatistics.FAILED && state != MediaStatistics.KNOWN)) { results.setText(stats.getReport()); try { Thread.sleep(PAUSE); } catch (Exception e) { } elapsed += PAUSE; state = stats.getState(); } if (state == MediaStatistics.FAILED || state == MediaStatistics.KNOWN) results.setText(stats.getReport()); else results.setText("Timing out after maximum period of " + MAX_WAIT_PERIOD + "ms"); } /*************************************************************************** * Main method - construct a GUIMediaStatistics frame and show it on the * screen. **************************************************************************/ public static void main(String[] args) { GUIMediaStatistics gui = new GUIMediaStatistics(); gui.pack(); gui.setSize(600, 400); gui.show(); }
}
</source>