【问题标题】:Clip not playing any sound剪辑不播放任何声音
【发布时间】:2013-06-16 23:15:05
【问题描述】:

好吧,标题说明了一切,我尝试使用 javax.sound 播放 wav 文件,但没有任何反应。我尝试了许多不同的文件,但没有任何运气。

public static void main(String[] args) throws IOException, UnsupportedAudioFileException, LineUnavailableException
{

    File in = new File("C:\\Users\\Sandra\\Desktop\\music\\rags.wav");
    AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(in);
    Clip play = AudioSystem.getClip();
    play.open(audioInputStream);
    FloatControl volume= (FloatControl) play.getControl(FloatControl.Type.MASTER_GAIN);
    volume.setValue(1.0f); // Reduce volume by 10 decibels.
    play.start();

}

【问题讨论】:

标签: java audio javasound


【解决方案1】:

如前所述,您需要阻止主线程退出,因为这会导致 JVM 终止。

Clip#start 不是阻塞调用,这意味着它会在调用后(很快)返回。

我毫不怀疑有很多方法可以解决这个问题,这只是其中一种的简单示例。

public class PlayMusic {

    public static void main(String[] args) throws InterruptedException {
        Clip play = null;
        try {
            File in = new File("C:\\Users\\Public\\Music\\Sample Music\\Kalimba.wav");
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(in);
            play = AudioSystem.getClip();
            play.open(audioInputStream);
            FloatControl volume = (FloatControl) play.getControl(FloatControl.Type.MASTER_GAIN);
            volume.setValue(1.0f); // Reduce volume by 10 decibels.
            play.start();
            // Loop until the Clip is not longer running.
            // We loop this way to allow the line to fill, otherwise isRunning will
            // return false
            //do {
            //    Thread.sleep(15);
            //} while (play.isRunning());
            play.drain();
        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException ex) {
            ex.printStackTrace();
        } finally {
            try {
                play.close();
            } catch (Exception exp) {
            }
        }
        System.out.println("...");
    }
}

实际的解决方案将取决于您的需求。

【讨论】:

  • 如果没有简单的礼貌来解释原因,您必须欣赏盲目投票,这样我们都可以了解什么会使答案更好
  • @MadProgrammer ClipDataLine,因此,start() 是非阻塞的。但是,接口中明确指出方法drain()阻塞:“此方法阻塞,直到排空完成。”来自DataLine.drain()。任何需要人为阻止程序退出的解决方案都是不正确的。这在Java Playing Back Audio Tutorial 中有明确说明。
  • @Jared 嗯,很高兴知道 - 此外,每条规则都有例外;)
  • 我在 (1) 带有 JDK 1.8.0_102-b14 64 位的笔记本电脑(Linux Mint 18.0 64 位)和 (2) 运行 Armbian 5.25(内核 3.4.113)的 Orange Pi Zero 上进行了一些测试)与 JDK 1.8.0_121-b13(来自 Oracle)。我发现在 (2)-OrPi drain() 上似乎没有阻塞,而是在阻塞之前执行了System.out.println(...)(“农民调试”)。不幸的是,在 (1) 笔记本电脑上,情况正好相反,println(...) 使它不阻塞,如果没有它就会阻塞。 (1) 和 (2) 上最可靠的方法是 Thread.sleep(clip.getMicrosecondLength() / 1000) - 嘿,uggggly...
  • @fr13d 不得不说我不是drain的粉丝,我更喜欢用LineListener,如果你需要的话,你可以用ReentrantLock或者别的什么来单身剪辑结束
【解决方案2】:

Java 的声音Clip 需要一个活动的Thread 来播放音频输入文件,否则应用程序在文件播放之前退出。你可以添加

JOptionPane.showMessageDialog(null, "Click OK to stop music");

拨打start之后。

【讨论】:

  • ClipDataLine,因此,start() 是非阻塞的。但是,接口中明确指出方法drain()阻塞:“此方法阻塞,直到排空完成。”来自DataLine.drain()。任何需要人为阻止程序退出的解决方案都是不正确的。这在Java Playing Back Audio Tutorial 中有明确说明。
【解决方案3】:

播放音频剪辑的正确方法是按照Playing Back Audio 中的说明排空线路。

所以你的 main 应该是这样的:

public static void main(String[] args) throws IOException,
    UnsupportedAudioFileException, LineUnavailableException
{
    File in = new File("C:\\Users\\Sandra\\Desktop\\music\\rags.wav");
    AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(in);
    Clip play = AudioSystem.getClip();
    play.open(audioInputStream);
    FloatControl volume= (FloatControl) play.getControl(FloatControl.Type.MASTER_GAIN);
    volume.setValue(1.0f); // Reduce volume by 10 decibels.
    play.start();
    play.drain();
    play.close();
}

play.drain() 阻塞,直到播放完所有数据。

【讨论】:

    【解决方案4】:

    这里playing a clip

        public static void main(String[] args) throws Exception {
               File in = new File("C:\\Users\\Sandra\\Desktop\\music\\rags.wav");
               AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(in);
               Clip play = AudioSystem.getClip();
               play.open(audioInputStream);
               FloatControl volume= (FloatControl)play.getControl(FloatControl.Type.MASTER_GAIN);
               volume.setValue(1.0f); // Reduce volume by 10 decibels.
               play.start();
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        // A GUI element to prevent the Clip's daemon Thread
                        // from terminating at the end of the main()
                        JOptionPane.showMessageDialog(null, "Close to exit!");
                    }
                });
            }
    

    【讨论】:

      【解决方案5】:

      您的程序在播放声音之前终止。我会以某种线程方式执行play.start();invokeLater,...),并找到一种等待声音结束的方法(Reimeus 建议这样做)。

      一条线索:

      public static void main(String[] args) {
          javax.swing.SwingUtilities.invokeLater(new Runnable() {
              public void run() {
      
                ...
      
                play.start();
                JOptionPane.showMessageDialog(null, "Click OK to stop music");
              }
          });
      
      }
      

      【讨论】:

        【解决方案6】:

        如果您只想播放音频,这里有一个方法。

        audioFileDirectoryString 变量需要正确的音频文件路径,否则会抛出异常,程序无法运行。

        如果使用 IDE,则在项目中拥有正确的音频文件目录的示例:

        1. src 文件夹中创建一个文件夹,例如:“音乐”并在其中放置一个音频文件
        2. audioFileDirectory = "/music/name_of_audio_file";

        播放音频的重要部分是程序的主线程需要以某种方式“活着”,所以行

        Thread.sleep(audio.getMicrosecondLength()/1000);
        

        是主线程“活着”的地方,参数audio.getMicrosecondLength()/1000是“活着”的时间,即音频文件的整个长度。

        public class AudioTest
        {
            void playAudio() throws Exception
            {
                String audioFileDirectory = "your_audioFileDirectory";
                InputStream is = getClass().getResourceAsStream(audioFileDirectory);
                BufferedInputStream bis = new BufferedInputStream(is);
                AudioInputStream ais = AudioSystem.getAudioInputStream(bis);
                Clip audio = AudioSystem.getClip();
                audio.open(ais);
                audio.loop(Clip.LOOP_CONTINUOUSLY);
                audio.start();
                Thread.sleep(audio.getMicrosecondLength()/1000);
                audio.close();
            } // end playAudio
        
            public static void main(String[] args) 
            {
                try 
                {
                    new AudioTest().playAudio();
                } 
                catch (Exception e) 
                {
                    System.out.println("Class: " + e.getClass().getName());
                    System.out.println("\nMessage:\n" + e.getMessage() + "\n");
                    e.printStackTrace();
                }
            } // end main
        } // end class AudioTest
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-12-22
          • 2018-05-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多