📄 mediacontent.java
字号:
/*
* MediaContent.java
* Created on 16. April 2003, 10:30
*
* Copyright (C) 2003 Florian Ledermann, Vienna University of Technology
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Contact address: ledermann@ims.tuwien.ac.at
*/
package org.vizir.media;
import java.awt.Dimension;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
//import javax.media.*;
//import javax.media.control.TrackControl;
//import javax.media.control.FramePositioningControl;
//import javax.media.format.*;
/**
* Description: This class encapsulates visual media (video, images) for frame-based retrieval.
* The media is read from an URL passed to the constructor and internally accessed
* by Java2D/JMF to retrieve the pixel data. Various methods can be used for
* convenient retrieval of raw pixel data in the desired color model.
*
* @author flo ledermann ledermann@ims.tuwien.ac.at
* @version $Id: MediaContent.java,v 1.2 2004/02/12 09:20:24 mr Exp $
*/
public class MediaContent {
/** set to false to supress debugging output */
private static final boolean DEBUG = true;
/** Constant for unknown color or media format */
public static final int UNKNOWN = -1;
/** Media type: image */
public static final int IMAGE = 0;
/** Media type: video */
public static final int VIDEO = 1;
/** Media type, IMAGE, VIDEO or UNKNOWN */
private int mediaType = UNKNOWN;
/** Color model, RGB, YUV or UNKNOWN */
private ColorModel colorModel = null;
// image stuff
/** The image to read pixel data from. */
BufferedImage image = null;
// video stuff
/** An object used for synchronization with the processor. */
Object stateSync = null;
/** Flag indicating successful completion of last state transition by the processor. */
boolean stateTransitionOK = true;
/** Processor for video data. */
// Processor p = null;
/** Control for accessing individual frames. */
// FramePositioningControl fpc = null;
/** The video format details. */
// VideoFormat videoFormat = null;
/** A Buffer containing the last frame that was successfully captured by our codec. */
// Buffer frameData = null;
/** Number of frames to be skipped when calling getNext(). */
int keyframeInterval = 1;
/**
* Constructor to read media from a given url. If the url has one of the well-known
* image extensions (jpg, jpeg, gif, bmp, tiff, svg), it tries to load an image from
* the URL, otherwise a video processor is created from the url.
*
* @param url The URL of the media file to load.
* @throws IOException Something went wrong when trying to load the contents.
* @throws Exception Something went wron when trying to initialize the JMF video
* processor.
*/
public MediaContent(URL url) throws IOException, Exception{
String ext = url.getFile();
ext = ext.substring(ext.lastIndexOf('.')+1);
if (ext.equalsIgnoreCase("jpg") ||
ext.equalsIgnoreCase("jpeg") ||
ext.equalsIgnoreCase("gif") ){
image = javax.imageio.ImageIO.read(url);
}
if (image != null){
mediaType = IMAGE;
colorModel = new ColorModel(ColorModel.RGB);
}
/*
else {
stateSync = new Object();
try {
p = Manager.createProcessor(url);
}
catch (Exception e) {
throw new IOException("Source could not be loaded from " + url.toString());
}
p.addControllerListener(this);
p.configure();
if (!waitForState(Processor.Configured)) {
throw new Exception("Failed to configure the processor.");
}
// we want to use our processor as a player, so disable output
p.setContentDescriptor(null);
TrackControl[] tc = p.getTrackControls();
if (tc == null) {
throw new Exception("Failed to obtain track controls from the processor.");
}
// Search for the track control for the video track.
TrackControl videoTrack = null;
for (int i = 0; i < tc.length; i++) {
if (tc[i].getFormat() instanceof VideoFormat) {
videoTrack = tc[i];
videoFormat = (VideoFormat) videoTrack.getFormat();
break;
}
}
if (videoTrack == null) {
throw new Exception("The input media does not contain a video track.");
}
frameData = new Buffer();
if (DEBUG) System.err.println("Video format: " + videoFormat);
// Instantiate and set the frame access codec to the data flow path.
try {
Codec codec[] = { new FrameAccessCodec()};
videoTrack.setCodecChain(codec);
} catch (UnsupportedPlugInException e) {
throw new Exception("The processor does not support codec Plug-Ins.");
}
// Try to retrieve a FramePositioningControl from the player.
fpc = (FramePositioningControl)p.getControl("javax.media.control.FramePositioningControl");
if (fpc == null) {
throw new Exception("The player does not support FramePositioningControl.");
}
// Realize the processor.
p.prefetch();
if (!waitForState(Processor.Prefetched)) {
throw new Exception("Failed to realize the processor.");
}
mediaType = VIDEO;
colorModel = new ColorModel(ColorModel.RGB);
}*/
}
/**
* Function to return the image as BufferedImage. If the mediaType is not IMAGE, the function return null.
* @return image as BufferedImage, null if mediaType is not IMAGE.
*/
public BufferedImage getImage(){
if (mediaType == IMAGE)
return image;
else
return null;
}
/**
* Block until the processor has transitioned to the given state.
* @return false if the transition failed.
*/
/*boolean waitForState(int state) {
synchronized (stateSync) {
try {
while (p.getState() != state && stateTransitionOK)
stateSync.wait();
} catch (Exception e) {}
}
return stateTransitionOK;
}*/
/**
* Returns the first frame of the media.
* @return MediaFrame object, representing the first frame of the media.
*/
public MediaFrame getFirst(){ return null;}
/* if (mediaType == VIDEO && fpc != null){
int fnum = fpc.seek(0);
if (DEBUG) System.err.println("seeked to frame " + fnum);
return getFrameData();
}
if (mediaType == IMAGE){
return getImageData();
}
return null;
}
*/
/**
* Helper function to return the pixel data of an image.
* @return MediaFrame object of the image.
* @throws UnsupportedOperationException if the frame data could not be grabbed
*/
private MediaFrame getImageData(){
int conversion = Pixel.NO_CONVERSION;
if (colorModel.getColorSpace() == ColorModel.YUV) conversion = Pixel.RGB2YUV;
return new MediaFrame(image);
}
/**
* Helper function to return the pixel data of a video frame.
* @return MediaFrame object of the video frame.
* @throws UnsupportedOperationException if the frame data could not be grabbed
*/
/*
private MediaFrame getFrameData() throws UnsupportedOperationException{
Format test=frameData.getFormat();
if (! (frameData.getFormat() instanceof RGBFormat))
throw new UnsupportedOperationException("unknown frame data format");
int conversion = Pixel.NO_CONVERSION;
if (colorModel.getColorSpace() == ColorModel.YUV) conversion = Pixel.RGB2YUV;
Object data = frameData.getData();
RGBFormat rgbf = (RGBFormat)frameData.getFormat();
Dimension2D d = rgbf.getSize();
if (DEBUG) System.err.println("Buffer length: " + frameData.getLength());
if (rgbf.getDataType() == Format.byteArray) {
return new MediaFrame((byte[])data,(int)d.getWidth(),(int)d.getHeight());
}
if (rgbf.getDataType() == Format.shortArray) {
return new MediaFrame((short[])data,(int)d.getWidth(),(int)d.getHeight());
}
if (rgbf.getDataType() == Format.intArray) {
return new MediaFrame((int[])data,(int)d.getWidth(),(int)d.getHeight());
}
else throw new UnsupportedOperationException("unknown frame data format");
}
*/
/**
* Gets the next keyframe, according to the setting of keyframeInterval.
* @return MediaFrame object, representing the desired frame.
*/
public MediaFrame getNext(){ return null; }
/* if (mediaType == VIDEO && fpc != null){
int fnum = fpc.skip(keyframeInterval);
if (DEBUG) System.err.println("skipped " + fnum + " frames");
return getFrameData();
}
if (mediaType == IMAGE){
return getImageData();
}
return null;
}
*/
/**
* Gets the frame closest to the given time.
* @param time Time to seek to.
* @return Media Frame objects, representing the desired frame.
*/
/*
public MediaFrame getViewAtTime(Time time){
if (mediaType == VIDEO && fpc != null){
int fnum = fpc.mapTimeToFrame(time);
fnum = fpc.seek(fnum);
if (DEBUG) System.err.println("seeked to frame " + fnum);
return getFrameData();
}
if (mediaType == IMAGE){
return getImageData();
}
return null;
}
*/
/**
* Returns the interval that is used by getNext().
* @return The current keyframeInterval.
*/
public int getKeyframeInterval() {
return keyframeInterval;
}
/**
* Sets the interval (in frames) that is used by getNext().
* @param frames Number of frames to skip by getNext().
*/
public void setKeyframeInterval(int frames){
keyframeInterval = frames;
}
/**
* Returns the media type of the loaded media.
* @return IMAGE, VIDEO or UNKNOWN.
*/
public int getMediaType() {
return mediaType;
}
/**
* Returns the size (in pixels) of the media.
* @return Size in pixels.
*/
public Dimension2D getSize() {
// if (mediaType == VIDEO && videoFormat != null)
// return videoFormat.getSize();
if (mediaType == IMAGE){
return new Dimension(image.getWidth(),image.getHeight());
}
return null;
}
/**
* Returns the number of frames in the media.
* @return The number of frames of the video or 1 if mediaType == IMAGE.
*/
public int getLengthInFrames() {
if (mediaType == IMAGE) return 1;
// if (mediaType == VIDEO && videoFormat != null){
// Time duration = p.getDuration();
// if (duration == Duration.DURATION_UNKNOWN) return UNKNOWN;
// return (int) (duration.getSeconds() * videoFormat.getFrameRate());
// }
return UNKNOWN;
}
/**
* Returns the number of frames per second in the media.
* @return FPS of the video or 0 if mediaType == IMAGE.
*/
public double getFramesPerSecond() {
// if (mediaType == VIDEO && videoFormat != null)
// return videoFormat.getFrameRate();
// else
return 0;
}
/**
* Returns the colorModel currently set.
* @return RGB, YUV or UNKNOWN.
*/
public ColorModel getColorModel() {
return colorModel;
}
/**
* Sets the color model for retrieved pixels. Pixels returned are internally
* converted to the desired color model before returning them to the caller.
* @param model RGB or YUV
* @throws IllegalArgumentException If model is not RGB or YUV.
*/
public void setColorModel(ColorModel model) throws IllegalArgumentException {
colorModel = model;
}
/**
* Called by the video-controller upon state changes.
*/
/*
public void controllerUpdate(ControllerEvent evt) {
if (evt instanceof ConfigureCompleteEvent ||
evt instanceof RealizeCompleteEvent ||
evt instanceof PrefetchCompleteEvent) {
synchronized (stateSync) {
stateTransitionOK = true;
stateSync.notifyAll();
}
} else if (evt instanceof ResourceUnavailableEvent) {
synchronized (stateSync) {
stateTransitionOK = false;
stateSync.notifyAll();
}
} else if (evt instanceof EndOfMediaEvent) {
p.setMediaTime(new Time(0));
} else if (evt instanceof SizeChangeEvent) {
}
}
*/
}
/**
* A pass-through codec to access individual frames of the video.
*
* @author flo ledermann ledermann@ims.tuwien.ac.at
*/
/*
public class FrameAccessCodec implements Codec {
/ **
* Callback to access individual video frames.
* /
void accessFrame(Buffer frame) {
frameData = frame;
if (DEBUG) {
int fnum = (int)frame.getSequenceNumber();
long t = (long)(frame.getTimeStamp()/10000000f);
System.err.println("frame #: " + frame.getSequenceNumber() +
", time: " + ((float)t)/100f +
", len: " + frame.getLength());
}
}
protected Format supportedIns[] = new Format [] { new RGBFormat() };
protected Format supportedOuts[] = new Format [] { new RGBFormat() };
Format input = null, output = null;
public String getName() {
return "Frame Access Codec";
}
public void open() {
}
public void close() {
}
public void reset() {
}
/ **
* Returns the supported input formats, in our case RGB and YUV.
* /
public Format [] getSupportedInputFormats() {
return supportedIns;
}
/ **
* Returns the supported input formats, in our case RGB and YUV.
* /
public Format [] getSupportedOutputFormats(Format in) {
if (in == null)
return supportedOuts;
else {
// If an input format is given, we use that input format
// as the output since we are not modifying the bit stream
// at all.
Format outs[] = new Format[1];
outs[0] = in;
return outs;
}
}
public Format setInputFormat(Format format) {
input = format;
if (format instanceof RGBFormat) {
if (DEBUG) System.err.println("Codec Format: RGB");
}
else {
if (DEBUG) System.err.println("Format: UNKNOWN");
}
return input;
}
public Format setOutputFormat(Format format) {
output = format;
return output;
}
/ **
* Passes the data through to the output unmodified, storing the data
* in our parent class.
* /
public int process(Buffer in, Buffer out) {
// This is the "Callback" to access individual frames.
accessFrame(in);
// Swap the data between the input & output.
out.copy(in);
return BUFFER_PROCESSED_OK;
}
/ **
* No controls for this codec.
* /
public Object[] getControls() {
return new Object[0];
}
/ **
* No controls for this codec.
* /
public Object getControl(String type) {
return null;
}
}
} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -