Java 我一次播放多个音频有问题
**因此,我在游戏中播放了大量音频,我认为这是一个问题,而如果我在同一个60秒内播放两个音频,则会弹出一个错误并将游戏冻结半秒Java 我一次播放多个音频有问题,java,audio,Java,Audio,**因此,我在游戏中播放了大量音频,我认为这是一个问题,而如果我在同一个60秒内播放两个音频,则会弹出一个错误并将游戏冻结半秒 我是否可以确定剪辑何时开始播放,以便停止下一个剪辑 (我想看剪辑何时开始播放,而不是何时播放) (但这对我来说也很有趣) 有没有比这更好的音频播放方式 剪辑设计为不能同时打开和启动。在从磁盘加载整个文件之前,它们甚至不会开始播放。我猜,如果您尝试在显示的代码中同时播放两个,那么文件加载延迟问题将变得更加复杂 相反,您可以(也应该)做的是预先初始化您的剪辑,包括打开它
剪辑设计为不能同时打开和启动。在从磁盘加载整个文件之前,它们甚至不会开始播放。我猜,如果您尝试在显示的代码中同时播放两个,那么文件加载延迟问题将变得更加复杂 相反,您可以(也应该)做的是预先初始化您的剪辑,包括打开它们,并将它们保存在内存中,以备使用。到了播放它们的时候,您应该只执行以下操作:
package me.Warrior;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.FloatControl;
public class SoundPlayer {
static URL path=null;
static AudioInputStream inputStream;
public static Clip clip;
public static synchronized void Play(final String url,float Volume) {
new Thread(new Runnable() {
public void run() {
try {
clip = AudioSystem.getClip();
URL resource = getClass().getClassLoader().getResource(url);
path=resource;
inputStream = AudioSystem.getAudioInputStream(path);
clip.open(inputStream);
setVolume(Volume,clip);
clip.start();
} catch (Exception e) {
}
}
}).start();
}
public static void setVolume(float Volume,Clip clip) {
FloatControl gainControl =
(FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
float dB=(float)(Math.log(Volume)/Math.log(10)*20);
gainControl.setValue(dB);
}
}
通过将帧位置设置为起始位置,可以重复使用剪辑
,而无需反复加载
但如果您不想用光存储音频的内存,请使用SourceDataLine
进行播放。在SourceDataLine
开始播放之前,只从磁盘加载一个缓冲区的数据(而不是等待整个文件加载)
这两种文件类型都不能很好地进行并行播放(同时播放两次或更多次),但是如果您正确地执行了上述操作,声音应该会很好地开始播放。如果仍然存在问题,或者如果您不满意MASTER_增益线有多笨重,可以尝试使用几个简单的库。一个叫,另一个叫。我偏爱后者(因为我写了它),它确实可以处理并发播放,并且比Clip
对音量有更细粒度的实时控制
这是一个非常常见的问题,很多原因是关于音频的Java教程很难阅读,因此人们忽略了这些重要的细节。我猜很多其他的志愿者教程作者在强调最佳实践方面做得并不好,他们只满足于得到一个声音播放,而不去理会它
编辑:重新阅读您的问题——有一个名为LineListener
的类,如果您想进一步了解该方面,它可以接收有关剪辑开始或停止的通知
此外,如果您收到实际的错误消息,请发布它们!这将有助于确定原因和解决方案。谢谢,我不知道,我会尝试,是的,我不介意浪费一点内存,毕竟这是一个小游戏,所以这意味着我应该预先打开/加载所有音频,并在必要时从一开始就开始播放(因为加载需要很多时间,如果我理解正确的话,这就是我的游戏冻结的原因)很难说,但从你所说的,我觉得这可能是个问题。你必须尝试一下,看看它是否有帮助。剪辑被设计成在内存中保持开放,所以你将改变一个更好的实践。我会考虑让FloatControl成为一个类级别的字段变量,而不是本地的。但是它并不是成本的近处。另外,我还添加了一些小的编辑,用于跟踪音频事件和错误消息。
public void playMyAudioFX() {
myAudioFX.setFramePosition(0);
myAudioFX.start();
}