I am using the following code to play a sound file using the java sound API.
Clip clip = AudioSystem.getClip();
AudioInputStream inputStream = AudioSystem.getAudioInputStream(stream);
clip.open(inputStream);
clip.start();
The method call to the Clip.start() method returns immediately, and the system playbacks the sound file in a background thread. I want my method to pause until the playback has completed.
Is there any nice way to do it?
EDIT: For everyone interested in my final solution, based on the answer from Uri, I used the code below:
private final BlockingQueue queue = new ArrayBlockingQueue(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 );
}
解决方案
A sound clip is a type or Line and therefore supports Line listeners.
If you use addLineListener, you should get events when play starts and stops; if you’re not in a loop, you should get a stop when the clip ends. However, as with any events, there might be a lag before the actual end of playback and the stopping.
Making the method wait is slightly trickier. You can either busy-wait on it (not a good idea) or use other synchronization mechanisms. I think there is a pattern (not sure about it) for waiting on a long operation to throw a completion event, but that’s a general question you may want to post separately to SO.