Java应用程序中的声音播放
声音可以创造意境,触发遐想,当与虚拟图像相结合时,更加可以让整个世界充满幻觉,声音是多媒体技术的基础。
播放声音是Java对多媒体的支持一个重要部分,它支持的声音文件类型主要有:
AU - (扩展名为AU或SND)适用于短的声音文件。
WAV - (扩展名为WAV)由 Microsoft和 IBM共同开发,几乎能被所有支持声音的Windows应用程序播放。
AIFF - (扩展名为AIF或IEF)音频互换文件格式是为Macintosh计算机和Silicon Graphics (SGI)计算机所共用的标准音频文件格式。
MIDI - (扩展名为MID)乐器数字接口MIDI是为音乐制造业所认可的标准,主要用于控制诸如合成器和声卡之类的设备。
那么在Java应用程序中,如何实现声音文件的播放呢?
sun公司为应用程序中的声音支持提供了一个Java包 – sun.audio,在这个包下面提供了大部分所需要的声音处理类。
下面我们来做个播放测试:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import sun.audio.*;
/**
* 测试声音播放
*
* @author
*
*/
public class MusicDemo {
public static void main(String[] args) throws Exception {
// 创建音乐文件输入流对象
InputStream in = new FileInputStream("musics/flourish.mid");
// 创建音频流对象
final AudioStream audioStream = new AudioStream(in);
new Thread(new Runnable() {
@Override
public void run() {
// 使用音频播放器播放声音
AudioPlayer.player.start(audioStream);
}
}).start();
Thread.sleep(3000);
// 停止声音播放
AudioPlayer.player.stop(audioStream);
}
}
打开扬声器,你就可以听到声音了,播放3秒后停止声音的播放。
注意:
我们在Eclipse中进行代码编写时,可能会出现类似 “The type ‘AudioStream’ is not API” 的错误提示。在Eclipse中,我们可以查看到AudioStream类位于rt.jar包中的sun.audio包中。
为什么Eclipse会提示我们 “The type ‘AudioStream’ is not API” 这钟错误呢,实际上这是Eclipse的设置导致的问题。
要解决这种错误,我们只需要将Eclipse的设置稍微修改一下即可:在preference->java->complier->errors/warning->deprecated and restricted API 中把 Forbidden reference 的Error改成warning 即可。
根本原因如下:
J2SE中的类大致可以划分为以下的各个包:java.*,javax.*,org.*,sun.*。除了“sun”包,其它各个包都是Java平台的标准实现,并且今后也将被继续支持。一般说来,“sun”之类的包并不包含在Java平台的标准中,它与操作系统相关,在不同的操作系统(如Solaris,Windows,Linux,Mac等等)中的实现也各不相同,并且可能随着J2SE版本不定期变化。因此,直接调用“sun”包的程序代码并不是100%的Java实现。
也就是说:java.*,javax.*,org.*包是作为J2SE的API公开接口的一部分,如果程序直接调用这些包中的API,那么程序是可以运行在所有Java平台上,而与操作系统无关;但sun.*包并不是API公开接口的一部分,调用“sun”包的程序并不能确保工作在所有Java平台上,事实上,这样的程序可能并不能工作在今后的Java平台上。
正因为如此,sun.*包中的类并没有提供API文档。平台无关性是Java语言最大的优势之一,此外,SUN和Java许可证确保维持了今后API的向上兼容性(以后修改的那些有严重bug的代码除外)。这种兼容性意味着你写好的程序编译成的class文件仍然可以工作在将来的版本当中。
每家实现Java平台的厂商都可以使用他们自己的方式。sun.*包中的类是SUN 对Java平台的实现方式,它们工作在Java2 SDK的下层,这些类未必被其它Java平台开发商支持。比如你的Java程序如果调用了一个名为“sun.package.Foo”的类,将有可能产生“ClassNotFoundError”的错误,同时你也将失去利用Java的一个主要的优点。
从技术上讲,并不能防止你的程序调用sun.*包中的类。在版本的变迁当中,这些类可能会被删除或转移到其它包路径下,而且它的接口(包括名称、标签等)也很有可能发生变化,(根据SUN的观点,我们应当能够通过对sun.*包的修改来提高Java平台的性能。)在这种情况下,即便你希望程序仅仅运行在SUN的实现平台下,你仍将承受新的版本给你的系统带来破坏的风险。总之,编写依赖于sun.*包的Java程序是不安全的,他们将变得无法移植,无法被很好地支持。