开发者

How can I make my Java application with audio play nice in Linux?

开发者 https://www.devze.com 2022-12-14 09:08 出处:网络
I have a Java application whose UI relies heavily on audio. On Windows and OS X, everything works fine; on Linux, however, the application requires exclu开发者_开发问答sive access to the sound device,

I have a Java application whose UI relies heavily on audio. On Windows and OS X, everything works fine; on Linux, however, the application requires exclu开发者_开发问答sive access to the sound device, a LineUnavailableException is thrown and no sound is heard. I'm using Kubuntu 9.10.

This means that no other application can play audio while the program is running, and can't even be holding an audio device when the program starts. This is naturally unacceptable.

Here is the code I'm using to play audio:

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(file);

Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);

clip.start();

this.wait((clip.getMicrosecondLength() / 1000) + 100);

clip.stop();

Am I doing something wrong? Is using Java to play audio in Linux a lost cause?


I fear that audio in Linux is a lost cause itself. But in this case, it really is a known Java Bug. You should try to figure out what sound architecture you are using. I think the default for Ubuntu is PulseAudio/ALSA. I'm not not sure about Kubuntu though.

There is a known workaround (I never tried it myself though).

It's also possible that some other applications you're running is exclusively using the soundcard, so make sure to test with different applications (i.e. applications that play nicely with others).


I was able to play audio sound on GNU/Linux (Ubuntu 10.10) using the OpenJDK with some tweaks. I believe the the LineUnavailableException was a bug in PulseAudio and was fixed in 10.10.

I needed to specify the Format (something not needed on 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();
// }

Be aware that the call to Clip.getMicrosecondLength() returns milliseconds.


Java Sound is terrible for high-precision or low-latency tasks, and almost totally dysfunctional on Linux. Abandon ship now before you sink more time into it. After Java Sound I tried OpenAL which wasn't great on Linux either. Currently I'm using FMOD which is unfortunately closed-source.

The open source way to go would probably be PortAudio. Try talking to the SIP Communicator devs.

I also tried RtAudio but found it had bugs with its ALSA implementation.


Send an mplayer command through a shell. Most easy solution.


i got this code from somewhere in internet, the sound comes up most time, occasionally doesn't come up

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();
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消