Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我一次播放多个音频有问题_Java_Audio - Fatal编程技术网

Java 我一次播放多个音频有问题

Java 我一次播放多个音频有问题,java,audio,Java,Audio,**因此,我在游戏中播放了大量音频,我认为这是一个问题,而如果我在同一个60秒内播放两个音频,则会弹出一个错误并将游戏冻结半秒 我是否可以确定剪辑何时开始播放,以便停止下一个剪辑 (我想看剪辑何时开始播放,而不是何时播放) (但这对我来说也很有趣) 有没有比这更好的音频播放方式 剪辑设计为不能同时打开和启动。在从磁盘加载整个文件之前,它们甚至不会开始播放。我猜,如果您尝试在显示的代码中同时播放两个,那么文件加载延迟问题将变得更加复杂 相反,您可以(也应该)做的是预先初始化您的剪辑,包括打开它

**因此,我在游戏中播放了大量音频,我认为这是一个问题,而如果我在同一个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();
    }