java无法播放整个音频片段
我用javax.sound.sampled.Clip
在游戏中播放音效(WAV文件)。但是,有2秒的效果并不是全部播放,只是部分播放。如果添加clip.loop(2)
,则声音会正确播放多次,即整整2秒钟。有什么问题,如何解决
package com.zetcode;
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JOptionPane;
public enum SoundEffect {
EXPLODE("resources/explosion.wav"),
HITGROUND("resources/impact.wav"),
CANNON("resources/cannon.wav");
private Clip clip;
SoundEffect(String soundFileName) {
try {
URL url = this.getClass().getClassLoader().getResource(soundFileName);
try (AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(url)) {
clip = AudioSystem.getClip();
clip.open(audioInputStream);
}
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
JOptionPane.showMessageDialog(null, "Cannot play sound", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
public void play() {
if (clip.isRunning()) {
clip.stop();
}
clip.setFramePosition(0);
clip.start();
}
static void init() {
values();
}
}
# 1 楼答案
您是否知道并解释了这样一个事实:当播放片段时(通过start()方法),播放代码的线程是一个守护进程?与常规线程不同,守护进程线程不会阻止Java程序关闭。如果程序在声音完成执行之前结束,则守护进程状态线程也会结束,即使它尚未完成
您是否正在尝试运行示例代码SoundClipTest或SoundEffectDemo?在我看来,SoundClipTest将在程序执行start()方法后立即退出,而SoundEffectDemo将保持并允许声音完成播放
**编辑1**
我刚才注意到您已经将SoundEffect设置为枚举。我以前从未见过这种方法
我使用的一种方法是创建一个名为GameSound的类,让它的构造函数分别预加载每个片段,并将它们保存在内存中,以便播放。然后,我创建了一个或多个播放方法
GameSound类将为每个声音效果提供实例变量
游戏声音构造器应该有:
游戏声音会有一个方法:
如果您喜欢让play方法获取一个参数,并在switch结构上使用该参数来选择要播放的声音,这也很好,特别是因为它消除了一些代码重复
这种方法可能会更好(随着代码变得更复杂,很容易添加到游戏声音中),而且编写代码也不会太难。我很想知道改变这个计划是否能解决这个问题
**编辑2**
对不起,上面的代码有错误。我在制作以下示例时修复了它们。不过,有一种想法是,当我去听你链接的音效时,有几次爆炸一开始就被截断了。您是否在其他应用程序(如Windows Groove Music,或从您获得这些声音的网站)中播放了这些声音,并在代码中播放时验证了它们是否不同
这是一个快速的“游戏声音”。我下载了爆炸+2。wav文件来自您的参考,因为它比其他文件长,并且有一个清晰的结尾,我正在参考它
这里有一个简单的Swing按钮,可以调用GameSound
当然,所有这些都假设有一个名为“resources”的子文件夹,其中包含爆炸式SFX