【问题标题】:How can I make my Java application with audio play nice in Linux?如何让我的 Java 应用程序在 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”从一开始就在那里。

标签: java linux audio


【解决方案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();
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-08-29
            • 1970-01-01
            • 2015-06-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多