如何在java中播放声音:Clip和AudioSystem的使用。以java程序定时播放音乐为例

例一:java程序定时播放音乐:

public static void main(String[] args) {
        play(XXXapplication.class.getResourceAsStream("/file/开始.wav"), 0, 3);
}

public static void play(InputStream filePath, int min, int sec){
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(filePath));
        AudioFormat format = audioInputStream.getFormat();
        if (!AudioSystem.isLineSupported(new DataLine.Info(Clip.class, format))) {
            System.err.println("Line not supported for this audio format.");
        } else {
            Clip clip = AudioSystem.getClip();
            clip.open(audioInputStream);
            clip.start();
            Thread.sleep(((long) min * 60L + (long) sec) * 1000L);
            clip.close();
        }
    }

 例二:实现检测音乐播放完自动关闭clip并执行后续代码(与例一区别为不需要传参"音乐完成的时间"):

    public static void play(InputStream in){
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(in));
        AudioFormat format = audioInputStream.getFormat();
        if (!AudioSystem.isLineSupported(new DataLine.Info(Clip.class, format))) {
            System.err.println("Line not supported for this audio format.");
        } else {
            Clip clip = AudioSystem.getClip();
            clip.open(audioInputStream);

            // 获取音频格式
            AudioFormat audioFormat = audioInputStream.getFormat();
            // 获取帧长度(如果可用)
            long frameLength = audioInputStream.getFrameLength();

            // 如果音频流没有指定帧长度,则需要找到音频文件的总字节数
            if (frameLength == AudioSystem.NOT_SPECIFIED) {
                frameLength = audioInputStream.getFrameLength() * audioFormat.getFrameSize();
            }

            // 计算总播放时间(秒)
            float frameRate = audioFormat.getFrameRate();
            // 秒
            float totalSeconds = frameLength / frameRate;

            clip.start();
            //开始后睡眠播放时间秒
            Thread.sleep((long) (totalSeconds * 1000L));
            //关闭
            clip.close();
        }

代码解释:

        1.play为我定义的一个方法,该方法的三个参数分别表示:播放的文件流,要延迟多长分钟时间退出play函数,要延迟多长秒钟时间退出play函数。

        2.我们在play内通过AudioSystem.getAudioInputStream();来获取一个音频输入流,然后再创建一个clip对象,通过clip的open方法,把该流放入clip,此时调用clip的start方法就可以播放音乐。只不过在这中间,对该流读取的文件格式进行判断,看看是不是clip支持播放的格式。

需要注意的问题:

        1.java支持的音频格式:默认情况下,Java只支持如WAV,AIFF,AU等格式的音频,你可以引入第三方jar来获得更多支持格式。注意,默认情况下不支持mp3,所以需要使用wav等格式音频。否则按以上代码会输出:Line not supported for this audio format.

        2.clip.start是异步方式,也就是说,主线程还会继续往后执行,所以如果不在clip.start和clip.close中间加入sleep函数的话,音乐不会播放,因为立马就会被关闭,所以要给定一些睡眠时间。

        3.关于代码中,AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(filePath));

注意,不能改为AudioInputStream audioInputStream = AudioSystem.getAudioInputStream( filePath);这样会报错不支持mark和reset。原因是我们通过getResourceAsStream得到的流是一个抽象类InputStream,而音频输入流需要用到mark和reset这两个方法,而inputstream不支持这两个方法,而BufferedInputStream支持,所以需要先转为BufferedInputStream在调用getAudioInputStream。

这是官方对BufferedInputStream的解释:BufferedInputStream向另一个输入流添加功能 - 即缓冲输入并支持markreset方法的功能。 创建BufferedInputStream将创建内部缓冲区阵列。 当读取或跳过来自流的字节时,内部缓冲区根据需要从包含的输入流中重新填充,一次多个字节。 mark操作会记住输入流中的一个点,并且reset操作会导致在从包含的输入流中获取新字节之前重新读取自最近的mark操作以来读取的所有字节。


        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值