java - 使用 java.sound.sampled.Clip 播放声音文件的正确方法是什么

标签 java file audio jar nullpointerexception

我读过很多关于这个主题的 SoF 主题和其他网站,但没有一个适合我,所以我再次询问,希望得到量身定制的答案。

我的 jar 中有一个 .WAV 文件,我想播放它,但我收到了 NullPointerException。 我尝试了很多方法,甚至通过绝对路径播放jar外的文件,但我得到了相同的结果。 这是播放声音的函数

public void gimli(){
        try {
            Clip clip;
             AudioInputStream  stream = AudioSystem.getAudioInputStream(this.getClass().getResource(Utils.class.getResourceAsStream("gimlilaught.wav").toString()));
   AudioFormat format = stream.getFormat();
    DataLine.Info info = new DataLine.Info(Clip.class, format);
  clip = (Clip)AudioSystem.getLine(info);
    clip.open(stream);
    clip.start();
}catch(Exception ex){
ex.printStackTrace(System.out);
}

感谢您的尝试。

最佳答案

需要一个AudioInputStream作为打开Clip的参数。查看 API,您将看到 AudioSystem.getAudioInputStream(InputStream)AudioSystem.getAudioInputStream(URL)可用于获取AudioInputStream。

Class 有两种服务:getResource(String)getResourceAsStream(String)getResource 方法将返回一个 URLgetResourceAsStream 方法将返回一个 InputStream

我更喜欢使用 URL 形式,因为它更宽容。使用AudioSystem.getAudioInputStream(InputStream)时,如果文件不支持标记重置,将会返回IOException >。 AudioSystem.getAudioInputStream(URL) 方法规避了这一要求。

此外,您应该知道 URLFile 不同,可用于标识 jar 内的文件。

设置相对地址时还必须小心。我通常喜欢有一个 /res 文件或 /audio 文件来保存要加载的 .wav。例如,如果 /res 是并行文件夹,则可以使用“../res/myAudio.wav”,或者“res/myAudio.wav” >"如果 /res 是子文件夹,相对于 getResource 方法中使用的类的位置。

这是一个简单的工作示例,其中音频文件位于子文件夹 /res 中:

private static void loadAndPlayClip() throws UnsupportedAudioFileException, 
        IOException, LineUnavailableException, InterruptedException
{
    String filename = "a3.wav";
    URL url = BasicClipExample.class.getResource("res/" + filename);
    AudioInputStream ais = AudioSystem.getAudioInputStream(url);
    DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
    Clip clip = (Clip) AudioSystem.getLine(info);
    clip.open(ais);

    clip.start();
    Thread.sleep(7000); // Duration should match length of audio file.
    clip.close();
}

虽然这个示例应该可以工作,但它不应该在生产中按原样使用,原因有两个。

  1. Thread.sleep() 命令会暂停主线程,这通常既不理想也不需要。系统为 Clip 播放创建的线程是 daemon线。 守护进程线程不会阻止程序完成和关闭。在这个简单的“即发即忘”示例中,主线程很快完成,因此如果我们不通过 sleep 间隔来推迟完成,程序将立即关闭。

  2. Clip 的初始加载和 Clip 的播放通常通过两种单独的方法完成。 Clip 专为可以方便地保存在内存中的音频而设计,无需重新加载即可重播。如果您使用每个播放命令重新加载 Clip,您将重做不需要的工作并增加延迟,因为剪辑在完全加载之前不会开始播放。如果音频文件不方便保存在内存中(例如,由于持续时间较长而导致文件较大),首选方法是使用 SourceDataLine 来播放它。

关于java - 使用 java.sound.sampled.Clip 播放声音文件的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61481941/

相关文章:

java - eclipse 将 Java 代码样式设置存储到什么文件?

java - 线程 "main"java.lang.NoClassDefFoundError : org/kie/api/KieServices$Factory with Drools version 7. 59.0 中的依赖关系异常问题

python - 使用Python复制目录结构

java - 在本地安全地保存密码java?

php 文件将内容反转

javascript - 有没有办法找出声音何时停止在 Javascript 中播放?

java - 使用 InputListener 检测滚动

java - 根据 JList 值将 JButton 动态添加到 JPanel

html - 播放声音的最有效方法(一页中有许多播放按钮)

ios将音视频url保存到文档目录