我如何等待java声音片段完成播放?

Pan*_*ros 7 java javasound

我使用以下代码使用java声音API播放声音文件.

    Clip clip = AudioSystem.getClip();
    AudioInputStream inputStream = AudioSystem.getAudioInputStream(stream);
    clip.open(inputStream);
    clip.start();
Run Code Online (Sandbox Code Playgroud)

调用Clip.start()方法的方法立即返回,系统在后台线程中播放声音文件.我希望我的方法暂停,直到播放完成.

有没有好办法呢?

编辑:对于对我的最终解决方案感兴趣的每个人,根据Uri的答案,我使用下面的代码:

private final BlockingQueue<URL> queue = new ArrayBlockingQueue<URL>(1);

public void playSoundStream(InputStream stream) {
    Clip clip = AudioSystem.getClip();
    AudioInputStream inputStream = AudioSystem.getAudioInputStream(stream);
    clip.open(inputStream);
    clip.start();
    LineListener listener = new LineListener() {
        public void update(LineEvent event) {
                if (event.getType() != Type.STOP) {
                    return;
                }

                try {
                    queue.take();
                } catch (InterruptedException e) {
                    //ignore this
                }
        }
    };
clip.addLineListener(listener );
}
Run Code Online (Sandbox Code Playgroud)

san*_*o21 8

在 Java 8 中我更喜欢这种方式:

CountDownLatch syncLatch = new CountDownLatch(1);

try (AudioInputStream stream = AudioSystem.getAudioInputStream(inStream)) {
  Clip clip = AudioSystem.getClip();

  // Listener which allow method return once sound is completed
  clip.addLineListener(e -> {
    if (e.getType() == LineEvent.Type.STOP) {
      syncLatch.countDown();
    }
  });

  clip.open(stream);
  clip.start();
}

syncLatch.await();
Run Code Online (Sandbox Code Playgroud)


小智 6

你可以把这个代码改为:

假设你的clip1正在播放,你想要在那之后播放一个clip2,你可以:

clip1.start();
while(clip1.getMicrosecondLength() != clip1.getMicrosecondPosition())
{
}
clip2.loop(some int here);
Run Code Online (Sandbox Code Playgroud)

并且,为了使这项工作不延迟你的主要任务(我说这是因为while循环使得工作等待clip1完成,无论接下来的工作是什么......)你可以在你的位置创建一个新线程希望它发生,只需将代码放在run()方法中......好运!


Uri*_*Uri 5

声音剪辑是一种类型或 Line,因此支持 Line 侦听器。

如果您使用addLineListener,您应该在播放开始和停止时获取事件;如果您没有处于循环状态,则应该在剪辑结束时停止。但是,与任何事件一样,在实际播放结束和停止之前可能会有延迟。

让方法等待稍微棘手一些。您可以忙等待(这不是一个好主意)或使用其他同步机制。我认为有一种模式(不确定)用于等待长时间操作以引发完成事件,但这是您可能需要单独发布到 SO 的一般问题。