JavaFx MediaPlayer playing one mp3 every hour


Question

I have following code:

    Task<Integer> task = new Task<Integer>() {
        @Override
        protected Integer call() throws Exception {
            Calendar tajm = Calendar.getInstance();
            int hour = tajm.get(Calendar.HOUR_OF_DAY);
            int minutes = 0;
            updateMessage(Integer.toString(hour));
            URL resource = getClass().getResource("classico.mp3");
            Media media = new Media(resource.toString());
            MediaPlayer mediaPlayer = new MediaPlayer(media);

            while (true) {
                try {
                    Thread.sleep(60000);
                    tajm = Calendar.getInstance();
                    if (tajm.get(Calendar.HOUR_OF_DAY) != hour) {
                        hour = tajm.get(Calendar.HOUR_OF_DAY);
                        updateMessage(Integer.toString(hour));
                        System.out.println("Hour has changed to: " + hour);

                        mediaPlayer.play();
                    } else {
                        hour = tajm.get(Calendar.HOUR_OF_DAY);
                        System.out.println("Hour has not changed, it's still: " + hour);
                        updateMessage(Integer.toString(hour));
                    }
                } catch (InterruptedException ie) {
                    //System.err.print("...");
                }
            }
        }
    };

The song plays only one time, at first change of hour. Any idea why?

I have one additional question, not related: is this normal that my javafx programs takes like 20 seconds to start? It's kind of annoying;p Normal applications, with only JavaSE starts almost immedietally.

1
0
8/29/2013 12:30:49 PM

Accepted Answer

Suggested Alternate Approach - Create a new player as needed

I'd advise creating a new MediaPlayer each time you want to play your mp3, rather than reusing an existing MediaPlayer. By creating a new MediaPlayer each time, you only need to consume the media playing resources when you need them, rather than allocating them and letting them set idle between play times.

For example, call all of the media related calls together rather than at separate points, and let the garbage collector throw away the media resources when they are no longer required.

Media media = new Media(resource.toString());
MediaPlayer mediaPlayer = new MediaPlayer(media);
mediaPlayer.play();

How to reuse an existing player (if required)

If you do want to use your current code rather and reuse the same media player, then you can place a couple of calls before your play call to ensure that on subsequent play calls the player tries to play the mp3 from the start rather than the end (which results in a no-op).

mediaPlayer.setStartTime(Duration.ZERO);
mediaPlayer.seek(Duration.ZERO);
mediaPlayer.play();

Suggestion - Periodically trigger playing your mp3 using a Timeline rather than a Task

You don't really need a separate thread and task which adds a bit more complication, you can use a Timeline to trigger the play event each hour.

2
12/15/2015 8:28:01 AM

Try using mediaPlayer.playFromStart()

Also: any unchecked exception thrown from inside your while loop will exit your program. As a test you can change your current catch(InterruptedException) to catch(Throwable) and print the error to see if that is the case.

Another approach would be to use a sheduled executor to execute your task (See Javadoc for SceduleThreadPooExecutor)


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon