JavaFX implements video player

For many Java development partners, many children's shoes have known JavaFX, but due to the limitations of JavaFX, most Java developers may not understand it very well, so naturally they lack practical experience in JavaFX, but sometimes We also want to develop some small programs by ourselves, such as the picture , or the audio browser, video browser, etc. Today, the editor will take you into the programming process of the video browser !

The renderings are as follows:

Require:

  1. The main background color is black;

  1. The video is centered up and down, left and right, and kept maximized in the interface;

  1. The progress bar controls the playback progress;

  1. The audio size can be controlled by dragging the audio progress bar;

  1. By default, it will play when it is turned on, click the screen to pause, and continue to click to start playing again.

Difficulty analysis:

  1. Specify to play video files through Media, and realize playback control through MediaPlayer;

  1. Use the BorderPane layout to center the video both horizontally and vertically;

  1. Use Slider to bind the playback progress bar event to dynamically display the playback progress;

  1. Set height-width change event to reset container width and height.

Details optimization points:

  1. When playing in full screen, the display will exit full screen without displaying the header title, and the operation will be reversed when exiting full screen;

  1. When the video is playing, it needs to automatically calculate the playing time according to the playing time of the video;

  1. ESC exits full-screen playback.

Okay, enough nonsense, let's use the code to implement it and see the effect.

code show as below:

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
import javafx.util.Duration;

public class VideoPlayerApplication extends Application {
    private Stage primaryStage;
    private Label time = new Label();
    private double allTime = 0;
    private Slider playSlider;
    private Slider audioSlider = new Slider(0, 100, 80);
    private boolean isplay;
    private Media media;
    private MediaPlayer player;
    private String title;

    public VideoPlayerApplication() {
        // 默认初始化标题及其文件URL
        this.title = "测试";
        this.media = new Media("http://192.168.18.9:8080/files/20230313/9c49403b-929b-4f65-843b-4c122432b90d.mp4");
    }

    public VideoPlayerApplication(String title, String url) {
        this.media = new Media(url);
        this.title = title;
    }

    @Override
    public void start(Stage primaryStage) {
        this.primaryStage = primaryStage;
        player = new MediaPlayer(media);
        player.play();
        isplay = true;
        MediaView mediaView = new MediaView(player);

        VBox anchorPane = new VBox(mediaView);
        anchorPane.setAlignment(Pos.CENTER);
        anchorPane.setPrefWidth(800);
        anchorPane.setPrefHeight(600);
        anchorPane.setStyle("-fx-background-color: #000;");
        BorderPane root = new BorderPane(anchorPane);

        root.setPrefWidth(800);
        root.setPrefHeight(600);
        player.volumeProperty().bind(audioSlider.valueProperty().divide(100));

        root.setOnMouseClicked(event -> {
            playOrStop();
        });

        playSlider = new Slider();
        playSlider.setMin(0);
        playSlider.setMax(500);
        playSlider.setPrefWidth(800);
        playSlider.setValue(0);

        VBox.setMargin(playSlider, new Insets(-50, 0, 0, 0));
        anchorPane.getChildren().add(playSlider);
        Label full = new Label("全屏");
        full.setOnMouseClicked(event -> {
            fullScreen(full);
        });
        Label label = new Label(">");
        label.setTextAlignment(TextAlignment.CENTER);
        label.setAlignment(Pos.CENTER);
        label.setPrefWidth(650);
        label.setMinWidth(80);
        Label vol = new Label("音量");
        vol.setStyle("-fx-text-fill:white");

        audioSlider.setMaxWidth(80);
        audioSlider.setMinWidth(30);
//        audioSlider.setRotate(-90);
        HBox hBox = new HBox(full, label, vol, audioSlider);
        hBox.setPadding(new Insets(20, 0, 0, 0));
        anchorPane.getChildren().add(hBox);
        Scene scene = new Scene(root);
        primaryStage.setTitle(title);
        primaryStage.setScene(scene);
        primaryStage.show();
        player.currentTimeProperty().addListener((x, y, z) -> {
            if (isplay) {
                double currents = player.getCurrentTime().toSeconds();
                allTime = player.getStopTime().toSeconds();
                playSlider.setValue(currents / allTime * 500);
                time.setText(formattime(currents, allTime, 0));
            }
        });

        playSlider.setOnMousePressed(x -> {
            isplay = false;
        });
        playSlider.setOnMouseReleased(x -> {
            player.seek(Duration.seconds(playSlider.getValue() / 500 * allTime));
            isplay = true;
        });
        ChangeListener<Number> changeListener = (event, oldVal, newVal) -> {
            System.out.println("oldVal = " + oldVal + ", newVal = " + newVal);
            mediaView.setFitHeight(primaryStage.getHeight() - 40);
            mediaView.setFitWidth(primaryStage.getWidth());
        };
        primaryStage.widthProperty().addListener(changeListener);
        primaryStage.heightProperty().addListener(changeListener);
        primaryStage.fullScreenProperty().addListener((event, q, d) -> {
            fullScreen(full);
        });

        root.setOnKeyPressed(event -> {
            System.out.println(event.getCode());
            if (KeyCode.SPACE.equals(event.getCode())) {
                playOrStop();
            }
        });

        primaryStage.setOnCloseRequest(event -> {
            player.pause();
            player.stop();
        });

        mediaView.setFitHeight(primaryStage.getHeight() - 40);
        mediaView.setFitWidth(primaryStage.getWidth());
    }

    private void playOrStop() {
        if (isplay) {
            isplay = false;
            player.pause();
        } else {
            Duration seconds = Duration.seconds(playSlider.getValue() / 500 * allTime);
            player.seek(seconds);
            isplay = true;
            player.play();
        }
    }

    private void fullScreen(Label full) {
        if ("全屏".equals(full.getText())) {
            primaryStage.setFullScreen(true);
            audioSlider.setVisible(false);
            playSlider.setVisible(false);
            full.setText("退出全屏");
        } else {
            primaryStage.setFullScreen(false);
            audioSlider.setVisible(true);
            playSlider.setVisible(true);
            full.setText("全屏");
        }
    }

    public static String formattime(double this_time, double all_time, int type) {
        String thistime = String.format("%02d:%02d:%02d", (int) this_time / 3600, (int) this_time % 3600 / 60, (int) this_time % 60);
        String alltime = String.format("%02d:%02d:%02d", (int) all_time / 3600, (int) all_time % 3600 / 60, (int) all_time % 60);
        return type == 1 ? thistime : type == 2 ? alltime : thistime + "/" + alltime;
    }
}

With this foundation, can we make a video player by ourselves? The answer must be yes, but if it supports zooming, that is to say, the interface size can be freely zoomed by the user. In this case, the processing will be much more complicated. If you have an idea, it is recommended to fix the default playback interface size (but full screen must be supported, otherwise the user experience will be extremely unfriendly), and the rest can be explored freely. If you encounter problems during the programming process, you can private message me at any time.

Alright, that's the end of today's class, get out of class is over!

Guess you like

Origin blog.csdn.net/m0_37649480/article/details/129492816