[英]how can I wait for a java sound clip to finish playing back?
我正在使用以下代码使用 java 声音 API 播放声音文件。
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(stream);
clip.open(inputStream);
clip.start();
对 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 );
}
在 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();
你可以把这个代码改为:
假设您的剪辑 1 正在播放并且您希望在此之后播放剪辑 2,您可以:
clip1.start();
while(clip1.getMicrosecondLength() != clip1.getMicrosecondPosition())
{
}
clip2.loop(some int here);
并且,为了在不延迟主要任务的情况下完成这项工作(我这么说是因为 while 循环使工作等待 clip1 完成,无论下一个工作是什么......)希望它发生,只需将代码放在它的 run() 方法中......祝你好运!
声音剪辑是一种类型或 Line,因此支持 Line 侦听器。
如果你使用 addLineListener,你应该在播放开始和停止时获取事件; 如果您不在循环中,则应在剪辑结束时停止。 但是,与任何事件一样,在实际播放结束和停止之前可能会有延迟。
使方法等待稍微有点棘手。 您可以忙等待它(不是一个好主意)或使用其他同步机制。 我认为有一种模式(不确定)用于等待长时间操作以引发完成事件,但这是一个一般性问题,您可能希望单独发布到 SO。
从 JDK8 开始, Clip
的侦听器有点问题(即它可能会为单个音频( .start()
)触发两次 Type.STOP 。
因此,我会使用类似的东西:
Clip[] myBunchOfClipsToPlaySequentially=new Clip[A_BUNCH];
//
// [load actual clips...]
// [...]
//
for(Clip c: myBunchOfClipsToPlaySequentially)
while(c.getFramePosition()<c.getFrameLength())
Thread.yield(); // Note that if we simply put a NO-OP instead (like a
// semicolon or a {}), we make our CPU
// cry). Thread.yield() allows for almost 0% CPU consumption.
此外,您可以看看 JFX8 提供的新AudioClip类(有一些漂亮的方法可以摆弄)
我使用了等待/通知来实现这一点。 仅供参考。
final Clip clip = AudioSystem.getClip(mixerInfo);
clip.addLineListener(new LineListener(){
@Override
public void update(LineEvent e) {
if (e.getType()==LineEvent.Type.STOP){
synchronized(clip){
clip.notifyAll();
}
System.err.println("STOP!");
}
}
});
clip.open(as);
clip.start();
while (true){
synchronized(clip){
clip.wait();
}
if (!clip.isRunning()){
break;
}
}
clip.drain();
clip.stop();
clip.close();
不知道我是否可以为其他人说话,这个线程很老了。 但是我使用剪辑库来播放我的 .wav 文件,然后在声音文件运行的时间内让线程休眠:
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
System.out.println("Clip Started");
Thread.sleep(162000); //Length of time in milliseconds
System.out.println("Clip finished");
对我来说就像一个魅力,我正在监控我的处理器,整个程序最多使用了 4%!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.