我有一个看起来像这样的主类:
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时,我尝试运行它时会发生同样的事情,除非这次没有命令行错误。
答案 0 :(得分:0)
要从jar加载文件,您需要使用getResources或getResourceAsStream。
答案 1 :(得分:0)
使用:
sound = new File(Main.class.getResource("Assets/BackgroundSound.wav").getPath());
答案 2 :(得分: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
。除了最琐碎的程序之外,尽量不要这样做。相反,实例化该类并让实例执行操作。并将该类从Main
重命名为SoundDemo
。否则在三个月内你会对自己说:“我在哪里学习如何让Java播放声音呢?它是什么文件?它在Main
?真的吗?”