Java JLayer: Problem with implementing Pausable Player

41 Views Asked by At

I am trying to implement and use a Pausable Player object based on the Advanced Player jlayer package. I am using the implementation found in this thread: https://stackoverflow.com/questions/12057214/jlayer-pause-and-resume-song/12060120#12060120 . Does anyone know what may be wrong with why it is not playing audio? My Public Player class is as follows:

package com.musicstreamingapp;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import javazoom.jl.player.advanced.AdvancedPlayer;
import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.AudioDevice;


public class PausablePlayer {

    private final static int NOTSTARTED = 0;
    private final static int PLAYING = 1;
    private final static int PAUSED = 2;
    private final static int FINISHED = 3;

    // the player actually doing all the work
    private final AdvancedPlayer player;

    // locking object used to communicate with player thread
    private final Object playerLock = new Object();

    // status variable what player thread is doing/supposed to do
    private int playerStatus = NOTSTARTED;

    public PausablePlayer(final InputStream inputStream) throws JavaLayerException {
        this.player = new AdvancedPlayer(inputStream);
    }

    public PausablePlayer(final InputStream inputStream, AudioDevice audioDevice) throws JavaLayerException {
        this.player = new AdvancedPlayer(inputStream, audioDevice);
    }

    /**
     * Starts playback (resumes if paused)
     */
    public void play() throws JavaLayerException {
        synchronized (playerLock) {
            switch (playerStatus) {
                case NOTSTARTED:
                    final Runnable r = new Runnable() {
                        public void run() {
                            playInternal();
                        }
                    };
                    final Thread t = new Thread(r);
                    //Got Rid of Line because Stack Overflow
                   // t.setDaemon(true);
                    t.setPriority(Thread.MAX_PRIORITY);
                    playerStatus = PLAYING;
                    t.start();
                    break;
                case PAUSED:
                    resume();
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * Pauses playback. Returns true if new state is PAUSED.
     */
    public boolean pause() {
        synchronized (playerLock) {
            if (playerStatus == PLAYING) {
                playerStatus = PAUSED;
            }
            return playerStatus == PAUSED;
        }
    }

    /**
     * Resumes playback. Returns true if the new state is PLAYING.
     */
    public boolean resume() {
        synchronized (playerLock) {
            if (playerStatus == PAUSED) {
                playerStatus = PLAYING;
                playerLock.notifyAll();
            }
            return playerStatus == PLAYING;
        }
    }

    /**
     * Stops playback. If not playing, does nothing
     */
    public void stop() {
        synchronized (playerLock) {
            playerStatus = FINISHED;
            playerLock.notifyAll();
        }
    }

    private void playInternal() {
        while (playerStatus != FINISHED) {
            try {
                //Added ret statement according to stack overflow
                boolean ret = player.play(1);
                if (!ret) {
                    break;
                }
            } catch (final JavaLayerException e) {
                break;
            }
            // check if paused or terminated
            synchronized (playerLock) {
                while (playerStatus == PAUSED) {
                    try {
                        playerLock.wait();
                    } catch (final InterruptedException e) {
                        // terminate player
                        break;
                    }
                }
            }
        }
        close();
    }

    /**
     * Closes the player, regardless of current state.
     */
    public void close() {
        synchronized (playerLock) {
            playerStatus = FINISHED;
        }
        try {
            player.close();
        } catch (final Exception e) {
            // ignore, we are terminating anyway
        }
    } {
    
}
}

This is how I instantiate the new Pausable Object:

   public static void playAudio(byte[] song) {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(song);
        try {

            PausablePlayer player = new PausablePlayer(byteArrayInputStream);
            player.play();
    
            //Pause and resume test
            Thread.sleep(5000); // Wait for 5 seconds before pausing
            player.pause();
            System.out.println("Paused Song");
            
            Thread.sleep(5000); // Wait for another 5 seconds before resuming
            player.resume();
            System.out.println("Resumed Song");
    
            // Close the player after playback
            Thread.sleep(5000); 
            player.stop();
        } catch (JavaLayerException | InterruptedException e) {
            e.printStackTrace();
            System.out.println("Error playing audio: " + e.getMessage());
        } 
0

There are 0 best solutions below