如何让我的 Java 应用程序在 Linux 中播放好音频?
Posted
技术标签:
【中文标题】如何让我的 Java 应用程序在 Linux 中播放好音频?【英文标题】:How can I make my Java application with audio play nice in Linux? 【发布时间】:2009-12-21 17:39:40 【问题描述】:我有一个 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();
我做错了吗?在 Linux 中使用 Java 播放音频会失败吗?
【问题讨论】:
请说明 Linux 发行版和版本。 @jsight:在我看来,“Kubuntu 9.10”从一开始就在那里。 【参考方案1】:我担心 Linux 中的音频本身就是一个失败的原因。但在这种情况下,它确实是known Java Bug。您应该尝试找出您正在使用的声音架构。我认为 Ubuntu 的默认值是 PulseAudio/ALSA。不过我不确定 Kubuntu。
有a known workaround(不过我自己从未尝试过)。
您正在运行的其他一些应用程序也有可能专门使用声卡,因此请务必使用不同的应用程序进行测试(即与其他应用程序配合得很好的应用程序)。
【讨论】:
【参考方案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() 的调用会返回 毫秒。
【讨论】:
【参考方案3】:Java 声音对于高精度或低延迟的任务来说很糟糕,而且在 Linux 上几乎完全无法正常工作。在您投入更多时间之前立即放弃船舶。 在 Java Sound 之后,我尝试了 OpenAL,它在 Linux 上也不是很好。 目前我正在使用 FMOD,不幸的是它是闭源的。
要采用的开源方式可能是 PortAudio。尝试与 SIP Communicator 开发人员交谈。
我也尝试过 RtAudio,但发现它的 ALSA 实现存在错误。
【讨论】:
【参考方案4】:通过 shell 发送 mplayer 命令。最简单的解决方案。
【讨论】:
【参考方案5】:我从互联网的某个地方得到这个代码,声音大部分时间都会出现,偶尔不会出现
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();
【讨论】:
以上是关于如何让我的 Java 应用程序在 Linux 中播放好音频?的主要内容,如果未能解决你的问题,请参考以下文章
如何让我的客户端应用程序名称显示在 java 的 zos 上?
如何让我的 React Native 应用出现在 android 的分享列表中