Playing Video in Java FX using vlcj api
Asked Answered
B

2

2

I am trying to play a video on Java FX components but not able to play. I know how to play a video in swing using vlcj but when I am trying the same I am not able to do so in javafx

    @Override
    public void start(Stage primaryStage) 
    {
        File f = new File("Video.mp4");
        new NativeDiscovery().discover();
        EmbeddedMediaPlayerComponent playerComponent = new EmbeddedMediaPlayerComponent();
        /*I dont know where to add the playerComponent as we do in swing*/
        MediaPlayer mp=playerComponent.getMediaPlayer();       
        StackPane root = new StackPane();
        Scene scene = new Scene(root, 700, 700);        
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
     //above code is for javafx where I am getting a problem
     //below code for swing
     public void playVideo()
     {
        new NativeDiscovery().discover();
        EmbeddedMediaPlayerComponent playerComponent = new EmbeddedMediaPlayerComponent();
        jif[i].setContentPane(playerComponent);
        MediaPlayer p = playerComponent.getMediaPlayer();
        ft = new FileTest();
        videoList = ft.getVideoList();
        jif[i].setVisible(true);
        frame.setVisible(true);
        p.setAspectRatio(width[i] + ":" + height[i]);
        p.playMedia(videoList[0]);
    }

I want to know what I need to do in javafx for settingContentPane we do in swing.

Bluster answered 9/9, 2015 at 9:39 Comment(0)
A
4

EmbeddedMediaPlayerComponent requires a heavyweight AWT Canvas to play the video in. You can't use that approach in JavaFX.

For JavaFX you have to render the video yourself using a DirectMediaPlayerComponent - "direct" meaning "direct rendering". At a high level this involves getting the video data (provided by the component for you) and then you rendering it in some way, like copying the video data to an image in your scene.

There is a full project here that shows a number of ways to do it, including one solution to get a resizable video player working:

https://github.com/caprica/vlcj-javafx

Anagnos answered 9/9, 2015 at 15:39 Comment(1)
Could anyone explain why that approach uses AnimationTimer instead of relaying on vlcj rendering callback?Keyser
S
2

I had the same problem. Then I tried the vlcj-javafx as mentioned above but with that solution, I had performance problems and it wasn't able to watch a video. So, I tried to use the awt with much better performance.

I ended up with an AWT JWindows that when the JavaFx Window is focused is topmost and changes the position like the javafx Window. I know that this isn't a good solution, but it works better than any solution that I tried before with java fx

I am not that experienced in Java Development and new to the Java Fx word. But it works quiet good. Code explanation: This panel you can use in the Java Fx the awt panel will be painted over this panel. To play the video use:

VlcPlayerPane#play(video_file_path.mp4)

MyMediaPlayerEventListener is MediaPlayerEventListener but with for every Method an empty defalt value.

//some imports here....
public class VlcPlayerPane extends Pane {
static {
    NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "C:/Program Files/VideoLAN/VLC");
}

private JWindow frame;
private Timer videoMoveTimer;
private EmbeddedMediaPlayerComponent mediaPlayerComponent;

private Runnable trackFinishedAction = null;
private Consumer<Long> onTimeChanged = null;
private Consumer<Float> onPositionChanged = null;
private Consumer<Long> onMaxLenghtChanged = null;

public VlcPlayerPane() {
    this.setBackground(
            new Background(new BackgroundFill(Color.BLACK, new CornerRadii(2), new Insets(2))));

    Platform.runLater(() ->
            getScene().getWindow().focusedProperty().addListener((a, b, c) -> {
                if (frame != null) {
                    if (c) {
                        frame.setAlwaysOnTop(true);
                    } else {
                        frame.setAlwaysOnTop(false);
                    }
                }
            }));
}

private void createMoveTimer() {
    videoMoveTimer = new Timer();
    videoMoveTimer.schedule(new TimerTask() {
        private Bounds oldBounds = null;

        @Override
        public void run() {
            Bounds bounds = localToScreen(getBoundsInLocal());
            if (!((Stage) getScene().getWindow()).isIconified()) {
                if (!frame.isVisible()) {
                    frame.setVisible(true);
                }

                if (oldBounds == null ||
                        bounds.getMinX() != oldBounds.getMinX() ||
                        bounds.getMinY() != oldBounds.getMinY() ||
                        bounds.getWidth() != oldBounds.getWidth() ||
                        bounds.getHeight() != oldBounds.getHeight()) {
                    oldBounds = bounds;
                    frame.setLocation(((int) bounds.getMinX()), ((int) bounds.getMinY()));
                    frame.setSize(((int) bounds.getWidth()), ((int) bounds.getHeight()));

                }
            } else {
                if (frame.isVisible()) {
                    frame.setVisible(false);
                    oldBounds = null;
                    frame.setSize(0, 0);
                }
            }
        }
    }, 0, 50);
}

private void createPlayer() {
    frame = new JWindow();

    mediaPlayerComponent = new EmbeddedMediaPlayerComponent();
    frame.setContentPane(mediaPlayerComponent);

    frame.setSize(0, 0);
    frame.setVisible(true);

    createMoveTimer();

    mediaPlayerComponent.getMediaPlayer().addMediaPlayerEventListener(new MyMediaPlayerEventListener() {
        @Override
        public void finished(MediaPlayer mediaPlayer) {
            if (trackFinishedAction != null) {
                trackFinishedAction.run();
            }
        }

        @Override
        public void timeChanged(MediaPlayer mediaPlayer, long newTime) {
            if (onTimeChanged != null) {
                onTimeChanged.accept(newTime);
            }
        }

        @Override
        public void positionChanged(MediaPlayer mediaPlayer, float newPosition) {
            if (onPositionChanged != null) {
                onPositionChanged.accept(newPosition);
            }
        }

        @Override
        public void lengthChanged(MediaPlayer mediaPlayer, long newLength) {
            if(onMaxLenghtChanged !=null){
                onMaxLenghtChanged.accept(newLength);
            }
        }
    });
}

public void play(String path) {
    if (mediaPlayerComponent == null) {
        createPlayer();
    }
    try {
        mediaPlayerComponent.getMediaPlayer().playMedia(path);
    }catch (Exception e){
        e.printStackTrace();
    }
}

public void pause() {
    if(mediaPlayerComponent != null) {
        mediaPlayerComponent.getMediaPlayer().pause();
    }
}

public void continuePlaying() {
    if(mediaPlayerComponent != null) {
        mediaPlayerComponent.getMediaPlayer().play();
    }
}


public void stopVideo() {
    if (mediaPlayerComponent != null &&
            mediaPlayerComponent.getMediaPlayer() != null) {
        mediaPlayerComponent.getMediaPlayer().stop();
    }

    videoMoveTimer.cancel();
    frame.setVisible(false);
    frame.dispose();
    frame = null;
    mediaPlayerComponent = null;
    videoMoveTimer = null;
}

public void setPlayPosition(int seconds){
    if(mediaPlayerComponent != null){
        mediaPlayerComponent.getMediaPlayer().setTime(seconds*1000);
    }
}


public void registerOnTimeChanged(Consumer<Long> action) {
    onTimeChanged = action;
}

public void registerOnPositionChanged(Consumer<Float> action) {
    onPositionChanged = action;
}

public void registerOnFinishedTrack(Runnable action) {
    trackFinishedAction = action;
}

public void registerOnMaxLengthChanged(Consumer<Long> action){
    onMaxLenghtChanged = action;
}

public long getLength() {
    if(mediaPlayerComponent == null){
        return 0;
    }
    return mediaPlayerComponent.getMediaPlayer().getLength();
}

public float getActualPositionPercent() {
    if(mediaPlayerComponent == null){
        return 0;
    }
    return mediaPlayerComponent.getMediaPlayer().getPosition();
}

public long getActualPositionSecond() {
    if(mediaPlayerComponent == null){
        return 0;
    }
    return mediaPlayerComponent.getMediaPlayer().getTime();
}
Simoneaux answered 27/8, 2018 at 15:47 Comment(1)
Hi Reto, any change you can include a link to a GitHub gist or even better copy/paste the code into this answer? This would help anyone coming across this question and wants to try your solution. Thanks!Vancouver

© 2022 - 2024 — McMap. All rights reserved.