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<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 ); }
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.