【问题标题】:Path to read a sound out of my package从我的包裹中读取声音的路径
【发布时间】:2014-04-13 10:38:16
【问题描述】:

我有一个加载和播放声音的 Sons 类。还有一个包含主类并使用这个 Sons 类的 adhd 类。

我所有的课程都在“adhd”包中,而我在 jar 中的声音是这样的:1.wav 在 jar 中的 SoundN 中。 (ADHD.jar/SoundN/1.wav)。

当我在 Eclipse 中运行代码时,它可以工作,但是当我运行 jar 时,它不会。保持声音“加载”对我来说很重要,因为我需要我的程序快速读取我的声音,因为我正在使用计时器。你建议我怎么做?

这是我的 Sons 类的代码,它在单例实例中加载声音。

儿子

package adhd;

import java.io.File; 
import java.io.IOException; 
import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioInputStream; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.FloatControl; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 
import javax.sound.sampled.UnsupportedAudioFileException;
import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class Sons {
    private static String PATH=null;
    private static Sons instance;
    private final Map<String, Clip> sons;
    private boolean desactive;

    Sons(String path) {
        PATH = path;
        sons = new HashMap<String, Clip>();
    }


    public void load(String nom) throws UnsupportedAudioFileException, IOException, LineUnavailableException {
        Clip clip = AudioSystem.getClip();
        clip.open(AudioSystem.getAudioInputStream(getClass().getResourceAsStream(PATH + nom)));
        sons.put(nom, clip);
    }


    public void play(String son) {
        if(!desactive) try {
            Clip c = getSon(son);
            c.setFramePosition(0);
            c.start();
        } catch(Exception e) {
            System.err.println("Impossible to play the sound " + sound);
            desactive = true;
        }
    }
}

这里是包含主要使用声音的 adhd 类

主类:adhd

public static void main(String[] args) {

    Sons sonN= new Sons("/SoundN/");

    try {
        sonN.load("1.wav");
    } catch (UnsupportedAudioFileException | IOException
            | LineUnavailableException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    sonN.play("1.wav");
}

这也是树的图片

【问题讨论】:

  • 路径显然取决于声音文件的位置。你不说,我们怎么知道?没有神奇的路径可以“从你的包裹中”找到所有东西,不管这意味着什么。
  • 我只是在等你给我开路。假设我的文件位于主项目文件夹中。在根目录中。
  • 也许我会告诉你我为什么要问。因为当我想访问我的类包中文件夹“sounds”中的声音时,我必须编写“/sounds/1.wav”。而且我需要 jar 来读取我的声音,所以我被告知将它们放入源文件夹中。所以当我这样做时,我有一个名为“src/sounds”的文件夹,它本身就在项目文件夹中。但我找不到如何访问它,甚至找不到位于项目文件夹(项目根目录)中的声音。
  • Class.getResourceAsStream() 使用类路径来加载资源。它不能加载不在类路径中的目录或 jar 之外的任何内容。如果声音在类路径中的目录/jar 中,则使用stackoverflow.com/a/23041578/571407 中描述的规则加载它。否则,使用文件 IO。
  • 问题是我真的需要使用这种方法,因为我想在实例中加载我的声音以便在程序中读取它们(否则会出现错误,因为我使用每 0.5 秒读取一次声音的计时器) .或者我怎样才能让我的 jar 读取包中的声音?有解决办法吗? (我可以在 Eclipse 中读取它们,但在运行 jar 时不能)。

标签: java audio clip


【解决方案1】:

现在,多亏了异常消息,我们才知道问题究竟出在哪里。问题不在于无法加载声音或在 jar 中找不到声音。问题在于,正如the javadoc 所说:

这些解析器必须能够标记流,读取足够的数据以确定它们是否支持流,如果不支持,则将流的读取指针重置为其原始位置。如果输入流不支持这些操作,此方法可能会失败并返回 IOException。

Class.getResourceAsStream()返回的流,当资源从jar加载时,不支持这些操作。所以你可以做的是将输入流中的所有内容读入内存中的字节数组,从这个字节数组创建一个ByteArrayInputStream,然后将该流传递给AudioSystem.getAudioInputStream()

如果由于声音很长而无法将所有内容加载到内存中(但我想您不会将其放入 jar 中),那么您可以将其写入临时文件,然后将 FileInputStream 传递给AudioSystem.getAudioInputStream().

【讨论】:

  • 请问您有这两个选项的示例,怎么做?这实际上是我第一次在 java 中操作声音。
  • 这与声音无关。您读取输入流的所有字节,然后创建一个 ByteArrayInputStream。阅读 javadoc 和 java IO 教程。
  • 我通过例子理解得更好,这就是我问的原因。这是我必须做的吗? stackoverflow.com/questions/15725871/…
  • 如果您在谈论答案中的代码,那么是的。
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 2023-03-23
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多