【问题标题】:Music not playing in .JAR-file音乐不在 .JAR 文件中播放
【发布时间】:2018-06-23 00:56:05
【问题描述】:

我正在尝试在打开 .JAR 文件时播放歌曲。它在 Netbeans 中运行良好,但打开 .Jar 文件时,仅显示场景更改按钮和这些场景中的图像。

在 FXML 的控制器中,我初始化了一个用于播放歌曲的线程:

@Override
public void initialize(URL url, ResourceBundle rb) {
    PlaySong ps = new PlaySong();
    Thread thread = new Thread(ps);
    thread.start();

} 

这会使用应该播放歌曲的线程调用类:

public class PlaySong implements Runnable {

@Override
public void run() {
    playSong();
}

static void playSong(){
    try{
        AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("/src/maanedsdag2/AssetsLibrary/James Smith  - Just the Way You Are.wav").getAbsoluteFile());
        Clip clip = AudioSystem.getClip();
        clip.open(audioInputStream);
        clip.start();

        Thread.sleep(clip.getMicrosecondLength()/1000);
    } catch(Exception e){

    }
}
}

我的意图是在通过初始化方法打开 FXML 时开始播放歌曲。

希望大家帮忙。

【问题讨论】:

  • 呃.. } catch(Exception e){ } 不要忽略异常!如果不记录潜在故障,至少转储堆栈跟踪。例如。 } catch(Exception e){ e.printStackTrace(); }
  • 这不是某种重复吗?试图从 jar 中打开文件的问题已经出现了无数次。文件系统不包括 jar 文件的内部。使用 URL 来处理这些资源。
  • 找到了上周的副本。我知道还有更多可以追溯到几年前。 stackoverflow.com/questions/50710703/…

标签: java jar fxml embedded-resource javasound


【解决方案1】:

您的音乐文件应位于项目的“src”文件中,以便部署在 JAR 中。你应该使用“getResourceAsStream()”来获取你的声音文件。

【讨论】:

  • 我已经把它放在了我的“AssetsLibrary”文件夹中。我应该在哪里使用 getResourceAsStream()?
  • @AlexanderMicheelsenRol 你可以试试这个:AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(this.getClass().getResourceAsStream("/" + "filepath to sound file");
  • 如果您使用 URL,getResource() 效果很好。
【解决方案2】:

当您从 IDE 启动应用程序时,您可以访问 src 文件,因为您的 JVM 执行路径是您的项目文件夹。

所以你会明白,在一个 jar 中你没有你的项目。在 Jar 中,执行路径是包含您的 jar 的文件夹,您会同意即使手动您也没有在此文件夹中找到文件夹 src?

您需要将您的音乐曲目视为资源而不是文件。我建议你阅读:Location-Independent Access to Resources.

但在你的情况下:

SomeClass.class.getResourceAsStream("relativePathfromSomeClasstoyourwavFile");

【讨论】:

  • 将 wav 文件放在根文件夹中是错误的还是应该放在 src 的某个子文件夹中?
  • 最好的做法是使用像 %mybasepackage%.ressource 这样的专用包,里面有资源库,以及使用一些静态方法(如 getMainAudioTheme())来处理资源源的类,这些方法会像这样返回您搜索的流它可以从您程序中的任何地方轻松访问(所以在 src 的子包中可以)
  • 虽然这个答案是正确的(用于加载嵌入式资源),但我有一些建议:1)“文件夹”完全是具有“窗口系统”的操作系统的概念,您所指的更准确地称为“目录”(在那些操作系统上表示为“文件夹”)。 2) Jar 中没有文件夹或目录,只有资源路径。 3)SomeClass.class 通常写成this.getClass() 更好,原因很简单,后者只能在类的实例中使用——这更有可能获得预期的上下文类加载器..
  • .. 用于应用程序资源。 SomeClass.class 版本可能会在 main(..) 方法中调用,并且可能会获得为核心 API 设计的引导类加载器。 4) "relativePath.." 不,使用"/path/from/root/of/class/path" 更安全,这样就独立于加载类的包。做到这一点的诀窍在于领先的/。 -- 话虽如此,this 部分出现在 “您需要将您的音乐曲目视为资源而不是文件。”
  • 哦,我忘记提到的一个技巧是:5)getResource(..) 用于URL 有时比getResourceAsStream(..) 用于InputStream 更安全。原因是 Java Sound(特别是)需要可重新定位的流,而来自 getResourceAsStream(..) 的流通常不需要。但是为Clip 类提供URL,它会根据需要加载资源。
【解决方案3】:

Duplicate?

操作系统文件系统不会“看到” jar 文件。改用 URL 即可。

通常使用相对寻址方案,并将音频放置在某种资源文件夹中。但是您也可以将音频放在与调用它的类相同的文件中。或者使用“绝对”地址(地址以字符“/”开头)引用项目的根目录。您的选择。

上面的“重复”标签有代码示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多