今天在利用JAVA3D播放声音的时候,碰到一个很奇怪的问题,那就是声音设备无法初始化。它抛出如下异常:
java.lang.UnsupportedOperationException: No AudioDevice specified
但是教程上面包括SUN的例子里面都是这样写的,他那样写肯定有它的道理,他不可能写一个错误的代码吧?那心里就纳闷了,为什么我的电脑就是播放不了呢,难道又像播放MIDI一样,因为装了JMF的原因?我把JMF也缷了,电脑也重启了,还是不行,该不会是人品问题吧:(
后来查看错误的调用顺序,发现是这句话抛出了异常:
......
viewer.createAudioDevice();
......
也就是在生成音频设备的时候,这个方法会生成并初始化好音频设备,我们在播放音频的时候,一定需要调此方法的。
然后再看这句话里面的代码,说到这里,突然觉得用JAVA挺爽的,可以看到你用的类的JAVA的源码,Viewver是JAVA3D里面的类,查看这个方法,发现这个方法如下:
public AudioDevice createAudioDevice() {
if (physicalEnvironment == null) {
System.err.println("Java 3D: createAudioDevice: physicalEnvironment is null");
return null;
}
try {
String audioDeviceClassName =
(String) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
return System.getProperty("j3d.audiodevice");
}
});
if (audioDeviceClassName == null) {
throw new UnsupportedOperationException("No AudioDevice specified");
}
// Issue 341: try the current class loader first before trying the
// system class loader
Class audioDeviceClass = null;
try {
audioDeviceClass = Class.forName(audioDeviceClassName);
} catch (ClassNotFoundException ex) {
// Ignore excpetion and try system class loader
}
if (audioDeviceClass == null) {
ClassLoader audioDeviceClassLoader =
(ClassLoader) java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction() {
public Object run() {
return ClassLoader.getSystemClassLoader();
}
});
if (audioDeviceClassLoader == null) {
throw new IllegalStateException("System ClassLoader is null");
}
audioDeviceClass = Class.forName(audioDeviceClassName, true,
audioDeviceClassLoader);
}
Class physEnvClass = PhysicalEnvironment.class;
Constructor audioDeviceConstructor =
audioDeviceClass.getConstructor(new Class[] {physEnvClass});
PhysicalEnvironment[] args = new PhysicalEnvironment[] { physicalEnvironment };
AudioEngine3DL2 mixer =
(AudioEngine3DL2) audioDeviceConstructor.newInstance((Object[])args);
mixer.initialize();
return mixer;
}
catch (Throwable e) {
e.printStackTrace();
physicalEnvironment.setAudioDevice(null);
System.err.println("Java 3D: audio is disabled");
return null;
}
}
然后再细看异常是在
if (audioDeviceClassName == null) {
throw new UnsupportedOperationException("No AudioDevice specified");
}
这一句抛出来的,而audioDeviceClassName 是通过System.getProperty("j3d.audiodevice");来获得的,之所以会抛出这个异常,还是因为系统没有j3d.audiodevice的属性,后来我输出System的所有Properties看了一下,果然没有j3d.audiodevice的属性,那就怪了,为什么我的电脑会没有这个属性呢?
后来才知道,本来这个属性装了JAVA3D以后都会有的,但是由于JAVA3D1.3发现了一个BUG,一个播放声音的BUG,所以在后续的版本中把这个属性去掉了,也就是不再让人用JAVA3D来播放声音了。我用的是JAVA3D1.5,所以就没有这个属性了,所以音频设备也就初始化不了了。
那怎么样呢?JAVA不装这个属性,我们自己指定就是了,于是在viewer.createAudioDevice();代码调用之前,我调用如下代码为它设置这个属性,让它可以自己找到音频播放设备:
System.setProperty("j3d.audiodevice", "com.sun.j3d.audioengines.javasound.JavaSoundMixer");
这样就好了,我们在播放的时候,使用的就是com.sun.j3d.audioengines.javasound.JavaSoundMixer来播放了,不过,因为有BUG的报道,所以用它播放可能会出现一些问题,听说现在JOAL正在努力解决这个问题。让我们共同期待吧。
JOAL的地址:https://joal.dev.java.net
JOGL的地址:https://jogl.dev.java.net
尽管千里冰封
依然拥有晴空
你我共同品味JAVA的浓香.
posted on 2007-10-06 09:02
千里冰封 阅读(2018)
评论(8) 编辑 收藏 所属分类:
JAVA扩展