gpt4 book ai didi

java - 当我从 .jar 运行时,为什么 Java Sound 的行为不同?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:40:58 25 4
gpt4 key购买 nike

下面的 play 方法来自一个类,该类在实例化时将 .wav 文件读入名为 data 的字节数组,并将声音格式存储在 AudioFormat 对象称为 format

我有一个从 java.util.Timer 调用 play 的程序。当我进入包含所有相关 .class 文件的文件夹并使用命令 java MainClass 运行程序时,一切都按预期进行。但是,当我将所有 .class 文件放入可执行文件 .jar 并使用命令 java -jar MyProgram.jar 运行程序时,使用 play 方法播放的声音是大约 50 到 150 毫秒后切断。

public void play() throws LineUnavailableException {
final Clip clip = (Clip)AudioSystem.getLine(new DataLine.Info(Clip.class, format));
clip.open(format, data, 0, data.length);
new Thread() {
public void run() {
clip.start();
try {
Thread.sleep(300); // all sounds are less than 300 ms long
} catch (InterruptedException ex) { /* i know, i know... */ }
clip.close();
}
}.start();
}

一些评论:

  • 我已经尝试将 play 方法中的 hibernate 时间增加到 1000 毫秒,但行为没有任何变化。

  • 使用 System.nanoTimeThread.sleep 计时,确认线程的 hibernate 时间与预期的一样长。

  • 由于要播放的声音文件已预加载到内存中,我认为从 .jar 中提取声音资源的行为不会导致问题。

  • 我已经尝试使用内存池大小选项 -Xms2m-Xmx64m(分别)从 jar 内部和外部运行该程序,其中行为没有变化。

我在 Ubuntu 11.04 上运行 OpenJDK Java 6。知道发生了什么事吗?

最佳答案

我不知道这是否与问题直接相关,但每次播放那个 Clip 时都实例化一个新的 Clip 有点弄巧成拙。 Clip 的要点是无需先加载它就可以启动它。按照您当前的设置,您的 Clip 在完全加载之前不会开始播放。 (当您包括实例化步骤时,SourceDataLines 开始播放的速度比 Clips 快,因为它们不会在开始之前等待所有数据加载。)

因此,作为解决此问题的第一步,我建议在播放调用之前实例化各种剪辑。我相信如果你做对了,并且剪辑开始在它自己的线程中,它就可以运行它的过程而不需要弄乱 Thread.sleep。您只需在下一次开始之前将剪辑重新定位回其起始帧。 (可以在开始前的播放调用中完成。

一旦您对 Clip 的使用变得更加常规,就可能更容易找出是否还有其他问题。

我也不清楚为什么将源 .wav 文件作为中间步骤加载到字节数组中。不妨将它们直接加载到 Clips 中。考虑到 PCM 数据的优势,无论哪种方式,它们都会占用几乎相同的空间量,并且在您调用它们时随时准备就绪。

禁用错误消息也是弄巧成拙的。 Java 可能会尝试为您提供完美的诊断,也许不是在这个特定的 sleep 调用中(我知道,我知道),但如果您经常这样做,谁知道呢。 :)

关于java - 当我从 .jar 运行时,为什么 Java Sound 的行为不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12252053/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com