我有一个Java应用程序,其UI很大程度上依赖于音频。在Windows和OS X上,一切正常;但是,在Linux上,应用程序需要对声音设备进行独占访问,抛出LineUnavailableException
并且听不到声音。我正在使用Kubuntu 9.10。
这意味着在程序运行时没有其他应用程序可以播放音频,甚至在程序启动时甚至无法保持音频设备。这自然是不可接受的。
以下是我用来播放音频的代码:
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
this.wait((clip.getMicrosecondLength() / 1000) + 100);
clip.stop();
我做错了吗?使用Java在Linux中播放音频是一个失败的原因吗?
答案 0 :(得分:5)
我担心Linux中的音频本身就是一个失败的原因。但在这种情况下,它确实是known Java Bug。您应该尝试找出您正在使用的声音架构。我认为Ubuntu的默认值是PulseAudio / ALSA。不过我对Kubuntu并不确定。
有a known workaround(我自己从未尝试过)。
您运行的其他一些应用程序也可能只使用声卡,因此请确保使用不同的应用程序(即与其他应用程序完美匹配的应用程序)进行测试。
答案 1 :(得分:2)
我能够使用OpenJDK在GNU / Linux(Ubuntu 10.10)上播放音频声音并进行一些调整。我相信LineUnavailableException是PulseAudio中的一个错误,并在10.10中修复。
我需要指定格式(Windows上不需要的东西)。
AudioInputStream audioIn = AudioSystem.getAudioInputStream(in);
// needed for working on GNU/Linux (openjdk) {
AudioFormat format = audioIn.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip)AudioSystem.getLine(info);
// }
// on windows, {
//Clip clip = AudioSystem.getClip();
// }
请注意,对Clip.getMicrosecondLength()的调用将返回毫秒。
答案 2 :(得分:1)
Java Sound对于高精度或低延迟的任务非常糟糕,并且在Linux上几乎完全失效。在您将更多时间投入其中之前放弃船舶。 在Java Sound之后我尝试了OpenAL,它在Linux上也不是很好。 目前我正在使用FMOD,这是不幸的闭源。
开源方式可能是PortAudio。尝试与SIP Communicator开发人员交谈。
我也尝试过RtAudio,但发现它的ALSA实现存在漏洞。
答案 3 :(得分:0)
我从互联网的某个地方获得此代码,声音大部分时间出现,偶尔也没出现
import java.util.*;
import java.text.*;
import java.io.*;
import java.net.*;
import javax.sound.sampled.*;
public class Sound2
{
public static
void main (String name[])
{
playSound ( "somesound.wav" );
}
public static
void playSound (String filename)
{
int BUFFER_SIZE = 128000;
//File soundFile = null;
AudioInputStream audioStream = null;
AudioFormat audioFormat = null;
SourceDataLine sourceLine = null;
try
{
audioStream =
AudioSystem.getAudioInputStream
(
new
BufferedInputStream
(
new FileInputStream ( filename )
)
//soundFileStream
);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
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();
System.exit(1);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
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();
}
}
答案 4 :(得分:0)
通过shell发送mplayer命令。最简单的解决方案。