2010-03-10 101 views
41

我想用Java播放* .wav文件。我希望它能做到以下几点:
当按下按钮时,发出短促的哔声。如何用java播放.wav文件

我已经使用了它,但大部分的代码没有工作。有人可以给我一个简单的代码片段来播放.wav文件吗?

+0

什么不工作,为什么 – Bozho

回答

32

最后我设法做以下工作得很好

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

这一个不适合我。我建议一个非常简单的:[http://alvinalexander.com/java/java-audio-example-java-au-play-sound](http://alvinalexander.com/java/java-audio-example-java -au-play-sound) – duleshi

+8

说真的,如果这是在Java中播放wav声音所需要的,那么我将停止使用Java,幸运的是我怀疑这是对的。 –

+0

@duleshi你的例子为我工作,它是该死的简单:) –

3

here正常工作的片断,具有完善的窗户测试:

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

如果您仍然有问题与尝试改变声音设备。另见这里推荐的工具http://stackoverflow.com/questions/2175318/how-to-change-default-sound-playback-device-programatically/2216886#2216886 – stacker

25

这里是最优雅的形式,我能来最多不使用太阳*:

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 
} 
+1

我听不到任何使用此示例代码出来的音频。有什么我错过了吗? –

+1

它应该是完整的,但它也是五岁,丑陋。我确信有更好的方式来使用它,使用漂亮的Java库。 – tschwab

+1

要听到输出,您应该延迟应用程序终止一段时间。尝试在'clip.start()'之后放置'Thread.sleep(1000)'。 – Metaphore

15

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

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()说它阻止,但它不是。剪辑未运行RIGHT AFTERstart()。 唯一的工作,但UGLY办法,我发现是:

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

剪辑有一个'addLineListener',所以你不需要使用'while'循环... –

10

您可以使用事件侦听器来关闭剪辑更是打出了

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

如果你想等到流的开始,你可以在开始之后添加句子“clip.drain()”音频由Line处理。 – Victor

0

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

一个将播放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(); 
    } 
} 
0

您可以使用语音串流这种方式还有:

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

} 
1

没有DataLine.Info信息=新DataLine.Info(SourceDataLine.class,AudioFormat的)Java反射机制的解决方案; 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 
    ( 
     String filename 
    ) throws Exception 
    { 

     AudioInputStream 
     audioStream = 
     AudioSystem.getAudioInputStream 
     (new File (filename)); 

     int BUFFER_SIZE = 128000; 
     AudioFormat audioFormat = null; 
     SourceDataLine sourceLine = null; 

     audioFormat = audioStream.getFormat(); 

     sourceLine = (SourceDataLine) 
     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(); 
    } 

}