Search code examples
javajavafxmediapause

JavaFX Media - pause(); method makes MediaPlayer fast-forward?


the pause() method of MediaPlayer makes the Media "seek" a bit. It's really annoying but I didn't find out where the problem is.

    private void playPauseClicked() 
    {     
        Status currentStatus = player.getStatus();
        if(currentStatus == Status.PLAYING)
        {
            Duration d1 = player.getCurrentTime(); //To measure the difference
            player.pause();
            Duration d2 = player.getCurrentTime();
            VIDEO_PAUSED = true;
        }
        else if(currentStatus == Status.PAUSED || currentStatus == Status.STOPPED)
        {
            player.play();
            VIDEO_PAUSED = false;
        }
    }

The result is not clear, it's something about 200-400ms difference between spot d1 and d2.

Of course I tried to seek my player back to d1 after pausing the media, didn't work, same result after resuming the media.

Thanks in advance for any advice :)


Solution

  • It's because the pause method does not stop the playing instantly (when pause is called, the media still plays and stops exactly at the moment when the statusProperty changes):

    Pauses the player. Once the player is actually paused the status will be set to MediaPlayer.Status.PAUSED.

    Therefore the measurements are not really relevant, because when you get the current time Duration d1 = player.getCurrentTime(); before the pause, the playing is not actually paused and also when you get the current time after the call of pause with Duration d2 = player.getCurrentTime(); is not correct, as pause has been executed asynchronously therefore there is no garantie that at d2 the video stopped to play:

    The operation of a MediaPlayer is inherently asynchronous.

    What you could do to get the correct time when the playing is stopped is to observe the changes of the status of the MediaPlayer using e.g. setOnPaused.

    Example:

    private void playPauseClicked() {
        Status currentStatus = player.getStatus();
    
        if(currentStatus == Status.PLAYING)
            player.pause();
        else if(currentStatus == Status.PAUSED || currentStatus == Status.STOPPED) {
            System.out.println("Player will start at: " + player.getCurrentTime());
            player.play();
        }
    }
    
    player.setOnPaused(() -> System.out.println("Paused at: " + player.getCurrentTime()));
    

    Sample output:

    Paused at: 1071.0203000000001 ms
    Player will start at: 1071.0203000000001 ms
    Paused at: 2716.7345 ms
    Player will start at: 2716.7345 ms
    

    Note: However it is not needed to set the time of the MediaPlayer in the case if you just want to stop and play, but if you want to you can use seek method.