How to halt a clip/object in a certain time?

258 Views Asked by At

Hi Stackoverflow!

So basically, I have two audio clips going on in my Java program and I want one of them to stop at a certain time and the other to start at a certain time.

I'll try to explain the code the best I can. http://pastebin.com/1zGdb30x Music.java

    package testingground;


import java.io.IOException;
import java.net.URL;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;


public class Music {
    public void musictwo() {
        URL url;
        try {
            url = new URL("file:///D:/Yes/GUI/song.wav");
             Clip clip = AudioSystem.getClip();
            AudioInputStream ais = AudioSystem.
              getAudioInputStream( url );
            clip.open(ais);
            clip.loop(100);

        } catch (UnsupportedAudioFileException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (LineUnavailableException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


    public void musicone() {
        URL url;
        try {
            url = new URL("file:///D:/Yes/GUI/rival.wav");
            Clip clip = AudioSystem.getClip();
            AudioInputStream ais = AudioSystem.
              getAudioInputStream( url );
            clip.open(ais);
            clip.loop(100);
        } catch (UnsupportedAudioFileException | IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (LineUnavailableException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

http://pastebin.com/nGm4DZfr Program.java

package testingground;

import javax.swing.JOptionPane;

public class Program {
    public static void main(String[] args) {
        System.out.println("The first song should play now!");
        Music a = new Music();
        a.musicone();
        System.out.println("The second song should play now!");
        a.musictwo();
        JOptionPane.showMessageDialog(null,"Press 'ok' to end the application.");
    }
}

In Music.java, I have the audio files working and they are only local .wav files that are only available on my computer. In program.java, the output is musicone and musictwo both play at the same time. Is there a way so that muscone plays, stops, then musictwo plays?

Things I have tried- - Have an if and else statement in program.java to execute clip.stop(). No errors, it just didn't work. - Have an if and else boolean from program.java to execute clip.stop() in Music.java. No syntax errors, it just didn't work.

1

There are 1 best solutions below

4
On BEST ANSWER

The way I understand your question, you can use a LineListener.

Just, for example, here is a class that goes through a List, playing the next stream each time the current one completes:

class Playlist implements LineListener {
    private final List<AudioInputStream> list = new ArrayList<>();
    private Clip clip;
    private int next;

    @Override
    public void update(LineEvent evt) {
        if(evt.getType() == LineEvent.STOP) {
            try {
                playNext();
            } catch(LineUnavailableException | IOException e) {
                e.printStackTrace();
            }
        }
    }

    void enqueue(AudioInputStream ais) {
        synchronized(this) {
            list.add(ais);
        }
    }

    void playNext() throws LineUnavailableException, IOException {
        synchronized(this) {
            if(list.isEmpty()) {
                throw new IllegalStateException();
            }
            if(clip != null) {
                if(clip.isRunning()) clip.stop();
                if(clip.isOpen()) clip.close();
            }

            clip = AudioSystem.getClip();
            clip.addLineListener(listener);
            try {
                clip.open(list.get(next));
            } finally {
                next = (next + 1) % list.size();
            }
            clip.start();
        }
    }
}