Search code examples
javafxvlcvlcj

use vlcj-javafx-demo develop a player, but it looks some components UI not update correctly when set full screen


I try to use vlcj-javafx-demo to develop a video player, and I put the progress bar(Slider) on the StackPane over the video layer. In the beginning, it looks work well, but when I set maximum or full screen the app, it looks some components UI did not update correctly. How can I correct it?

Thanks a lot!

normally: [1]: https://i.sstatic.net/bbE51.png

normally: [2]: https://i.sstatic.net/Plsb1.png the red color is the sence background color.

the code :

package my.javafx.myplayer;

import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.DoubleProperty;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.control.Slider;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
import uk.co.caprica.vlcj.player.base.MediaPlayerEventAdapter;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;

import java.util.ArrayList;
import java.util.List;

import static uk.co.caprica.vlcj.javafx.videosurface.ImageViewVideoSurfaceFactory.videoSurfaceForImageView;

/**
 *
 */
public class VlcjJavaFxApplication extends Application {

    private final MediaPlayerFactory mediaPlayerFactory;

    private final EmbeddedMediaPlayer embeddedMediaPlayer;

    private ImageView videoImageView;
    
    Slider progress=new Slider();

    public VlcjJavaFxApplication() {
        this.mediaPlayerFactory = new MediaPlayerFactory();
        this.embeddedMediaPlayer = mediaPlayerFactory.mediaPlayers().newEmbeddedMediaPlayer();
        this.embeddedMediaPlayer.events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
            @Override
            public void mediaPlayerReady(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer) {
                Platform.runLater(()->{
                    progress.setValue(0);
                    progress.setMax(embeddedMediaPlayer.media().info().duration());
                    
                    progress.setMin(0);
                });
            }
            @Override
            public void playing(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer) {
                
            }

            @Override
            public void paused(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer) {
            }

            @Override
            public void stopped(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer) {
            }

            @Override
            public void timeChanged(uk.co.caprica.vlcj.player.base.MediaPlayer mediaPlayer, long newTime) {
                Platform.runLater(()->{
                    progress.setValue(newTime);
                });
                
            }
        });
    }

    @Override
    public void init() {
        this.videoImageView = new ImageView();
        this.videoImageView.setPreserveRatio(true);

        embeddedMediaPlayer.videoSurface().set(videoSurfaceForImageView(this.videoImageView));
    }

    @Override
    public final void start(Stage primaryStage) throws Exception {
        List<String> params = new ArrayList<String>();
        params.add("/Users/baixq/Downloads/妙味课堂xhtml+css2/妙味课堂-XHTMLCSS2整站视频教程-4.avi");
        if (params.size() != 1) {
            System.out.println("Specify a single MRL");
            System.exit(-1);
        }
        StackPane root=new StackPane();
        //BorderPane root = new BorderPane();
        root.setStyle("-fx-background-color: black;");

        videoImageView.fitWidthProperty().bind(root.widthProperty());
        videoImageView.fitHeightProperty().bind(root.heightProperty());

        root.widthProperty().addListener((observableValue, oldValue, newValue) -> {
            // If you need to know about resizes
        });

        root.heightProperty().addListener((observableValue, oldValue, newValue) -> {
            // If you need to know about resizes
        });
        
        

        Scene scene = new Scene(root, 1200, 675, Color.RED);
        primaryStage.setTitle("vlcj JavaFX");
        primaryStage.setScene(scene);
        
        AnchorPane contrlBox=new AnchorPane();//操作面板上的控制模块
        contrlBox.prefWidthProperty().bind(root.widthProperty());
        contrlBox.prefHeightProperty().bind(root.heightProperty().multiply(0.1));
        
        BorderPane controlBar=new BorderPane();
        controlBar.setStyle("-fx-background-color: #130c0e;");
        controlBar.prefWidthProperty().bind(root.widthProperty());
        controlBar.prefHeightProperty().bind(root.heightProperty().multiply(0.1));
        controlBar.setCenter(progress);
        Button fullScreen=new Button("全屏");
        controlBar.setRight(fullScreen);
        
        contrlBox.getChildren().add(controlBar);
        contrlBox.setBottomAnchor(controlBar, 0.0);
        
        
        root.getChildren().addAll(videoImageView,contrlBox);
        
        
        primaryStage.show();
        embeddedMediaPlayer.media().play(params.get(0));
        
        fullScreen.setOnAction(event->{
            primaryStage.setFullScreen(true);
        });

        root.setOnMouseEntered(event->{
            Platform.runLater(()->{
                FadeTransition ft = new FadeTransition(Duration.millis(500), contrlBox);
                ft.setFromValue(0.0);
                ft.setToValue(1);
                //ft.setCycleCount(Timeline.INDEFINITE);
                ft.setAutoReverse(false);
                
                
                ft.play();
                contrlBox.setVisible(true);
            });
            
            
            
        });

        root.setOnMouseExited(event->{
            Platform.runLater(()->{
                FadeTransition ft = new FadeTransition(Duration.millis(500), contrlBox);
                ft.setFromValue(1);
                ft.setToValue(0.0);
                ft.setAutoReverse(false);
                
                
                
                ft.play();
                contrlBox.setVisible(false);
            });
        });
        
        //embeddedMediaPlayer.controls().setPosition(0.4f);
    }

    @Override
    public final void stop() {
        embeddedMediaPlayer.controls().stop();
        embeddedMediaPlayer.release();
        mediaPlayerFactory.release();
    }

    public static void main(String[] args) {
        launch(args);
    }
}


Solution

  • You appear to be using a Linux OS, try passing one or more of these system properties when you start your JVM:

    -Dprism.dirtyopts=false
    
    -Dprism.forceUploadingPainter=true
    

    This is mentioned under "Linux notes" here: https://github.com/caprica/vlcj-javafx-demo/tree/vlcj-5.x

    I have seen similar painting glitches on Linux before and in all cases using these properties, at least for me, clears the issue with only a small hit to performance - even when doing something like a full-screen grid of nine concurrent media players, where each one had an animating video controls overlay.