gpt4 book ai didi

java - Windows 7 上的 Java 是否支持任何声音格式?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:53:17 25 4
gpt4 key购买 nike

我们会的,我一直在用头撞墙试图让 Java 播放一些简单的 wav 文件,但没有任何运气。我试过这段代码:

Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(soundBytes));
clip.open(inputStream);
clip.start();

这在“clip.open(...)”上失败,异常:

javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.

我试过更复杂的(流媒体版本):

int BUFFER_SIZE = 128000;
AudioInputStream audioStream = null;
AudioFormat audioFormat;
SourceDataLine sourceLine = null;

try {
audioStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(soundBytes));
} catch (Exception e){
e.printStackTrace();
}

audioFormat = audioStream.getFormat();

DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
try {
sourceLine = (SourceDataLine) AudioSystem.getLine(info);
sourceLine.open(audioFormat);
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}

sourceLine.start();

int nBytesRead = 0;
byte[] abData = new byte[BUFFER_SIZE];
while (nBytesRead != -1) {
try {
nBytesRead = audioStream.read(abData, 0, abData.length);
} catch (IOException e) {
e.printStackTrace();
}
if (nBytesRead >= 0) {
@SuppressWarnings("unused")
int nBytesWritten = sourceLine.write(abData, 0, nBytesRead);
}
}

sourceLine.drain();
sourceLine.close();

这在“sourceLine.open(...)”上也失败了,异常是:

javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.

我尝试了两种不同的 wav 文件,包括 C:\Windows\Media 中的古老的“tada.wav”。

我还使用 GoldWave 将其中一个文件更改为无符号 8 位单声道,但这只是将错误消息更改为:

javax.sound.sampled.LineUnavailableException: line with format PCM_UNSIGNED 44100.0 Hz, 8 bit, mono, 1 bytes/frame,  not supported.

关于我可能哪里出错的任何想法?似乎播放一个简单的 wave 文件应该很简单,所以我猜我在某个地方迷路了。

提前致谢。

更新

所以,情节变厚了。如果我们将它移到一个单独的独立 java 程序中,代码就可以正常工作。我们的应用程序中一定有什么东西在破坏 Java 播放声音的能力。

这是上述错误的堆栈跟踪:

javax.sound.sampled.LineUnavailableException: line with format PCM_UNSIGNED 44100.0 Hz, 8 bit, mono, 1 bytes/frame,  not supported.
at com.sun.media.sound.DirectAudioDevice$DirectDL.implOpen(DirectAudioDevice.java:492)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:107)
at com.sun.media.sound.AbstractDataLine.open(AbstractDataLine.java:139)
at com.hcs.orc.detail.SoundAddEdit.playButtonActionPerformed(SoundAddEdit.java:315)
at com.hcs.orc.detail.SoundAddEdit.access$100(SoundAddEdit.java:40)
at com.hcs.orc.detail.SoundAddEdit$2.actionPerformed(SoundAddEdit.java:225)

更新 2

更多有趣的发现。看来我们在加载 DLL 时发生了冲突。我们有自己的 DLL 来帮助我们做一些事情(比如找到一个可靠且可用的 MAC 地址)。如果您在加载我们的 DLL 之前播放声音(加载声音相关的 DLL),那么两者都可以工作。但是,如果您使用我们的 DLL,然后尝试播放声音,声音会给您上面报告的错误。

有人知道为什么一个看似无关的 DLL 会导致另一个 DLL 稍后加载不正确吗?

作为真正蹩脚和糟糕的解决方法的条目,我们可以在查找 MAC 地址之前在启动时播放几分之一秒的静音。这是一种糟糕的形式,原因有很多,其中包括我们的许多客户根本不使用声音。

更新 3

深入研究我们的库,问题似乎是由对 RegisterClassEx(...) 的调用引起的。我们这样做是为了可以显示带有 HTML 帮助文件的嵌入式 IE 窗口。

最佳答案

我以前遇到过类似的问题(尽管与加载 DLL 无关。)Javasound 通过使用 1 个或多个混音器在底层工作,每个混音器有 1 行或多行。这些行中的每一行都有许多它说它支持的格式,但这并不意味着它在播放该格式时不会自发燃烧(本质上,没有什么能阻止它吹嘘播放它不能播放的格式。)

当您使用 AudioSystem.getLine() 时,它将遍历所有这些混音器的所有这些行,并基本上返回它遇到的第一个表示它可以处理该格式的行。如果该行是一个大骗子,那么它就不会寻找其他行 - 它只会随之而来并产生您所看到的错误。

现在这里要记住的重要一点是它在这些行上迭代的顺序是完全任意的。所以任何事情都可能导致它发生变化,包括看似无关紧要的事情,例如加载 DLL。我可以在这里看到两种可能性之一,DLL 以某种方式提供了导致问题的另一条音频线路,或者加载 DLL 只会导致任意顺序发生变化,当您这样做时,由于某种原因它首先遇到可疑线路。

解决方法并不好,但比播放声音并稍等片刻要好,您基本上必须测试线路以查看它是否在说真话:

SourceDataLine dataline = null;
for (Mixer.Info mixerInfo : AudioSystem.getMixerInfo()) {
try {
Mixer mixer = AudioSystem.getMixer(mixerInfo);
dataline = (SourceDataLine)mixer.getLine(info);
if(dataline==null) {
continue; //Doesn't support this format
}
dataline.open(audioFormat);
dataline.start();
}
catch (Exception ex) {
//If we get here it's a buggered line, so loop round again
continue;
}
try {
dataline.close();
}
catch (Exception ex) {
ex.printStackTrace(); //Shouldn't get here
}
}


if(dataline==null) {
//No dataline capable of *really* playing the stream
}
else {
//We have a non-lying dataline!
}

这种方式需要更长的时间,但它本质上是双重检查 - 我们遍历每条数据线,如果它它可以播放格式,我们检查它是否真的可以 - 并且只在那种情况下,我们会确定它是否可以安全使用。

关于java - Windows 7 上的 Java 是否支持任何声音格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20959838/

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