Ubuntu16.4,Java,WAV文件播放
Ubuntu 16.4, Java, WAV file playback
这是一件奇怪的事情。我正在尝试通过 Java AudioSystem 和 AudioSystem.getClip()
播放一些声音。文件都是"PCM_SIGNED, 22.050.0 Hz, 16 bit, mono, 2 bytes/frame, little endian".
在几个 Ubuntu 16.4 LTS Linux 盒子上,这种格式被 PulseAudio 拒绝 Invalid Format Exception
,因为唯一接受的格式似乎是 "PCM_SIGNED, unknown sample rate, 16 bit, stereo, 4 bytes/frame, big endian".
我已经尝试重新采样我的 WAV 以匹配这个奇怪的约束,但无济于事。 AudioSystem.getAudioInputStream()
甚至不再接受这些
不用说,同样适用于 Mac OS 和 Windows。而且使用sox
库和play file.wav
播放这些文件也没有问题
好的,解决了。
通常如果有人问,如何使用Java播放WAV,这是最常见的答案:
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(DragonflyApp.class.getResource("/resources/" + soundFile));
clip = AudioSystem.getClip();
clip.addLineListener(e -> {
if (e.getType() == LineEvent.Type.STOP) {
// Do something on end of playback
}
});
clip.open(audioInputStream);
clip.start();
不幸的是,在某些 Linux 系统上,这最终会导致 "Invalid Format" 异常,由 PulseAudio 抛出,它声称无法播放最简单的 WAV 文件(见上文)。
解决方法是在 Linux 下使用此序列。它通常也适用于 MacOS,但最终的 "STOP" 指示来得很晚(播放结束后大约 5 秒),所以我在这里进行条件执行:
这适用于 Linux(至少在 Ubuntu 16.04 上),带有剪辑,以前被 PulseAudio 拒绝:
DataPusher datapusher = null;
DataLine.Info lineinfo = null;
SourceDataLine sourcedataline = null;
lineinfo = new DataLine.Info(SourceDataLine.class, audioInputStream.getFormat());
if (!(AudioSystem.isLineSupported(lineinfo))) {
return;
}
sourcedataline = (SourceDataLine) AudioSystem.getLine(lineinfo);
sourcedataline.addLineListener(e -> {
if (e.getType() == LineEvent.Type.STOP) {
// Do something on end of playback
}
});
datapusher = new DataPusher(sourcedataline, audioInputStream);
datapusher.start();
有条件地使用两个代码片段:
if (System.getProperty("os.name").equals("Mac OS X")) {
// The clip solution
}
else {
// The datapusher solution
}
希望,这可以帮助其他人,他们也会遇到这个问题。
这是一件奇怪的事情。我正在尝试通过 Java AudioSystem 和 AudioSystem.getClip()
播放一些声音。文件都是"PCM_SIGNED, 22.050.0 Hz, 16 bit, mono, 2 bytes/frame, little endian".
在几个 Ubuntu 16.4 LTS Linux 盒子上,这种格式被 PulseAudio 拒绝 Invalid Format Exception
,因为唯一接受的格式似乎是 "PCM_SIGNED, unknown sample rate, 16 bit, stereo, 4 bytes/frame, big endian".
我已经尝试重新采样我的 WAV 以匹配这个奇怪的约束,但无济于事。 AudioSystem.getAudioInputStream()
不用说,同样适用于 Mac OS 和 Windows。而且使用sox
库和play file.wav
好的,解决了。
通常如果有人问,如何使用Java播放WAV,这是最常见的答案:
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(DragonflyApp.class.getResource("/resources/" + soundFile));
clip = AudioSystem.getClip();
clip.addLineListener(e -> {
if (e.getType() == LineEvent.Type.STOP) {
// Do something on end of playback
}
});
clip.open(audioInputStream);
clip.start();
不幸的是,在某些 Linux 系统上,这最终会导致 "Invalid Format" 异常,由 PulseAudio 抛出,它声称无法播放最简单的 WAV 文件(见上文)。
解决方法是在 Linux 下使用此序列。它通常也适用于 MacOS,但最终的 "STOP" 指示来得很晚(播放结束后大约 5 秒),所以我在这里进行条件执行:
这适用于 Linux(至少在 Ubuntu 16.04 上),带有剪辑,以前被 PulseAudio 拒绝:
DataPusher datapusher = null;
DataLine.Info lineinfo = null;
SourceDataLine sourcedataline = null;
lineinfo = new DataLine.Info(SourceDataLine.class, audioInputStream.getFormat());
if (!(AudioSystem.isLineSupported(lineinfo))) {
return;
}
sourcedataline = (SourceDataLine) AudioSystem.getLine(lineinfo);
sourcedataline.addLineListener(e -> {
if (e.getType() == LineEvent.Type.STOP) {
// Do something on end of playback
}
});
datapusher = new DataPusher(sourcedataline, audioInputStream);
datapusher.start();
有条件地使用两个代码片段:
if (System.getProperty("os.name").equals("Mac OS X")) {
// The clip solution
}
else {
// The datapusher solution
}
希望,这可以帮助其他人,他们也会遇到这个问题。