我正在尝试在我的Java游戏中播放.wav格式的歌曲,这里是SoundPlayer
类的一些代码:
private static HashMap<String, Clip> clips;
private static int gap;
public static void init() {
clips = new HashMap<String, Clip>();
gap = 0;
}
public static void load(String s, String n) {
if(clips.get(n) != null) return;
Clip clip;
try {
InputStream in = SoundPlayer.class.getResourceAsStream(s);
InputStream bin = new BufferedInputStream(in);
AudioInputStream ais = AudioSystem.getAudioInputStream(bin);
AudioFormat baseFormat = ais.getFormat();
AudioFormat decodeFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
AudioInputStream dais = AudioSystem.getAudioInputStream(decodeFormat, ais);
clip = AudioSystem.getClip();
clip.open(dais);
clips.put(n, clip);
} catch(Exception e) {
e.printStackTrace();
}
}
当我调用load()方法时,它在行clip.open(dais)
上崩溃并且我收到了以下错误:
javax.sound.sampled.LineUnavailableException: Failed to allocate clip data: Requested buffer too large.
这适用于短音效,所以我猜这是因为文件超过一分钟。有没有更好的方法来做到这一点?
谢谢!
答案 0 :(得分:2)
过去我在使用Java工作时遇到了麻烦。这是加载.wav soundclips的好方法。
private Clip clip;
public Sound(String fileName)
{
try
{
File file = new File(fileName);
if (file.exists())
{
AudioInputStream sound = AudioSystem.getAudioInputStream(file);
clip = AudioSystem.getClip();
clip.open(sound);
}
else
{
throw new RuntimeException("Sound: file not found: " + fileName);
}
}
catch (UnsupportedAudioFileException e)
{
e.printStackTrace();
throw new RuntimeException("Sound: Unsupported Audio File: " + e);
}
catch (IOException e)
{
e.printStackTrace();
throw new RuntimeException("Sound: Input/Output Error: " + e);
}
}
public void play()
{
clip.setFramePosition(0);
clip.start();
}
public void loop()
{
clip.loop(Clip.LOOP_CONTINUOUSLY);
}
public void stop()
{
clip.stop();
}
我发现这很棒!如果您愿意,还可以添加更多异常,例如LineUnavailableException和MalformedURLException。要创建声音片段,您可以这样做:
private Sound sound = new Sound("/sounds/sound.wav");
然后做
sound.play();
答案 1 :(得分:0)
我不知道你为什么要手动解码AudioFormat
。
我通常会使用类似......
的内容try (InputStream is = new BufferedInputStream(new FileInputStream(SoundPlayer.class.getResourceAsStream(s)))) {
AudioInputStream audioStream = AudioSystem.getAudioInputStream(is);
AudioFormat format = audioStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(audioStream);
clip.start();
try {
Thread.sleep(250);
} catch (InterruptedException ex) {
}
clip.drain();
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException ex) {
ex.printStackTrace();
}
注意,这将阻止,直到Clip
耗尽,一直播放结束。我测试了5分48秒的音乐文件。我使用上面的代码以及你成功的代码,但坦率地说,我使用的代码更简单(不那么复杂 - 简单==好:):)
说完这一切后,实际上并不需要try (InputStream is = new BufferedInputStream(new FileInputStream(SoundPlayer.class.getResourceAsStream(s)))) {
,因为AudioSystem.getAudioInputStream(...);
可以接受URL
和File
引用,例如......
try {
AudioInputStream audioStream = AudioSystem.getAudioInputStream(
SoundPlayer.class.getResourceAsStream(s))));