【问题标题】:How to play .wav files with java如何使用 java 播放 .wav 文件
【发布时间】:2011-01-25 21:26:16
【问题描述】:

我正在尝试使用 Java 播放 *.wav 文件。我希望它执行以下操作:
按下按钮时,播放短促的哔声。

我已经用谷歌搜索过了,但大部分代码都不起作用。谁能给我一个简单的代码 sn-p 来播放 .wav 文件?

【问题讨论】:

    标签: java audio wav


    【解决方案1】:

    没有java反射的解决方案DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat)

    Java 反射会降低性能。 运行:java playsound absoluteFilePathTo/file.wav

    import javax.sound.sampled.*;
    import java.io.*;
    public class playsound {
    
        public static void main (String args[]) throws Exception {
            playSound (args[0]);
        }
    
        public static void playSound () throws Exception {
            AudioInputStream 
            audioStream = AudioSystem.getAudioInputStream(new File (filename));
    
            int BUFFER_SIZE = 128000;
            AudioFormat audioFormat = null;
            SourceDataLine sourceLine = null;
    
            audioFormat = audioStream.getFormat();
    
            sourceLine = AudioSystem.getSourceDataLine(audioFormat);
            sourceLine.open(audioFormat);
            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) {
                    int nBytesWritten = sourceLine.write(abData, 0, nBytesRead);
                }
            }
    
            sourceLine.drain();
            sourceLine.close();
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      使用AudioInputStream 的另一种方法:

      import java.io.File;
      
      import javax.sound.sampled.AudioInputStream;
      import javax.sound.sampled.AudioSystem;
      import javax.sound.sampled.Clip;
      import javax.sound.sampled.Line;
      import javax.sound.sampled.LineEvent;
      import javax.sound.sampled.LineListener;
      import javax.swing.JDialog;
      import javax.swing.JFileChooser;
      
      public class CoreJavaSound extends Object implements LineListener {
          File soundFile;
      
          JDialog playingDialog;
      
          Clip clip;
      
          public static void main(String[] args) throws Exception {
              CoreJavaSound s = new CoreJavaSound();
          }
      
          public CoreJavaSound() throws Exception {
              JFileChooser chooser = new JFileChooser();
              chooser.showOpenDialog(null);
              soundFile = chooser.getSelectedFile();
      
              System.out.println("Playing " + soundFile.getName());
      
              Line.Info linfo = new Line.Info(Clip.class);
              Line line = AudioSystem.getLine(linfo);
              clip = (Clip) line;
              clip.addLineListener(this);
              AudioInputStream ais = AudioSystem.getAudioInputStream(soundFile);
              clip.open(ais);
              clip.start();
          }
      
          public void update(LineEvent le) {
              LineEvent.Type type = le.getType();
              if (type == LineEvent.Type.OPEN) {
                  System.out.println("OPEN");
              } else if (type == LineEvent.Type.CLOSE) {
                  System.out.println("CLOSE");
                  System.exit(0);
              } else if (type == LineEvent.Type.START) {
                  System.out.println("START");
                  playingDialog.setVisible(true);
              } else if (type == LineEvent.Type.STOP) {
                  System.out.println("STOP");
                  playingDialog.setVisible(false);
                  clip.close();
              }
          }
      }
      

      【讨论】:

      • 为什么是extends Object
      • @MazeOfEncryption 我真的不记得了 :)
      【解决方案3】:

      您也可以通过这种方式使用 AudioStream:

      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.InputStream;
      
      import javax.swing.JButton;
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      
      import sun.audio.AudioPlayer;
      import sun.audio.AudioStream;
      
      public class AudioWizz extends JPanel implements ActionListener {
      
          private static final long serialVersionUID = 1L; //you like your cereal and the program likes their "serial"
      
          static AudioWizz a;
          static JButton playBuddon;
          static JFrame frame;
      
          public static void main(String arguments[]){
      
              frame= new JFrame("AudioWizz");
              frame.setSize(300,300);
              frame.setVisible(true);
              a= new AudioWizz();
              playBuddon= new JButton("PUSH ME");
              playBuddon.setBounds(10,10,80,30);
              playBuddon.addActionListener(a);
      
              frame.add(playBuddon);
              frame.add(a);
          }
      
          public void actionPerformed(ActionEvent e){ //an eventListener
              if (e.getSource() == playBuddon) {
                  try {
                      InputStream in = new FileInputStream("*.wav");
                      AudioStream sound = new AudioStream(in);
                      AudioPlayer.player.start(sound);
                  } catch(FileNotFoundException e1) {
                      e1.printStackTrace();
                  } catch (IOException e1) {
                      e1.printStackTrace();
                  }
              }
          }
      
      }
      

      【讨论】:

        【解决方案4】:

        将播放 WAV 文件的类,在声音播放完毕之前一直阻塞:

        class Sound implements Playable {
        
            private final Path wavPath;
            private final CyclicBarrier barrier = new CyclicBarrier(2);
        
            Sound(final Path wavPath) {
        
                this.wavPath = wavPath;
            }
        
            @Override
            public void play() throws LineUnavailableException, IOException, UnsupportedAudioFileException {
        
                try (final AudioInputStream audioIn = AudioSystem.getAudioInputStream(wavPath.toFile());
                     final Clip clip = AudioSystem.getClip()) {
        
                    listenForEndOf(clip);
                    clip.open(audioIn);
                    clip.start();
                    waitForSoundEnd();
                }
            }
        
            private void listenForEndOf(final Clip clip) {
        
                clip.addLineListener(event -> {
                    if (event.getType() == LineEvent.Type.STOP) waitOnBarrier();
                });
            }
        
            private void waitOnBarrier() {
        
                try {
        
                    barrier.await();
                } catch (final InterruptedException ignored) {
                } catch (final BrokenBarrierException e) {
        
                    throw new RuntimeException(e);
                }
            }
        
            private void waitForSoundEnd() {
        
                waitOnBarrier();
            }
        }
        

        【讨论】:

          【解决方案5】:

          这是我在不使用 sun 的情况下能想到的最优雅的形式。*:

          import java.io.*;
          import javax.sound.sampled.*;
          
          try {
              File yourFile;
              AudioInputStream stream;
              AudioFormat format;
              DataLine.Info info;
              Clip clip;
          
              stream = AudioSystem.getAudioInputStream(yourFile);
              format = stream.getFormat();
              info = new DataLine.Info(Clip.class, format);
              clip = (Clip) AudioSystem.getLine(info);
              clip.open(stream);
              clip.start();
          }
          catch (Exception e) {
              //whatevers
          }
          

          【讨论】:

          • 我听不到使用此示例代码发出的任何音频。我有什么遗漏的吗?
          • 应该是完整的,不过也是五岁了,丑陋的。我确信有更好的方法,使用漂亮的 Java 库。
          • 要听到输出,您应该延迟应用程序终止一段播放时间。尝试将Thread.sleep(1000) 放在clip.start() 之后。
          【解决方案6】:

          您可以在播放后使用事件监听器关闭剪辑

          import java.io.File;
          import javax.sound.sampled.*;
          
          public void play(File file) 
          {
              try
              {
                  final Clip clip = (Clip)AudioSystem.getLine(new Line.Info(Clip.class));
          
                  clip.addLineListener(new LineListener()
                  {
                      @Override
                      public void update(LineEvent event)
                      {
                          if (event.getType() == LineEvent.Type.STOP)
                              clip.close();
                      }
                  });
          
                  clip.open(AudioSystem.getAudioInputStream(file));
                  clip.start();
              }
              catch (Exception exc)
              {
                  exc.printStackTrace(System.out);
              }
          }
          

          【讨论】:

          • 如果你想等到音频流被线路处理,你可以在句子开头添加“clip.drain()”。
          【解决方案7】:

          最后我设法做到了以下,它工作正常

          import java.io.File;
          import java.io.IOException;
          
          import javax.sound.sampled.AudioFormat;
          import javax.sound.sampled.AudioInputStream;
          import javax.sound.sampled.AudioSystem;
          import javax.sound.sampled.DataLine;
          import javax.sound.sampled.LineUnavailableException;
          import javax.sound.sampled.SourceDataLine;
          
          public class MakeSound {
          
              private final int BUFFER_SIZE = 128000;
              private File soundFile;
              private AudioInputStream audioStream;
              private AudioFormat audioFormat;
              private SourceDataLine sourceLine;
          
              /**
               * @param filename the name of the file that is going to be played
               */
              public void playSound(String filename){
          
                  String strFilename = filename;
          
                  try {
                      soundFile = new File(strFilename);
                  } catch (Exception e) {
                      e.printStackTrace();
                      System.exit(1);
                  }
          
                  try {
                      audioStream = AudioSystem.getAudioInputStream(soundFile);
                  } 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();
              }
          }
          

          【讨论】:

          【解决方案8】:

          最短形式(无需安装随机库)?

          public static void play(String filename)
          {
              try
              {
                  Clip clip = AudioSystem.getClip();
                  clip.open(AudioSystem.getAudioInputStream(new File(filename)));
                  clip.start();
              }
              catch (Exception exc)
              {
                  exc.printStackTrace(System.out);
              }
          }
          

          唯一的问题是没有好的方法可以让这个方法阻塞在 *.wav 完成后关闭和处理数据。 clip.drain() 说它正在阻塞,但事实并非如此。剪辑未在之后 start() 运行。 我发现的唯一可行但 UGLY 的方法是:

          // ...
          clip.start();
          while (!clip.isRunning())
              Thread.sleep(10);
          while (clip.isRunning())
              Thread.sleep(10);
          clip.close();
          

          【讨论】:

            【解决方案9】:

            sn-p here 工作正常,用 windows 声音测试:

            public static void main(String[] args) {
                    AePlayWave aw = new AePlayWave( "C:\\WINDOWS\\Media\\tada.wav" );
                    aw.start();     
            }
            

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-08-15
            • 1970-01-01
            • 1970-01-01
            • 2011-04-18
            • 2018-08-23
            • 2012-12-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多