我读过很多关于这个主题的 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 方法将返回一个 URL
。 getResourceAsStream 方法将返回一个 InputStream
。
我更喜欢使用 URL 形式,因为它更宽容。使用AudioSystem.getAudioInputStream(InputStream)时,如果文件不支持标记和重置,将会返回IOException
>。 AudioSystem.getAudioInputStream(URL) 方法规避了这一要求。
此外,您应该知道 URL
与 File
不同,可用于标识 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();
}
虽然这个示例应该可以工作,但它不应该在生产中按原样使用,原因有两个。
Thread.sleep()
命令会暂停主线程,这通常既不理想也不需要。系统为Clip
播放创建的线程是 daemon线。 守护进程线程不会阻止程序完成和关闭。在这个简单的“即发即忘”示例中,主线程很快完成,因此如果我们不通过 sleep 间隔来推迟完成,程序将立即关闭。Clip
的初始加载和Clip
的播放通常通过两种单独的方法完成。Clip
专为可以方便地保存在内存中的音频而设计,无需重新加载即可重播。如果您使用每个播放命令重新加载Clip
,您将重做不需要的工作并增加延迟,因为剪辑在完全加载之前不会开始播放。如果音频文件不方便保存在内存中(例如,由于持续时间较长而导致文件较大),首选方法是使用SourceDataLine
来播放它。
关于java - 使用 java.sound.sampled.Clip 播放声音文件的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61481941/