如何播放wav文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何播放wav文件相关的知识,希望对你有一定的参考价值。

如何播放wav文件

建议使用jmf(java media framwork),这样就能播放mp3等众多格式的音乐了;去sun官网下一个jmf,安装好后,把
jmf.jar包引入便可使用,给出例zi代码:使用方法:构造函数中传入文件路径名即可,播放、暂停、继续、停止等功能均已实现。

/*************************************************
* Subclass: MusicPlay
*************************************************/
public class MusicPlay implements Runnable
private Time zeroTime = new Time(0);
private Player player;
private boolean isloop = false;

/*************************************************
* Function: MusicPlay Description: constructor, load the music file and
* get ready for play Called By: MultiMedia()
*************************************************/
// 实例化各个参数 filename 为文件名,可为绝对路径
public MusicPlay(String filename)
File file = new File(filename);
try
player = Manager.createRealizedPlayer(file.toURI().toURL());
player.addControllerListener(new ControllListener());
catch (NoPlayerException e)
e.printStackTrace();
catch (CannotRealizeException e)
e.printStackTrace();
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();



/*************************************************
* Function: isRunning Description: test if this music is playing Called
* By:
*************************************************/
public boolean isRunning()
return player.getState() == Player.Started;


/*************************************************
* Function: play Description: play the music for once Called By:
* resumeAll()
*************************************************/
// 只播放一次
public void play()
if (!turnOff)
player.start();


/*************************************************
* Function: replay Description: replay the music Called By: musics that
* will be played many times will invoke this methed
*************************************************/
// 再播放一次
public void replay()
if (turnOff)
return;

if (player.getState() == Controller.Prefetched)
player.setMediaTime(zeroTime);
player.start();


/*************************************************
* Function: stop Description: stop this music Called By: stopAll() of
* upper class,suspendAll() of upper
* class,BackroundForMenuPanel,GameOverPanel
*************************************************/
public void stop()
player.stop();


/*************************************************
* Function: close Description: dispose the music Called By: closeAll()
* of super class
*************************************************/
public void close()
player.stop();
player.close();


/*************************************************
* Function: loop Description: make the music played repetitiously
* Called By: music that will repetitious play
*************************************************/
// 循环播放
public void loop()
if (turnOff)
return;

isloop = true;
player.prefetch();
replay();


/*************************************************
* Function: run Description: trig this music Called By: Override method
*************************************************/
@Override
public void run()
loop();


/*************************************************
* Subclass: ControllListener Description: listener for playing and
* implement playing repetitiously
*************************************************/
// 通过对播放进度的监听,实现循环播放
private class ControllListener implements ControllerListener

public void controllerUpdate(ControllerEvent e)
if (e instanceof EndOfMediaEvent)
if (isloop)
player.setMediaTime(new Time(0));
player.start();





参考技术A WAV符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持,该格式也支持MSADPCM,CCITT A LAW等多种压缩运算法,支持多种音频数字,取样频率和声道,标准格式化的WAV文件和CD格式一样,也是44.1K的取样频率,16位量化数字,因此在声音文件质量和CD相差无几! WAV是波形声音文件,使用Windows自带的媒体播放器就可以打开,如今主流的音频播放器都支持打开WAV文件。 参考技术B wav是一种常见的音频文件
打开任何播放器 将文件拖拽进去或右键点击,选择打开方式,任何播放文件都可以打开
参考技术C 使用系统自带的媒体播放器,或暴风影音等,都可以播放。

如何使用 java 播放 .wav 文件

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

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

我已经用谷歌搜索过了,但大部分代码都不起作用。谁能给我一个简单的代码 sn-p 来播放 .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();
    

【讨论】:

这个对我不起作用。我推荐一个非常简单的:http://alvinalexander.com/java/java-audio-example-java-au-play-sound 说真的,如果这是在 Java 中播放 wav 声音所需要的,那么我将停止使用 Java,幸运的是我怀疑这是正确的。 如果你在游戏循环中尝试这个,它会冻结游戏【参考方案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();     

【讨论】:

如果您仍然有问题,请尝试更换声音设备。另请参阅此处推荐的工具***.com/questions/2175318/…

以上是关于如何播放wav文件的主要内容,如果未能解决你的问题,请参考以下文章

C++如何播放wav声音文件.Linux系统

如何使用 java 播放 .wav 文件

如何在导出的 jar 文件中播放 .wav 文件?

如何播放wav文件

如何在 Windows 中播放 .wav 文件?

如何在python中播放wav文件?