VLCJ Media Event Listener not Firing

64 Views Asked by At

I'm trying to make an embedded video player in a program using Java swing and vlcj and would like a video scrubber. I'm coding between MacOS and windows and using vlcj 4.8.2.

I am currently trying to use a JSlider to create the video scrubber and am struggling with the media event listeners. I have put a test output in an event listener for when the time changes in the video but it never seems to fire even though the video is playing on my screen.

I have a main class that calls a UI class that calls the initializeMediaPlayer.

Is there a reason this isnt outputting the time change or an easier way to create a video scrubber?

I am still quite new to this library so I assume I'm missing a fairly easy thing.

This is my media player class:

import java.awt.BorderLayout;
import uk.co.caprica.vlcj.factory.discovery.NativeDiscovery;
import uk.co.caprica.vlcj.player.component.CallbackMediaPlayerComponent;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import uk.co.caprica.vlcj.player.base.MediaPlayerEventAdapter;
import static uk.co.caprica.vlcj.player.base.State.PLAYING;
import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;

public class MediaPlayer {

    public static void initializeMediaPlayer(JPanel videoPanel) {
        
        JButton uploadFootageButton = new JButton("<html>Click to Upload Footage<br />(or drag and drop)</html>"); //upload footage button
                                                                                                                       //over two lines
        videoPanel.add(uploadFootageButton, BorderLayout.CENTER);
        
        uploadFootageButton.addActionListener(new ActionListener() { //adds the action listener
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser footageUpload = new JFileChooser(); //load file explorer

                int result = footageUpload.showOpenDialog(null);

                if (result == JFileChooser.APPROVE_OPTION) { //if a file is selected
                    new NativeDiscovery().discover(); //find the vlc path

                    String selectedFilePath = footageUpload.getSelectedFile().getAbsolutePath(); //path of video

                    videoPanel.remove(uploadFootageButton); //remove upload button when video is uploaded
                    
                    JPanel mediaBar = new JPanel();
                    videoPanel.add(mediaBar, BorderLayout.SOUTH);

                    CallbackMediaPlayerComponent mediaPlayerComponent = new CallbackMediaPlayerComponent();
                    videoPanel.add(mediaPlayerComponent); //add the media player
                 
                    EmbeddedMediaPlayer mediaPlayer = mediaPlayerComponent.mediaPlayer();

                    mediaPlayer.media().prepare(selectedFilePath); //prepare the video
                    mediaPlayer.controls().play(); //play the video
                    
                    videoPanel.revalidate(); //make sure video panel is correct
                    videoPanel.repaint();

                    initialiseMediaSettings(mediaBar, mediaPlayer, mediaPlayerComponent); //create video settings and buttons
                }
                
            }
        });
    }
    
    public static void initialiseMediaSettings(JPanel mediaBar, EmbeddedMediaPlayer mediaPlayer, CallbackMediaPlayerComponent mediaPlayerComponent) {

        //code here that adds:
        //mute audio button
        //play/pause button
        //playback speed options

        //scrubber
/*-----------------------------------------------------------------------------------------------------------------------------------*/
        JSlider videoScrubber = new JSlider();

        while (mediaPlayer.status().state() != PLAYING) { //while its not playing
            try {
                Thread.sleep(100); // Sleep for a short interval to avoid busy-waiting
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        videoScrubber.setMinimum(0); //cant have negative time in video
        videoScrubber.setMaximum((int) mediaPlayer.status().length()); //max of slider is video length

        mediaPlayer.controls().setRepeat(true); 

        videoScrubber.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                if (!videoScrubber.getValueIsAdjusting()) { //stops updating whilst scrubber is being moved
                    mediaPlayer.controls().setPosition(((float) videoScrubber.getValue()) / videoScrubber.getMaximum());
                }
            }
        });
        
        mediaPlayerComponent.mediaPlayer().events().addMediaPlayerEventListener(new MediaPlayerEventAdapter() {
            public void timeChanged(MediaPlayer mediaPlayer, long newTime) {
                System.err.println("Time changed: " + newTime);
            }
        });
        
        mediaBar.add(videoScrubber);
    }
/*-----------------------------------------------------------------------------------------------------------------------------------*/
}

I have tried just having a reccuring excecute function that updates the scrubber but it just ends up being laggy and not working correctly.

0

There are 0 best solutions below