在intellij idea创建的jar文件中播放.wav时出现问题

n7taea2i  于 2021-07-03  发布在  Java
关注(0)|答案(2)|浏览(532)

如果之前有人问过这个问题,我很抱歉,但我找不到一个对我们有用的答案。我也是一个初学者,所以请容忍我。
基本上,在我们的代码不和谐的音频停止工作。

clip = AudioSystem.getClip();
             File file = new File(musicLocation);
             clip.open(AudioSystem.getAudioInputStream(file.getAbsoluteFile()));
             clip.start();

我尝试过使用getresourceasstream和getresource,因为文件在jared时显然不能正常工作,但即使在intellij中也不能正常工作。
我的代码位于src文件夹中,音乐位置被传递给代码,如下所示:

filepath = "src/Images/music/click.wav"; 
musicObject.playMusic(filepath);

图像在jar文件中正常工作。
编辑:jar文件似乎无法获取音频文件,这些文件位于另一个正在访问的文件夹中,因为删除.wav文件后jar的文件大小不会改变。
编辑2:

public class Music {
    Clip loop;
    void loopMusic(String musicLocation) {
        try {
            loop = AudioSystem.getClip();
            InputStream is = getClass().getResourceAsStream(musicLocation);
            AudioInputStream audioS = AudioSystem.getAudioInputStream(is);
            loop = AudioSystem.getClip();
            loop.open(audioS);
            loop.start();
            loop.loop(Clip.LOOP_CONTINUOUSLY);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
    void stopLoop(){
        if (loop != null) {
            loop.stop();
            loop.close();
        }
        loop=null;
    }
}

这就是我们正在尝试使用的coe。musiclocation字符串以以下格式传递: /folder/file.wav 通过winrar将.wav文件手动放入jar后,仍然无法加载jar文件中的音乐。
编辑3:尝试使用url类,收到nullpointerexception

URL musicLocation = this.getClass().getResource("/Images/music/battle.wav");
AudioInputStream inputStream = AudioSystem.getAudioInputStream(musicLocation);

当作为位置名前面带有“src”的文件传入audioinputstream时,它不会传递null。
编辑4:尝试将url类与音乐类包中文件夹内的文件一起使用

URL musicLocation = this.getClass().getResource("audio/battle.wav");
AudioInputStream inputStream = AudioSystem.getAudioInputStream(musicLocation);

如果上面的音频文件夹位于classes(包含所有的.java文件)包中,则返回nullpointerexception。在前面添加了一个“classes/”之后,将鼠标悬停在我的ide中的字符串上,可以让我“看到”文件的源代码是否正确(如果愿意的话),但它仍然会向.wav文件返回一个nullpointerexception。
编辑5:在实现phil的代码后接收到这个错误

Exception in thread "main" java.lang.ExceptionInInitializerError
    at Classes.Frame.<init>(Frame.java:15)
    at Classes.GraphicsRunner.main(GraphicsRunner.java:15)
Caused by: java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:222)
    at java.desktop/javax.sound.sampled.AudioSystem.getAudioInputStream(AudioSystem.java:1032)
    at Classes.Music.<init>(Music.java:16)
    at Classes.Panel.<clinit>(Panel.java:24)
    ... 2 more

编辑6:显示导致上述错误的类

package Classes;

import javax.sound.sampled.*;
import javax.swing.*;
import java.io.*;
import java.net.URL;

public class Music {
    Clip clip;

    // Constructor, create looping audio resource, hold in memory.
    public Music() {
        URL url = this.getClass().getResource("audio/battle.wav");
        AudioInputStream ais;
        try {
            ais = AudioSystem.getAudioInputStream(url);
            //line 16 above 
            DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
            clip = (Clip) AudioSystem.getLine(info);
            clip.open(ais);
        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
            e.printStackTrace();
        }
    }

    public void play() {
        clip.setFramePosition(0);
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }
}

编辑7:phils将项目移动到eclipse时使用的相同代码集。我仍然不确定为什么它在intellij中不起作用,但我的问题还是解决了。感谢所有提供帮助的人!

pes8fvy9

pes8fvy91#

首先,检查资源是否是 Classpath . 像does这样的人应该做这项工作:

InputStream in = getClass().getResourceAsStream("/path/click.wav");                     
InputStream buffS = new BufferedInputStream(in);
AudioInputStream audioS = AudioSystem.getAudioInputStream(buffS);
Clip clip = AudioSystem.getClip();
clip.open(audioS);
clip.start();
bwntbbo3

bwntbbo32#

这个 java.io.File 对象不是寻址打包在jar中的文件的好选择。我不知道正确的技术方法来解释这一点,但在简单的语言中,它只能处理文件夹中的文件。它不能在jar文件中“查看”。
因此,更常见的做法是通过获取 URL 使用 Class.getResource 方法。一 URL 可以识别已压缩且位于jar中的文件。
还可以使用 .getResourceAsStream 方法。此方法返回 InputStream ,不是 URL . 但这是一个更艰难的选择。如果你在api中看到 AudioSystem.getAudioInputStream ,并比较版本,您将看到如果参数是 InputStream ,将对文件进行测试,以确定是否支持“标记”和“重置”。相当数量的音频文件没有通过这些测试。因此,将该方法与 URL 争论。
在中如何提供文件名也会出现问题 getResource 方法,但通常如果名称字符串在daw中起作用,它也会在jar中起作用(假设您获得的是url而不是文件)。“相对”和“根”寻址的细节不是最容易解释的。但如果需要我们可以去那里。
编辑:故障排除的代码示例。

public class Music {
    Clip clip;

    // Constructor, create looping audio resource, hold in memory.
    public Music() {
        URL url = this.getClass().getResource("audio/battle.wav");
        AudioInputStream ais;
        try {
            ais = AudioSystem.getAudioInputStream(url);
            DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
            clip = (Clip) AudioSystem.getLine(info);
            clip.open(ais);
        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
            e.printStackTrace();
        }
    }

    public void play() {
        clip.setFramePosition(0);
        clip.loop(Clip.LOOP_CONTINUOUSLY);
    }    
}

代码采用以下文件夹结构:

/src/.../folderwithMusic/Music
/src/.../folderwithMusic/audio/battle.wav

请注意,文件名区分大小写。url的null值表示文件不在预期位置。首先让它在ide中工作,可能更喜欢使用控制台或文件资源管理器来验证文件结构和文件位置。
如果您尝试运行上面的代码时遇到问题,那么输入的代码和堆栈跟踪将非常有用。

相关问题