如何开始播放已播放的声音?

时间:2016-07-27 10:55:20

标签: java audio

我正在进行游戏扩展以播放一些声音。声音可以在随机时间触发,这意味着相同的声音可以在很短的时间间隔内被触发两次。在这种情况下,声音应该开始播放,即使它已经播放(如果这是有道理的)。

我正在使用Clip播放声音。这意味着我必须在播放之前“回放”剪辑。似乎,因为它是相同的剪辑,它在重新启动之前停止播放。我想要的是继续播放,并在普通话的“顶部”播放相同的片段。见这个例子:

import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class JavaApplication {

    public static void main(String[] args) throws Exception {
        File file = new File(JavaApplication.class.getResource("1.wav").getPath());
        AudioInputStream inputStream = AudioSystem.getAudioInputStream(file);

        Clip clip = AudioSystem.getClip();
        clip.open(inputStream);
        clip.setFramePosition(0);
        clip.start(); // The sound is 300 ms long
        Thread.sleep(150); // Let it play for 150 ms
        clip.setFramePosition(0); // Attempt to start it from the beginning, without stopping it
        clip.start();
        Thread.sleep(1000);
    }
}

3 个答案:

答案 0 :(得分:0)

您是否尝试在需要时创建重复对象并在完成后将其销毁?一个新的Clip对象或只是复制原始文件并将其与它一起播放。

 Clip temp = clip;
 temp.start(); // The sound is 300 ms long
 Thread.sleep(150); // Let it play for 150 ms
 temp = null;

只是一个建议,你也可以尝试使用Clip []数组来处理在不同时间播放的几个片段。

答案 1 :(得分:0)

您需要创建两个AudioInputStream个实例。无需在代码中明确使用多线程。跳它会有所帮助。感谢。

import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class JavaApplication {

    public static void main(String[] args) throws Exception {

        File file = new File(JavaApplication.class.getResource("1.wav").getPath());
        AudioInputStream inputStream1 = AudioSystem.getAudioInputStream(file);
        AudioInputStream inputStream2 = AudioSystem.getAudioInputStream(file);

        Clip clip = AudioSystem.getClip();
        clip.open(inputStream1);
        clip.setFramePosition(0);
        clip.start();

        // Clip is 2000 ms long. let it play for 1000 ms
        Thread.sleep(1000);

        Clip clip2 = AudioSystem.getClip();
        clip2.open(inputStream2);
        clip2.setFramePosition(0);
        clip2.start();

        Thread.sleep(2000);

    }
}

答案 2 :(得分:0)

找到解决方案:读取声音的原始字节,并在每次播放声音时根据数据创建输入流。这使我能够在自己的基础上播放相同的声音文件"无需多次从磁盘加载。

package com.mysite.javaapplication;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;

public class JavaApplication {

    private static void playSoundBytes(byte[] data) throws Exception {
        AudioInputStream inputStream = AudioSystem.getAudioInputStream(new ByteArrayInputStream(data));
        AudioFormat format = inputStream.getFormat();
        Clip clip = AudioSystem.getClip();
        clip.open(inputStream);
        clip.setFramePosition(0);
        clip.start();
    }

    private static byte[] getResourceAsBytes(String name, int bufferSize) throws IOException {
        InputStream stream = JavaApplication.class.getResourceAsStream(name);
        byte buffer[] = new byte[bufferSize];
        int b, i = 0;
        while ((b = stream.read()) != -1) {
            try {
                buffer[i++] = (byte) b;
            } catch (IndexOutOfBoundsException e) {
                throw new IOException("Buffer of " + bufferSize + " bytes is too small to read resource \"" + name + "\"");
            }
        }
        byte data[] = new byte[i + 1];
        while (i >= 0) {
            data[i] = buffer[i];
            i--;
        }
        return data;
    }

    public static void main(String[] args) throws Exception {

        byte[] soundData = getResourceAsBytes("/1.wav", 1000*1000);
        playSoundBytes(soundData);
        Thread.sleep(1000);
        playSoundBytes(soundData);
        Thread.sleep(2000);
    }
}