Some videos (of not uncommon conversion/format) will freeze if you seek too soon after they are loaded. The audio keeps playing in the background.
The issue is reproducible with both local and remote video files.
This is a regression as the problem occurs only starting JavaFX 14 (for Windows) and 15 (for MacOS).
N.B. On MacOS until JavaFX 14, the video plays after the long start up delay (JDK-8241629).
SSCCE with remote Video URLs:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.layout.FlowPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.Stage;
import javafx.util.Duration;
public class VideoSeekIssue extends Application {
@Override
public void start(Stage primaryStage) {
final Media bad = new Media("https://sideline.s3.amazonaws.com/tmp-delete/2020_11_20_Onnered_Savehof.mp4");
final Media good = new Media("https://sideline.s3.amazonaws.com/faq/10-minutes-of-typical-video.mp4");
final Dialog dialog = new Dialog();
dialog.setTitle("Bad video will work if you do not seek soon");
dialog.getDialogPane().getButtonTypes().add(ButtonType.CLOSE);
Button btnOpenSeek = new Button("Open+Seek (bad vid)");
btnOpenSeek.onActionProperty().setValue(actionEvent -> open(bad, false));
Button btnOpenSeekLater = new Button("Open+Seek later (bad vid)");
btnOpenSeekLater.onActionProperty().setValue(actionEvent -> open(bad, true));
Button btnOpenSeekGood = new Button("Open+Seek (good vid)");
btnOpenSeekGood.onActionProperty().setValue(actionEvent -> open(good, false));
dialog.getDialogPane().setContent(new FlowPane(
btnOpenSeek, btnOpenSeekLater, btnOpenSeekGood));
dialog.show();
}
private static void open(Media media, boolean seekLater) {
final MediaPlayer player = new MediaPlayer(media);
MediaView mediaView = new MediaView(player);
Group root = new Group(mediaView);
Scene scene = new Scene(root, 1280, 720);
Stage stage = new Stage();
stage.setTitle("Media Player with " + System.getProperty("jfxmedia.platform") + " playing " + media.getSource());
stage.setScene(scene);
stage.show();
player.play();
if (seekLater) {
new Thread(() -> {
try { Thread.sleep(10000); } catch (Exception e){}
Platform.runLater(() -> player.seek(Duration.seconds(400)));
}).start();
} else {
player.setOnPlaying(() -> player.seek(Duration.seconds(400)));
}
}
public static void main(String[] args) {
launch(args);
}
}