1

I am making a mp3Player in java with the library from javazoom. I have manged to start and stop the mp3 but i cant resume it. Does anyone know how to do this?

Here is the MP3Player class:

public class MP3Player extends JFrame{

public MP3Player(){
    JPanel jpBottom = new JPanel();
    JButton btnPlay = new JButton("Play");
    JButton btnPause = new JButton("Pause");

    jpBottom.add(btnPause);
    jpBottom.add(btnPlay);

    Container cp = this.getContentPane();
    BorderLayout bl = new BorderLayout();
    cp.setLayout(bl);
    cp.add(jpBottom, BorderLayout.SOUTH);

    btnPlay.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if(t.isInterrupted()){
                        t.resume();
                    } else{
                        t.start();
                    }
                }
            }
    );

    btnPause.addActionListener(
            new ActionListener() {
                public void actionPerformed(ActionEvent e){
                   t.interrupt();
                }
            }
    );

    this.setVisible(true);
    this.setSize(250, 100);
    this.setTitle("MP3 Player");
    this.setLocation(100, 100);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

Thread t = new Thread(new PlayerThread("file:///C://a.mp3"));

public static void main(String[] args) {
    MP3Player n = new MP3Player();
}
}

The PlayerThread class:

public class PlayerThread implements Runnable{

    String path;
    PlayerThread(String path){
        this.path = path;
    }

    public void run(){
        try{
            URL url = new URL(path);
            InputStream in = url.openStream();
            AdvancedPlayer pl = new AdvancedPlayer(in);
            pl.play();
        }
        catch(Exception e){
            System.out.println("Error: "+e);
        }
    }

    public void pause(){
        Thread.interrupted();
    }
}
Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
Twistar
  • 782
  • 5
  • 21
  • 35
  • 1
    Most likely, your `PlayerThread` implementation, whatever it is, has no idea that [interrupt](http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html) is supposed to cause it to pause. – David Schwartz May 31 '12 at 10:58
  • 1
    The problem has nothing to do with the GUI, and all to do with the PlayerThread. Yet you show us only the GUI. And please read the javadoc of Thread to know what those methods do, and notice you shouldn't use resume(). http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html. Also, interrupt() is not meant to pause a thread. – JB Nizet May 31 '12 at 10:58
  • I provided sample code for a pause/resume scenario for threads [here](http://stackoverflow.com/a/10669623/823393). It uses a `ReadWriteLock`. – OldCurmudgeon May 31 '12 at 11:19

3 Answers3

2

It looks like you're making a lot of assumptions that things will "just work", without reading the APIs for the libraries you're using.

Firstly, interrupting a thread simply sets a flag on that thread. By convention, blocking calls will usually inspect this flag periodically and terminate early by throwing an InterruptedException if that is the case. But that's not an automatic guarantee, and a caller cannot forcibly interrupt another thread. You need to ensure that interruption will do what you expect.

Your pause() method is doubly wrong in that you're not even setting the interrupted flag; Thread.interrupted() checks whether the current thread is interrupted (returning a boolean).

Let's go back to basics - you're playing sound by calling AdvancedPlayer.play(). How do you get an AdvancedPlayer to pause? Looking through its documentation, it seems like it doesn't support pausing in any obvious way. (There's a stop() method but I don't believe it would resume from the same place). And since the method doesn't throw InterruptedException, it's almost guaranteed that it doesn't respond to interrupts.

However, there is a BasicPlayer class that does have a pause. Is there any reason why you couldn't use that instead, something like (ignoring exceptions):

public class PlayerThread implements Runnable{
    final BasicPlayer player;

    PlayerThread(String path){
        player = new BasicPlayer(new URL(path).openStream());
    }

    public void run(){
        player.player();
    }

    public void pause() {
        player.pause();
    }
}
Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
1

First, fhe Thread.interrupted() tests to see if the thread has been interrupted. It doesn't interrupt it.

Second, the effect of interrupting an AdvancedPlayer instance is not defined by the javadocs.

Third, it looks like the way you are supposed to stop the player is by calling stop(), but there is no specified way to pause.


is that done with Thread.stop()?

Thread.stop() stops the Java thread, but that doesn't mean that the player will stop playing. That depends on how the player library code is implemented.

Furthermore, Thread.stop() is a deprecated API, which can cause all sorts of problems if you use it.


FWIW, the javazoom APIs look a bit of a mess to me, and the libraries don't appear to have been touched for ~10 years. Have you considered looking for something that is more uptodate and better engineered?

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    @Twistar: read the javadoc. stop() is deprecated and should never be used. Documentation is there to be read. – JB Nizet May 31 '12 at 11:11
  • `Thread.stop()` is deprecated ([for good reason](http://docs.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html)). You set *the interrupted flag* on a thread by calling `interrupt()` on an instance of `Thread`. This still probably doesn't do what you expect/want though... – Andrzej Doyle May 31 '12 at 11:13
0

First of all you should stop using Thread.suspend and Thread.resume as they are deprecated and deadlock-prone. Instead you should have some sort of flag within PlayerThread e.g say isPaused set it to true or false on click on playBtn, based on flag should play or pause the music with playthread.Also please note that once thread becomes dead you can start it again, So i think starting thread within playBtns actionPerformed does not seems good idea ( although i m not aware of your entire design)

Jitendra Vispute
  • 709
  • 8
  • 18