0

我有一个看起来像这样的主类:

package complete;

import java.io.File;
import java.io.*;
import javax.sound.sampled.*;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.BooleanControl;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.SourceDataLine;
import javax.swing.JFrame;

public class Main {

public static void main(String[] args) {
    JFrame frame = new JFrame("Presentation");
    frame.setSize(806, 506);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(false);
    frame.add(new GameFrame());
    frame.setVisible(true);
sound = new File("Assets/BackgroundSound.wav"); // Write you own file location here and be aware that it need to be an .wav file

    new Thread(play).start();
}

static File sound;
static boolean muted = false; // This should explain itself
static float volume = 100.0f; // This is the volume that goes from 0 to 100
static float pan = 0.0f; // The balance between the speakers 0 is both sides and it goes from -1 to 1

static double seconds = 0.0d; // The amount of seconds to wait before the sound starts playing

static boolean looped_forever = true; // It will keep looping forever if this is true

static int loop_times = 0; // Set the amount of extra times you want the sound to loop (you don't need to have looped_forever set to true)
static int loops_done = 0; // When the program is running this is counting the times the sound has looped so it knows when to stop

final static Runnable play = new Runnable() // This Thread/Runnabe is for playing the sound
{
    public void run()
    {
        try
        {
            // Check if the audio file is a .wav file
            if (sound.getName().toLowerCase().contains(".wav"))
            {
                AudioInputStream stream = AudioSystem.getAudioInputStream(sound);

                AudioFormat format = stream.getFormat();

                if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED)
                {
                    format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
                            format.getSampleRate(),
                            format.getSampleSizeInBits() * 2,
                            format.getChannels(),
                            format.getFrameSize() * 2,
                            format.getFrameRate(),
                            true);

                    stream = AudioSystem.getAudioInputStream(format, stream);
                }

                SourceDataLine.Info info = new DataLine.Info(
                        SourceDataLine.class,
                        stream.getFormat(),
                        (int) (stream.getFrameLength() * format.getFrameSize()));

                SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
                line.open(stream.getFormat());
                line.start();

                // Set Volume
                FloatControl volume_control = (FloatControl) line.getControl(FloatControl.Type.MASTER_GAIN);
                volume_control.setValue((float) (Math.log(volume / 100.0f) / Math.log(10.0f) * 20.0f));

                // Mute
                BooleanControl mute_control = (BooleanControl) line.getControl(BooleanControl.Type.MUTE);
                mute_control.setValue(muted);

                FloatControl pan_control = (FloatControl) line.getControl(FloatControl.Type.PAN);
                pan_control.setValue(pan);

                long last_update = System.currentTimeMillis();
                double since_last_update = (System.currentTimeMillis() - last_update) / 1000.0d;

                // Wait the amount of seconds set before continuing
                while (since_last_update < seconds)
                {
                    since_last_update = (System.currentTimeMillis() - last_update) / 1000.0d;
                }

                //System.out.println("Playing!");

                int num_read = 0;
                byte[] buf = new byte[line.getBufferSize()];

                while ((num_read = stream.read(buf, 0, buf.length)) >= 0)
                {
                    int offset = 0;

                    while (offset < num_read)
                    {
                        offset += line.write(buf, offset, num_read - offset);
                    }
                }

                line.drain();
                line.stop();

                if (looped_forever)
                {
                    new Thread(play).start();
                }
                else if (loops_done < loop_times)
                {
                    loops_done++;
                    new Thread(play).start();
                }
            }
        }
        catch (Exception ex) { ex.printStackTrace(); }
    }
};



}

当我运行可运行 JAR 时,框架以正确的大小和标题打开,但屏幕为空白。

当我从命令行运行时,出现此错误:

java.io.FileNotFoundException: Assets\BackgroundSound.wav <The system cannot find the path specified> 

at java.io.FileInputStream.open<Native Method>

at java.io.FileInputStream.<init><Unknown Source>

at com.sun.media.sound.WaveFloatFileReader.getAudioInputStream<Unknown Source>

at javax.sound.sampled.AudioSystem.getAudioInputStream<Unknown Source>

at complete.Main$1.run<Main.Java:50>

at java.lang.Thread.run<Unknown Source>

我已经从 JAR 中提取了文件,所有的类、图像和 WAV 文件都在那里。

当我从 Main 类中删除声音部分并在 Eclipse 中运行时,程序完全运行并且没有预期的声音。

当我将此版本导出为 Runnable JAR 时,与之前尝试运行它时发生的情况相同,只是这次没有命令行错误。

4

3 回答 3

0

的数据sound不直接包含在磁盘上的文件中;它位于您项目的 jar 文件中。所以,File用来访问它是不正确的。相反,使用重载AudioStream方法:

public static AudioInputStream getAudioInputStream(InputStream stream)
                                        throws UnsupportedAudioFileException,
                                               IOException

从提供的输入流中获取音频输入流。流必须指向有效的音频文件数据。此方法的实现可能需要多个解析器检查流以确定它们是否支持它。这些解析器必须能够标记流,读取足够的数据以确定它们是否支持流,如果不支持,则将流的读取指针重置为其原始位置。如果输入流不支持这些操作,则此方法可能会因 IOException 而失败。

您可以InputStream通过使用Class.getResourceAsStream(String name). 这将查看类路径,因此可以设置为在 Eclipse 和 jar 文件中工作。最简单的方法是将声音文件移动到您的类文件旁边,因此您可以使用:

InputStream soundResource = Main.class.getResourceAsStream("BackgroundSound.wav");
AudioInputStream ais = AudioSystem.getAudioInputStream(soundResource);

抱歉——我需要编辑最后一部分——我忘了​​这都是main. 除了最琐碎的程序外,尽量不要这样做。相反,实例化类并让实例做事。并将类从重命名MainSoundDemo. 否则三个月后你会对自己说,“我在哪里做的关于学习如何让 Java 播放声音的练习?它在什么文件中?它在Main?真的吗?”

于 2013-07-28T20:34:25.110 回答
0

要从 jar 加载文件,您需要使用getResources或 getResourceAsStream。

于 2013-07-28T20:28:35.807 回答
0

利用:

sound = new File(Main.class.getResource("Assets/BackgroundSound.wav").getPath());
于 2013-07-28T20:30:42.673 回答