【问题标题】:Cannot play embedded sound in a jar file无法在 jar 文件中播放嵌入的声音
【发布时间】:2013-01-17 08:58:44
【问题描述】:

我正在创建一个名为 BatteryBeeper 的个人使用软件。当充电是我设置的提醒时,它会提醒我给笔记本电脑充电。

当电量达到设定的阈值时,它应该会播放声音。

我看了答案:sound not playing in jar 和我的AudioInputStream 的构造类似于 Jigar Joshi 提到的。

但是我得到一个空异常:

java.lang.NullPointerException
    at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
    at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
    at demo.BatteryBeeper.setupSoundPlayback(BatteryBeeper.java:169)
    at demo.BatteryBeeper.<init>(BatteryBeeper.java:41)
    at demo.BatteryBeeper.main(BatteryBeeper.java:35)  

这是我加载声音的代码:

public void setupSoundPlayback(){
        try{
            buzzer = AudioSystem.getClip();
            in = AudioSystem.getAudioInputStream(BatteryBeeper.class.
                    getResourceAsStream("sound/buzzer3_x.wav"));
            buzzer.open(in);
        }catch(Exception e){
            e.printStackTrace();
        }

    }  

播放代码如下:

public void playSound(){
        buzzer.start();
    }  

是什么导致了问题?

杂项

这是一个普通的 Eclipse 项目。在src 下有一个sound 文件夹,里面有wave 文件

编辑

在AlexR的回答之后,我改变了路径,得到了一个新的异常:

javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input stream
    at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
    at demo.BatteryBeeper.setupSoundPlayback(BatteryBeeper.java:169)
    at demo.BatteryBeeper.<init>(BatteryBeeper.java:41)
    at demo.BatteryBeeper.main(BatteryBeeper.java:35)

【问题讨论】:

    标签: java nullpointerexception embedded-resource javasound


    【解决方案1】:

    你的问题不在于播放声音。您的问题在于访问嵌入式资源。当您使用BatteryBeeper.class.getResourceAsStream("sound/buzzer3_x.wav") 时,您尝试检索位于类BatteryBeeper 所在的同一包中的资源。这意味着您的文件位于/demo/sound/buzzer3_x.wav。看来这是错误的。如果您的文件确实在 sound/buzzer3_x.wav 中,请使用 getResourceAsStream("/sound/buzzer3_x.wav")(注意路径中的前导斜杠)。

    【讨论】:

    • 当我在 Eclipse 中运行文件时会播放声音,但是当我将其导出为 JAR 文件时,它不会。为什么?
    • 因为你没有正确导出。你用jar -tf 看了吗?
    【解决方案2】:

    如果您仍然收到消息“无法从 InputStream 获取 AudioInputStream”,则问题很可能是 InputStream 阶段未引发信息错误。

    如果您查看 AudioSystem.getAudioInputStream(InputStream) 的规范,您会发现输入流可能由于不支持标记/重置操作而失败,但由于某种原因,它选择抛出其他错误消息!!

    http://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/AudioSystem.html#getAudioInputStream%28java.io.InputStream%29

    更好的是,使用 AudioSystem.getAudioInputStream(URL) 格式,音频文件的可标记性不是问题,因为中间 InputStream 永远不会创建 afaik。

    http://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/AudioSystem.html#getAudioInputStream%28java.net.URL%29

    URL 表单的另一个好处是可以很好地处理嵌入在 Jar 中的文件。当然,你还是要提供正确的地址。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-20
      • 2022-06-12
      • 2011-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多