如何在Java应用程序中播放音频
我正在制作一个java应用程序,我需要播放音频。我主要播放我的大炮射击的小声音文件,这是一个大炮射击游戏,炮弹爆炸,尽管我计划播放循环背景音乐。我已经找到了两种不同的方法来实现这一点,但它们都不符合我的要求 第一种方法实际上是一种方法:如何在Java应用程序中播放音频,java,audio,Java,Audio,我正在制作一个java应用程序,我需要播放音频。我主要播放我的大炮射击的小声音文件,这是一个大炮射击游戏,炮弹爆炸,尽管我计划播放循环背景音乐。我已经找到了两种不同的方法来实现这一点,但它们都不符合我的要求 第一种方法实际上是一种方法: public void playSoundFile(File file) {//http://java.ittoolbox.com/groups/technical-functional/java-l/sound-in-an-applicatio
public void playSoundFile(File file) {//http://java.ittoolbox.com/groups/technical-functional/java-l/sound-in-an-application-90681
try {
//get an AudioInputStream
AudioInputStream ais = AudioSystem.getAudioInputStream(file);
//get the AudioFormat for the AudioInputStream
AudioFormat audioformat = ais.getFormat();
System.out.println("Format: " + audioformat.toString());
System.out.println("Encoding: " + audioformat.getEncoding());
System.out.println("SampleRate:" + audioformat.getSampleRate());
System.out.println("SampleSizeInBits: " + audioformat.getSampleSizeInBits());
System.out.println("Channels: " + audioformat.getChannels());
System.out.println("FrameSize: " + audioformat.getFrameSize());
System.out.println("FrameRate: " + audioformat.getFrameRate());
System.out.println("BigEndian: " + audioformat.isBigEndian());
//ULAW format to PCM format conversion
if ((audioformat.getEncoding() == AudioFormat.Encoding.ULAW)
|| (audioformat.getEncoding() == AudioFormat.Encoding.ALAW)) {
AudioFormat newformat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
audioformat.getSampleRate(),
audioformat.getSampleSizeInBits() * 2,
audioformat.getChannels(),
audioformat.getFrameSize() * 2,
audioformat.getFrameRate(), true);
ais = AudioSystem.getAudioInputStream(newformat, ais);
audioformat = newformat;
}
//checking for a supported output line
DataLine.Info datalineinfo = new DataLine.Info(SourceDataLine.class, audioformat);
if (!AudioSystem.isLineSupported(datalineinfo)) {
//System.out.println("Line matching " + datalineinfo + " is not supported.");
} else {
//System.out.println("Line matching " + datalineinfo + " is supported.");
//opening the sound output line
SourceDataLine sourcedataline = (SourceDataLine) AudioSystem.getLine(datalineinfo);
sourcedataline.open(audioformat);
sourcedataline.start();
//Copy data from the input stream to the output data line
int framesizeinbytes = audioformat.getFrameSize();
int bufferlengthinframes = sourcedataline.getBufferSize() / 8;
int bufferlengthinbytes = bufferlengthinframes * framesizeinbytes;
byte[] sounddata = new byte[bufferlengthinbytes];
int numberofbytesread = 0;
while ((numberofbytesread = ais.read(sounddata)) != -1) {
int numberofbytesremaining = numberofbytesread;
sourcedataline.write(sounddata, 0, numberofbytesread);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
问题是,我的整个程序会停止,直到声音文件完成,或者至少接近完成
第二种方法是:
File file = new File("Launch1.wav");
AudioClip clip;
try {
clip = JApplet.newAudioClip(file.toURL());
clip.play();
} catch (Exception e) {
e.getMessage();
}
我在这里遇到的问题是,每次声音文件提前结束或根本不播放都取决于我放置代码的位置
他们有没有办法在没有上述问题的情况下播放声音?我做错什么了吗?非常感谢您的帮助。我想您应该在文档中提到的后台线程中运行playSound方法 你可能会想调用这个 在单独的线程中播放循环 从应用程序的其余部分 程序,这样你的程序就不会 在玩长距离游戏时出现冻结 声音 也许通过做类似的事情
// shared executor
ExecutorService soundExecutor = ...; //Executors.newSingleThreadExecutor();
...
final File soundFile = ...;
soundExecutor.submit(new Runnable(){
public void run(){
SoundUtils.playSoundFile(soundFile);
}
});
我想你应该在后台线程中运行playSound方法,如文档中所述 你可能会想调用这个 在单独的线程中播放循环 从应用程序的其余部分 程序,这样你的程序就不会 在玩长距离游戏时出现冻结 声音 也许通过做类似的事情
// shared executor
ExecutorService soundExecutor = ...; //Executors.newSingleThreadExecutor();
...
final File soundFile = ...;
soundExecutor.submit(new Runnable(){
public void run(){
SoundUtils.playSoundFile(soundFile);
}
});
问题是,我的整个程序会停止,直到声音文件完成,或者至少接近完成
这就引出了线程问题。你试过在背景线中播放声音吗?顺便问一下,这是一个Swing程序吗?如果是这样,请使用SwingWorker播放声音。原因有很多,但一个主要原因是通过SwingWorker内置的PropertyChangeListener支持很容易跟踪线程的状态
问题是,我的整个程序会停止,直到声音文件完成,或者至少接近完成
这就引出了线程问题。你试过在背景线中播放声音吗?顺便问一下,这是一个Swing程序吗?如果是这样,请使用SwingWorker播放声音。原因有很多,但一个主要原因是通过SwingWorker内置的PropertyChangeListener支持很容易跟踪线程的状态。对于第一种方法,您必须为音频创建另一个线程 例如:
new Thread(
new Runnable() {
public void run() {
try {
// PLAY AUDIO CODE
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
当然,您必须确保之前的声音没有继续播放。对于第一种方法,您必须为音频创建另一个线程 例如:
new Thread(
new Runnable() {
public void run() {
try {
// PLAY AUDIO CODE
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
当然,您必须确保前一个声音没有继续播放。您应该创建一个线程来处理音频播放。但是要确保它能够混合声音,这样两个镜头在彼此之后可以在正确的时间播放它们的声音,而不必等待之前的声音结束。 应该有框架为你做混合 一个好的起点是:
您应该创建一个线程来处理音频播放。但是要确保它能够混合声音,这样两个镜头在彼此之后可以在正确的时间播放它们的声音,而不必等待之前的声音结束。 应该有框架为你做混合 一个好的起点是:
我们可以为此线程创建一个简短的方法吗?如果我们在周围使用它,它看起来相当大:当然,用某种方法把它包起来。它不是一个阻塞函数。我们能为这个线程创建一个短方法吗?如果我们在周围使用它,它看起来相当大:当然,用某种方法把它包起来。它不是一个阻塞函数。