【问题标题】:Trouble playing wav in Java在 Java 中播放 wav 时遇到问题
【发布时间】:2010-10-09 07:53:20
【问题描述】:

我在试玩

PCM_UNSIGNED 11025.0 Hz, 8 bit, mono, 1 bytes/frame

文件如here (1)here(2) 所述。

第一种方法有效,但我不想依赖sun.* 的东西。第二个结果只是播放了一些前导帧,这听起来更像是点击。不能是 IO 问题,因为我是从 ByteArrayInputStream 播放的。

请分享您对为什么会发生这种情况的想法。 TIA。

【问题讨论】:

    标签: java wav playback javasound


    【解决方案1】:

    我不确定为什么您链接到的第二种方法会启动另一个线程;我相信无论如何音频都会在自己的线程中播放。问题是您的应用程序在剪辑完成播放之前就完成了吗?

    import javax.sound.sampled.*;
    import java.io.File;
    import java.io.IOException;
    import javax.sound.sampled.LineEvent.Type;
    
    private static void playClip(File clipFile) throws IOException, 
      UnsupportedAudioFileException, LineUnavailableException, InterruptedException {
      class AudioListener implements LineListener {
        private boolean done = false;
        @Override public synchronized void update(LineEvent event) {
          Type eventType = event.getType();
          if (eventType == Type.STOP || eventType == Type.CLOSE) {
            done = true;
            notifyAll();
          }
        }
        public synchronized void waitUntilDone() throws InterruptedException {
          while (!done) { wait(); }
        }
      }
      AudioListener listener = new AudioListener();
      AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(clipFile);
      try {
        Clip clip = AudioSystem.getClip();
        clip.addLineListener(listener);
        clip.open(audioInputStream);
        try {
          clip.start();
          listener.waitUntilDone();
        } finally {
          clip.close();
        }
      } finally {
        audioInputStream.close();
      }
    }
    

    【讨论】:

    • 事实上我并没有在单独的线程中运行它,只是为了简洁起见将其链接起来。非常感谢!!!
    • @Jataro - 你是对的;我错过了 API 中的那个调用;我会更新代码。
    • 根据download.oracle.com/javase/tutorial/sound/playing.htmldrain() 似乎不适用于剪辑
    • @lucks - 谢谢!我已经更正了代码。来自文档:一旦你开始播放声音,你如何找到它何时结束?我们在上面看到了一种解决方案——在写入最后一个数据缓冲区后调用 drain 方法——但该方法仅适用于 SourceDataLine。另一种适用于 SourceDataLines 和 Clips 的方法是注册以在线路更改其状态时接收来自线路的通知。这些通知以 LineEvent 对象的形式生成,其中有四种类型:OPEN、CLOSE、START 和 STOP。
    • 所以看来你必须在它自己的线程中播放它,在文件结束之前哪个线程不会终止? (即如果应用程序的主线程退出,程序将退出,这与大多数 Java 线程应用程序不同)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 2011-08-28
    • 2013-06-05
    • 1970-01-01
    相关资源
    最近更新 更多