如何让我的Java应用程序在Linux中播放音频效果不错?

时间:2009-12-21 17:39:41

标签: java linux audio

我有一个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中播放音频是一个失败的原因吗?

5 个答案:

答案 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命令。最简单的解决方案。