import java.awt.*;
import java.io.IOException;
import javax.media.Buffer;
import javax.media.Codec;
import javax.media.ControllerClosedEvent;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.Controls;
import javax.media.Effect;
import javax.media.EndOfMediaEvent;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoProcessorException;
import javax.media.NotConfiguredError;
import javax.media.Processor;
import javax.media.RealizeCompleteEvent;
import javax.media.Time;
import javax.media.UnsupportedPlugInException;
import javax.media.control.TrackControl;
import javax.media.format.RGBFormat;
import javax.swing.*;
public class Media11 extends JFrame implements ControllerListener {
private JPanel contentPane;
private BorderLayout bl = new BorderLayout();
Component vc = null;// 媒体播放画面组件
Component cc = null;// 媒体播放控制组件
TrackControl[] tc = null;// 各条媒体踪迹的数据控制处理对象
Processor p = null;// 媒体处理器,控制整个媒体的播放过程
public Media11(String mediaURL) {
Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, new Boolean(true));// 处理swing组件和awt组件的冲突
MediaLocator ml = new MediaLocator(mediaURL);
try {
p = Manager.createProcessor(ml);
} catch (NoProcessorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}// 根据媒体定位对象,实例化一个处理器exitProc()方法向屏幕显示信息,并退出程序
if (p == null) {
exitProc("不能创建播放器!");
}
p.addControllerListener(this);// 添加处理器的控制状态变化监听器
p.configure();// 初始化处理器的设置
while (p.getState() != p.Configured)
;
p.setContentDescriptor(null);// 如果处理器不能完成初始设置,则设置媒体上下文描述器
tc = p.getTrackControls();// 处理器得到媒体数据的所有踪迹控制处理对象
if (tc.length > 0) {
Codec[] cd = new Codec[1];
cd[0] = new NegativeEffect();// 设置媒体编码器为经NegativeEffect对象处理后的编码器
try {
tc[0].setCodecChain(cd);
} catch (UnsupportedPlugInException e) {
e.printStackTrace();
} catch (NotConfiguredError e) {
e.printStackTrace();
}// 指定一条将在每条媒体踪迹中使用的编码器插件链
}
p.realize();// 处理器进入realizing状态
}
public void controllerUpdate(ControllerEvent e) {// 如果事件是控制器关闭事件、则正常退出程序
if (e instanceof ControllerClosedEvent)
System.exit(0);
// 如果是媒体播放完毕,则重新设置媒体时间
if (e instanceof EndOfMediaEvent) {
p.setMediaTime(new Time(0));
return;
}
// 如是是Realize完成,则处理器获得可视化的播放画面组件,实例化vc对象并添加到主窗口中;同时获得播放控制组件,实例化cc对象,并添加到主窗口中
if (e instanceof RealizeCompleteEvent) {
vc = p.getVisualComponent();
if (vc != null)
this.getContentPane().add(vc, BorderLayout.CENTER);
cc = p.getControlPanelComponent();
if (cc != null)
this.getContentPane().add(cc, BorderLayout.SOUTH);
// 调整主窗口属性,并使窗口适合媒体画面大小,而不可改变
this.pack();
this.setResizable(false);
this.setVisible(true);
}
}
public void exitProc(String str) {
System.out.println(str);
System.exit(-1);
}
public static void main(String[] args) {
new Media11(ClassLoader.getSystemResource("lift.mpeg").toString());
}
}
class NegativeEffect implements Effect {
private static String EffectName = "NegativeEffect";
protected RGBFormat inputFormat;// 输入的RGB色彩格式
protected RGBFormat outputFormat;// 输出的RGB色彩格式
protected Format[] supportedInputFormats;// 所有支持的输入格式
protected Format[] supportedOutputFormats;// 所有支持的输出格式
// 构造方法,实例化所有支持的输入输出色彩为RGB色彩格式
public NegativeEffect() {
supportedInputFormats = new Format[] { new RGBFormat() };
supportedOutputFormats = new Format[] { new RGBFormat() };
}
// 实现Effect接口继承自Codec的方法,返回所有支持的输入格式
public Format[] getSupportedInputFormats() {
System.out.println("getSupportedInputFormats");
return supportedInputFormats;
}
// 实现Effect接口继承自Codec的方法,返回所有支持的输出格式
public Format[] getSupportedOutputFormats(Format parm) {
System.out.println("getSupportedOutputFormats[in = " + parm + "]");
// 如果传入的Format对象parm不是RGBFormat实例,则返回默认的RGBFormat格式对象
if (parm == null)
return supportedOutputFormats;
if (!(parm instanceof RGBFormat))
return new Format[0];
// 如果是,根据该格式返回一个对象引用
RGBFormat rf = (RGBFormat) parm;
RGBFormat rfb = (RGBFormat) parm.clone();
return new Format[] { rfb };
}
// 实现Effect接口继承自Codec的方法,返回传入的数据格式
public Format setInputFormat(Format parm) {
System.out.println("setInputFormatInput[input=" + parm + "]");
inputFormat = (RGBFormat) parm;
return (RGBFormat) inputFormat;
}
// 实现Effect接口继承自Codec的方法,返回传入的数据格式
public Format setOutputFormat(Format parm) {
System.out.println("setOutputFormat[output=" + parm + "]");
outputFormat = (RGBFormat) parm;
return (RGBFormat) outputFormat;
}
// 不一定要实现的两个方法,仅仅满足get、set的对称性
public Format getInputFormat() {
System.out.println("getInputFormat");
return inputFormat;
}
public Format getOutputFormat() {
System.out.println("getOutputFormat");
return outputFormat;
}
// 实现Effect接口自Codec的方法,处理输入的媒体数据parm,得到经处理的输出的媒体数据parm,该方法完成本类的效用,处理媒体数据,达到使色彩反色输出的处理效果是本类的核心方法
public int process(Buffer parm1, Buffer parm2) {
Object o = parm1.getData();// 获得输入的数据对象的引用
int inLength = parm1.getLength();// 输入的数据的长度
int inOffset = parm1.getOffset();// 偏移量
// 如果输入输出的媒体数据非合法的short[]int[]形式,返回出错信息
if (!(o instanceof short[]) && !(o instanceof int[]))
return this.BUFFER_PROCESSED_FAILED;
Object oo = parm2.getData();
if (oo != null) {
if (!(oo instanceof short[]) && !(oo instanceof int[]))
return this.BUFFER_PROCESSED_FAILED;
} else {
// 根据输入的数据长度,设置输出的数据长度
if (o instanceof short[])
parm2.setData(new short[inLength]);
else
parm2.setData(new int[inLength]);
oo = parm2.getData();
}
// 根据输入的数据偏移量,设置输出的数据偏移量
int outOffset = parm2.getOffset();
if (o instanceof short[]) {
short[] inData = (short[]) o;
short[] outData = (short[]) oo;
// 处理输入的媒体数据,将色彩取反,并将数据放入输出的媒体数据对象中
for (int i = 0; i < inLength; i++)
outData[outOffset++] = (short) -inData[inOffset++];
} else {
int[] inData = (int[]) o;
int[] outData = (int[]) oo;
for (int i = 0; i < inLength; i++)
outData[outOffset++] = -inData[inOffset++];
}
// 设置输出媒体数据的格式
parm2.setFormat(outputFormat);
// 设置输出媒体数据的长度和偏移
parm2.setLength(inLength);
parm2.setOffset(0);
// 返回数据处理成功完成信息
return this.BUFFER_PROCESSED_OK;
}
// 返回类名
public String getName() {
System.out.println("getName");
return EffectName;
}
// 以下的方法不一定要求实现,这些方法是Effect接口的父类的上层类
public void open() {
System.out.println("open");
}
public void close() {
System.out.println("close");
}
public void reset() {
System.out.println("reset");
}
public Object[] getControls() {
System.out.println("getControls");
return new Controls[0];
}
public Object getControl(String parm1) {
System.out.println("getControl[controlType=" + parm1 + "]");
Class clas = null;
try {
Object[] cs = this.getControls();
for (int i = 0; i < cs.length; i++) {
if (clas.isInstance(cs[i])) {
return cs[i];
}
}
clas = Class.forName(parm1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}