整理 Java I/O (六):音频输入流 - AudioInputStream

我们的程序往往需要播放一些音效,Java 提供了 AudioInputStream 类来帮助我们读取声音档案,但是该类支持的格式甚少,只支持 WAV、AIFF、AU 等PCM(Pulse-code modulation)格式的文件,如果要播放例如 MP3 等格式的文件的话,可以使用 JavaFX 提供的 MediaPlayer 或 AudioClip 或者其他第三方类库。

可以通过 AudioSystem 的 getAudioInputStream 方法来获取到 AudioInputStream,由于 AudioInputStream 只是一个输入流,并没有播放声音的功能,只是包含了音频的格式和长度,播放声音需要通过 AudioInputStream 对象的 AudioFormat 来创建一个 DataLine.Info 对象,然后根据 AudioFomart 来获取 SourceDataLine,这样扬声器有了 SourceDataLine 就有了数据流,扬声器就可以发声了。

SourceDataLine 就像一个管道一样,数据流从计算机内部的音频文件中流到 AudioSystem 音频系统中,line.open()打开管道入口,line.start()打开管道出口,line.drain()将管道出口端导入另一个地方将管道中剩余的数据流放空,line.close()关闭管道的出口。

AudioSystem 类包含许多操作 AudioInputStream 对象的方法。例如,这些方法可以让您:

  • 从外部音频文件、流或 URL 获得音频输入流

  • 从音频输入流写入外部文件

  • 将音频输入流转换为不同的音频格式

关于Java sound的更多内容,请查看:
java sound初探 - weidiao - 博客园
Java如何播放聲音? - Magic Len

简单示例:

public class AudioInputStreamTest {
    public static void main(String[] args) {
        new AudioInputStreamTest().player(new File("D:\\李宗盛 - 山丘.wav"));
    }

    private void player(File file) {
        try {
            AudioInputStream audioInputStream = AudioSystem
                    .getAudioInputStream(file);

            System.out.println("此音频的格式为:" + audioInputStream.getFormat()
                    + "\n此音频的流长度为:" + audioInputStream.getFrameLength()
                    + "帧\n此文件共有 " + file.length() + " 字节");

            AudioFormat format = audioInputStream.getFormat();
            DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
            SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
            line.open();
            line.start();
            int length = 0;
            byte[] buffer = new byte[512];
            while ((length = audioInputStream.read(buffer)) != -1) {

                // if (audioInputStream.available() > 8459032) {
                // audioInputStream.skip(length);
                // continue;
                // }
                NumberFormat numberFormat = NumberFormat.getInstance();
                numberFormat.setMaximumFractionDigits(2);
//              System.out
//                      .println(numberFormat.format(((float) file.length() - (float) audioInputStream
//                              .available()) / (float) file.length() * 100)
//                              + "%");

                line.write(buffer, 0, length);
            }
            line.drain();
            line.close();
            audioInputStream.close();

        } catch (UnsupportedAudioFileException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (LineUnavailableException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
Copyright© 2020-2022 li-xyz 冀ICP备2022001112号-1